From 27f7b6f43172dfffb32dca5ae62be5c4d812aa2a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 26 Aug 2009 19:56:12 +0200 Subject: [PATCH] --- yaml --- r: 164917 b: refs/heads/master c: e5dc8ae121592239c2a2521d383bcb789849b2a3 h: refs/heads/master i: 164915: 15c3b2edbd31cecb09bdaccc586c19300064f7f3 v: v3 --- [refs] | 2 +- trunk/Documentation/ABI/testing/sysfs-gpio | 1 - trunk/Documentation/accounting/getdelays.c | 12 +- .../auxdisplay/cfag12864b-example.c | 22 +- trunk/Documentation/fb/ep93xx-fb.txt | 135 -- trunk/Documentation/fb/matroxfb.txt | 4 +- trunk/Documentation/filesystems/ncpfs.txt | 6 +- trunk/Documentation/filesystems/proc.txt | 5 +- trunk/Documentation/gpio.txt | 17 - trunk/Documentation/ia64/aliasing-test.c | 8 +- trunk/Documentation/lguest/lguest.c | 26 +- trunk/Documentation/pcmcia/crc32hash.c | 2 +- .../powerpc/dts-bindings/fsl/esdhc.txt | 2 - trunk/Documentation/rtc.txt | 26 - trunk/Documentation/spi/spi-summary | 2 +- trunk/Documentation/spi/spidev_test.c | 4 +- trunk/Documentation/sysctl/kernel.txt | 8 - trunk/Documentation/video4linux/v4lgrab.c | 2 +- trunk/Documentation/vm/page-types.c | 52 +- trunk/Documentation/vm/slabinfo.c | 68 +- .../watchdog/src/watchdog-test.c | 2 +- trunk/MAINTAINERS | 11 +- trunk/arch/arm/configs/n770_defconfig | 2 +- trunk/arch/arm/configs/omap3_beagle_defconfig | 47 +- trunk/arch/arm/configs/omap_3430sdp_defconfig | 39 +- trunk/arch/arm/configs/omap_ldp_defconfig | 54 +- trunk/arch/arm/mach-at91/Kconfig | 7 - trunk/arch/arm/mach-at91/Makefile | 1 - .../arch/arm/mach-at91/at91sam9260_devices.c | 96 - .../arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 --- trunk/arch/arm/mach-at91/include/mach/board.h | 5 - trunk/arch/arm/mach-ep93xx/clock.c | 88 +- trunk/arch/arm/mach-ep93xx/core.c | 32 - .../mach-ep93xx/include/mach/ep93xx-regs.h | 6 - trunk/arch/arm/mach-ep93xx/include/mach/fb.h | 56 - .../arm/mach-ep93xx/include/mach/platform.h | 2 - .../arm/mach-omap2/board-rx51-peripherals.c | 4 - trunk/arch/arm/mach-omap2/devices.c | 71 +- trunk/arch/arm/mach-omap2/mmc-twl4030.c | 78 - trunk/arch/arm/mach-omap2/mmc-twl4030.h | 2 - trunk/arch/arm/plat-mxc/include/mach/spi.h | 27 - trunk/arch/arm/plat-omap/include/mach/irqs.h | 2 - .../arm/plat-omap/include/mach/lcd_mipid.h | 5 - trunk/arch/arm/plat-omap/include/mach/mmc.h | 20 +- .../arch/arm/plat-omap/include/mach/omapfb.h | 4 +- trunk/arch/blackfin/include/asm/sections.h | 38 +- trunk/arch/ia64/Kconfig | 4 - trunk/arch/ia64/mm/init.c | 5 + trunk/arch/mips/mm/init.c | 7 +- trunk/arch/mn10300/kernel/setup.c | 2 +- trunk/arch/powerpc/boot/dts/mpc8377_mds.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8377_wlan.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8378_mds.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8379_mds.dts | 1 - trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts | 1 - trunk/arch/powerpc/kernel/setup-common.c | 2 +- trunk/arch/powerpc/mm/init_32.c | 36 + trunk/arch/powerpc/mm/init_64.c | 29 + trunk/arch/powerpc/mm/mem.c | 6 +- .../powerpc/platforms/pseries/hvCall_inst.c | 2 +- trunk/arch/score/include/asm/page.h | 3 +- trunk/arch/score/include/asm/thread_info.h | 15 +- trunk/arch/score/kernel/vmlinux.lds.S | 77 +- trunk/arch/sh/mm/init.c | 6 + trunk/arch/sparc/include/asm/vio.h | 2 +- trunk/arch/x86/Kconfig | 4 - trunk/arch/x86/include/asm/syscall.h | 14 +- trunk/arch/x86/kernel/ptrace.c | 21 +- trunk/arch/x86/lguest/boot.c | 10 +- trunk/arch/x86/mm/init_32.c | 6 + trunk/arch/x86/mm/init_64.c | 10 +- trunk/drivers/block/DAC960.c | 2 +- trunk/drivers/block/cciss.c | 2 +- trunk/drivers/block/virtio_blk.c | 33 +- trunk/drivers/char/hw_random/virtio-rng.c | 3 +- trunk/drivers/char/misc.c | 2 +- trunk/drivers/char/tpm/tpm.c | 4 +- trunk/drivers/char/tpm/tpm_bios.c | 4 +- trunk/drivers/char/virtio_console.c | 5 +- trunk/drivers/connector/cn_proc.c | 25 - trunk/drivers/gpio/Kconfig | 35 - trunk/drivers/gpio/Makefile | 4 - trunk/drivers/gpio/adp5520-gpio.c | 206 -- trunk/drivers/gpio/bt8xxgpio.c | 3 +- trunk/drivers/gpio/gpiolib.c | 253 +-- trunk/drivers/gpio/langwell_gpio.c | 297 --- trunk/drivers/gpio/max7301.c | 1 - trunk/drivers/gpio/mc33880.c | 196 -- trunk/drivers/gpio/mcp23s08.c | 5 +- trunk/drivers/gpio/pca953x.c | 4 +- trunk/drivers/gpio/pcf857x.c | 3 +- trunk/drivers/gpio/ucb1400_gpio.c | 125 -- trunk/drivers/hwmon/adcxx.c | 101 +- trunk/drivers/hwmon/dme1737.c | 2 +- trunk/drivers/hwmon/lis3lv02d_spi.c | 2 +- trunk/drivers/hwmon/lm70.c | 55 +- trunk/drivers/hwmon/max1111.c | 1 - trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c | 2 +- trunk/drivers/input/touchscreen/ad7877.c | 1 - trunk/drivers/input/touchscreen/ad7879.c | 1 - trunk/drivers/input/touchscreen/ads7846.c | 1 - trunk/drivers/isdn/capi/kcapi_proc.c | 10 +- trunk/drivers/leds/leds-dac124s085.c | 1 - trunk/drivers/lguest/core.c | 5 +- trunk/drivers/lguest/page_tables.c | 45 +- trunk/drivers/mfd/ezx-pcap.c | 1 - trunk/drivers/mfd/ucb1400_core.c | 31 +- trunk/drivers/misc/eeprom/at25.c | 2 +- trunk/drivers/misc/lkdtm.c | 2 +- trunk/drivers/mmc/core/core.c | 318 +-- trunk/drivers/mmc/core/core.h | 8 +- trunk/drivers/mmc/core/host.c | 1 - trunk/drivers/mmc/core/host.h | 2 - trunk/drivers/mmc/core/mmc.c | 149 +- trunk/drivers/mmc/core/mmc_ops.c | 59 - trunk/drivers/mmc/core/mmc_ops.h | 1 - trunk/drivers/mmc/core/sd.c | 75 +- trunk/drivers/mmc/core/sdio.c | 316 +-- trunk/drivers/mmc/core/sdio_bus.c | 3 + trunk/drivers/mmc/core/sdio_cis.c | 2 +- trunk/drivers/mmc/core/sdio_io.c | 2 +- trunk/drivers/mmc/host/Kconfig | 29 +- trunk/drivers/mmc/host/Makefile | 1 - trunk/drivers/mmc/host/atmel-mci.c | 33 +- trunk/drivers/mmc/host/mmc_spi.c | 1 - trunk/drivers/mmc/host/msm_sdcc.c | 1287 ------------ trunk/drivers/mmc/host/msm_sdcc.h | 238 --- trunk/drivers/mmc/host/omap_hsmmc.c | 1083 ++-------- trunk/drivers/mmc/host/sdhci-of.c | 49 +- trunk/drivers/mmc/host/sdhci-pci.c | 5 +- trunk/drivers/mmc/host/sdhci.c | 54 +- trunk/drivers/mmc/host/sdhci.h | 6 +- trunk/drivers/mtd/devices/mtd_dataflash.c | 1 - trunk/drivers/net/ehea/ehea_qmr.c | 2 +- trunk/drivers/net/enc28j60.c | 1 - trunk/drivers/net/ks8851.c | 1 - trunk/drivers/net/niu.c | 2 +- trunk/drivers/net/virtio_net.c | 15 +- trunk/drivers/net/wireless/libertas/if_spi.c | 1 - trunk/drivers/net/wireless/p54/p54spi.c | 1 - .../drivers/net/wireless/wl12xx/wl1251_main.c | 1 - trunk/drivers/of/base.c | 1 + trunk/drivers/rtc/Kconfig | 49 - trunk/drivers/rtc/Makefile | 17 +- trunk/drivers/rtc/rtc-at91rm9200.c | 24 +- trunk/drivers/rtc/rtc-bfin.c | 2 +- trunk/drivers/rtc/rtc-coh901331.c | 311 --- trunk/drivers/rtc/rtc-ds1305.c | 1 - trunk/drivers/rtc/rtc-ds1307.c | 3 +- trunk/drivers/rtc/rtc-ds1390.c | 1 - trunk/drivers/rtc/rtc-ds3234.c | 1 - trunk/drivers/rtc/rtc-ep93xx.c | 14 +- trunk/drivers/rtc/rtc-m41t94.c | 1 - trunk/drivers/rtc/rtc-max6902.c | 1 - trunk/drivers/rtc/rtc-mxc.c | 507 ----- trunk/drivers/rtc/rtc-pcap.c | 224 --- trunk/drivers/rtc/rtc-pcf2123.c | 364 ---- trunk/drivers/rtc/rtc-r9701.c | 1 - trunk/drivers/rtc/rtc-rs5c348.c | 1 - trunk/drivers/rtc/rtc-stmp3xxx.c | 304 --- trunk/drivers/rtc/rtc-sysfs.c | 14 - trunk/drivers/scsi/sg.c | 6 +- trunk/drivers/serial/max3100.c | 1 - trunk/drivers/spi/Kconfig | 23 +- trunk/drivers/spi/Makefile | 4 +- trunk/drivers/spi/mxc_spi.c | 685 ------- trunk/drivers/spi/omap2_mcspi.c | 210 +- trunk/drivers/spi/pxa2xx_spi.c | 2 +- trunk/drivers/spi/spi.c | 85 +- trunk/drivers/spi/spi_imx.c | 1770 +++++++++++++++++ trunk/drivers/spi/spi_ppc4xx.c | 612 ------ trunk/drivers/spi/spi_s3c24xx.c | 157 +- trunk/drivers/spi/spi_stmp.c | 679 ------- trunk/drivers/spi/spidev.c | 1 - trunk/drivers/spi/tle62x0.c | 1 - trunk/drivers/staging/stlc45xx/stlc45xx.c | 1 - trunk/drivers/usb/storage/onetouch.c | 2 +- trunk/drivers/video/Kconfig | 50 +- trunk/drivers/video/Makefile | 3 - trunk/drivers/video/aty/atyfb_base.c | 829 ++++---- trunk/drivers/video/au1100fb.c | 7 +- trunk/drivers/video/backlight/corgi_lcd.c | 1 - trunk/drivers/video/backlight/ltv350qv.c | 1 - trunk/drivers/video/backlight/tdo24m.c | 1 - trunk/drivers/video/backlight/tosa_lcd.c | 2 +- trunk/drivers/video/backlight/vgg2432a4.c | 3 +- trunk/drivers/video/console/bitblit.c | 8 +- trunk/drivers/video/console/fbcon.c | 58 +- trunk/drivers/video/console/newport_con.c | 2 +- trunk/drivers/video/console/vgacon.c | 8 +- trunk/drivers/video/da8xx-fb.c | 890 --------- trunk/drivers/video/ep93xx-fb.c | 646 ------ trunk/drivers/video/fbmem.c | 19 +- trunk/drivers/video/matrox/g450_pll.c | 209 +- trunk/drivers/video/matrox/g450_pll.h | 8 +- trunk/drivers/video/matrox/i2c-matroxfb.c | 18 +- trunk/drivers/video/matrox/matroxfb_DAC1064.c | 614 +++--- trunk/drivers/video/matrox/matroxfb_DAC1064.h | 4 +- trunk/drivers/video/matrox/matroxfb_Ti3026.c | 258 ++- trunk/drivers/video/matrox/matroxfb_accel.c | 129 +- trunk/drivers/video/matrox/matroxfb_accel.h | 2 +- trunk/drivers/video/matrox/matroxfb_base.c | 772 +++---- trunk/drivers/video/matrox/matroxfb_base.h | 80 +- trunk/drivers/video/matrox/matroxfb_crtc2.c | 160 +- trunk/drivers/video/matrox/matroxfb_g450.c | 185 +- trunk/drivers/video/matrox/matroxfb_g450.h | 8 +- trunk/drivers/video/matrox/matroxfb_maven.c | 50 +- trunk/drivers/video/matrox/matroxfb_misc.c | 288 ++- trunk/drivers/video/matrox/matroxfb_misc.h | 15 +- trunk/drivers/video/msm/Makefile | 19 - trunk/drivers/video/msm/mddi.c | 828 -------- trunk/drivers/video/msm/mddi_client_dummy.c | 97 - trunk/drivers/video/msm/mddi_client_nt35399.c | 255 --- trunk/drivers/video/msm/mddi_client_toshiba.c | 283 --- trunk/drivers/video/msm/mddi_hw.h | 305 --- trunk/drivers/video/msm/mdp.c | 538 ----- trunk/drivers/video/msm/mdp_csc_table.h | 582 ------ trunk/drivers/video/msm/mdp_hw.h | 621 ------ trunk/drivers/video/msm/mdp_ppp.c | 750 ------- trunk/drivers/video/msm/mdp_scale_tables.c | 766 ------- trunk/drivers/video/msm/mdp_scale_tables.h | 38 - trunk/drivers/video/msm/msm_fb.c | 636 ------ trunk/drivers/video/omap/Kconfig | 82 +- trunk/drivers/video/omap/Makefile | 12 - trunk/drivers/video/omap/blizzard.c | 91 +- trunk/drivers/video/omap/dispc.c | 130 +- trunk/drivers/video/omap/dispc.h | 7 +- trunk/drivers/video/omap/hwa742.c | 2 +- trunk/drivers/video/omap/lcd_2430sdp.c | 202 -- trunk/drivers/video/omap/lcd_ams_delta.c | 137 -- trunk/drivers/video/omap/lcd_apollon.c | 138 -- trunk/drivers/video/omap/lcd_ldp.c | 200 -- trunk/drivers/video/omap/lcd_mipid.c | 625 ------ trunk/drivers/video/omap/lcd_omap2evm.c | 191 -- trunk/drivers/video/omap/lcd_omap3beagle.c | 130 -- trunk/drivers/video/omap/lcd_omap3evm.c | 192 -- trunk/drivers/video/omap/lcd_overo.c | 179 -- trunk/drivers/video/omap/omapfb_main.c | 64 +- trunk/drivers/video/omap/rfbi.c | 7 +- trunk/drivers/video/platinumfb.c | 12 +- trunk/drivers/video/s3c-fb.c | 2 +- trunk/drivers/video/s3c2410fb.c | 4 +- trunk/drivers/video/sis/sis_main.c | 4 +- trunk/drivers/video/sis/vstruct.h | 2 +- trunk/drivers/video/tmiofb.c | 2 +- trunk/drivers/video/via/accel.c | 589 ++---- trunk/drivers/video/via/accel.h | 13 +- trunk/drivers/video/via/chip.h | 4 +- trunk/drivers/video/via/dvi.c | 6 +- trunk/drivers/video/via/global.c | 3 + trunk/drivers/video/via/global.h | 2 + trunk/drivers/video/via/hw.c | 474 +++-- trunk/drivers/video/via/hw.h | 57 +- trunk/drivers/video/via/ioctl.h | 6 +- trunk/drivers/video/via/lcd.c | 16 +- trunk/drivers/video/via/share.h | 98 - trunk/drivers/video/via/via_i2c.c | 64 +- trunk/drivers/video/via/viafbdev.c | 1049 ++++++---- trunk/drivers/video/via/viafbdev.h | 61 +- trunk/drivers/video/via/viamode.c | 100 +- trunk/drivers/video/via/viamode.h | 141 +- trunk/drivers/video/via/vt1636.c | 4 +- trunk/drivers/virtio/virtio_balloon.c | 3 +- trunk/drivers/virtio/virtio_pci.c | 125 +- trunk/drivers/virtio/virtio_ring.c | 6 +- trunk/drivers/vlynq/vlynq.c | 1 + trunk/firmware/ihex2fw.c | 2 +- trunk/fs/afs/proc.c | 8 +- trunk/fs/aio.c | 10 +- trunk/fs/anon_inodes.c | 68 +- trunk/fs/buffer.c | 57 +- trunk/fs/compat.c | 7 + trunk/fs/devpts/inode.c | 3 +- trunk/fs/dlm/debug_fs.c | 12 +- trunk/fs/eventfd.c | 67 +- trunk/fs/exec.c | 5 - trunk/fs/ext2/namei.c | 2 +- trunk/fs/hugetlbfs/inode.c | 4 +- trunk/fs/inode.c | 19 +- trunk/fs/jbd2/journal.c | 4 +- trunk/fs/minix/dir.c | 22 +- trunk/fs/ncpfs/dir.c | 2 +- trunk/fs/ncpfs/ioctl.c | 2 +- trunk/fs/nfs/client.c | 4 +- trunk/fs/nfsd/export.c | 2 +- trunk/fs/ntfs/file.c | 42 +- trunk/fs/ocfs2/cluster/netdebug.c | 4 +- trunk/fs/ocfs2/dlm/dlmdebug.c | 2 +- trunk/fs/open.c | 5 +- trunk/fs/proc/array.c | 85 +- trunk/fs/proc/base.c | 23 +- trunk/fs/proc/kcore.c | 300 +-- trunk/fs/proc/nommu.c | 2 +- trunk/fs/proc/task_mmu.c | 33 +- trunk/fs/qnx4/Kconfig | 11 + trunk/fs/qnx4/Makefile | 2 +- trunk/fs/qnx4/bitmap.c | 81 + trunk/fs/qnx4/dir.c | 5 + trunk/fs/qnx4/file.c | 40 + trunk/fs/qnx4/inode.c | 84 +- trunk/fs/qnx4/namei.c | 105 + trunk/fs/qnx4/qnx4.h | 8 + trunk/fs/qnx4/truncate.c | 34 + trunk/fs/ramfs/inode.c | 4 +- trunk/fs/select.c | 14 +- trunk/fs/smbfs/proc.c | 2 +- trunk/fs/sync.c | 1 - trunk/include/asm-generic/gpio.h | 8 - trunk/include/asm-generic/kmap_types.h | 47 +- trunk/include/asm-generic/sections.h | 16 - trunk/include/asm-generic/syscall.h | 8 +- trunk/include/linux/anon_inodes.h | 3 - trunk/include/linux/cn_proc.h | 10 - trunk/include/linux/cpumask.h | 12 - trunk/include/linux/eventfd.h | 6 - trunk/include/linux/gfp.h | 2 +- trunk/include/linux/gpio.h | 11 - trunk/include/linux/ioport.h | 4 - trunk/include/linux/jbd.h | 2 +- trunk/include/linux/kernel.h | 16 +- trunk/include/linux/kmemcheck.h | 6 +- trunk/include/linux/magic.h | 6 - trunk/include/linux/memory_hotplug.h | 8 + trunk/include/linux/mm.h | 8 - trunk/include/linux/mmc/card.h | 12 +- trunk/include/linux/mmc/core.h | 1 - trunk/include/linux/mmc/host.h | 58 - trunk/include/linux/mmc/mmc.h | 3 - trunk/include/linux/mmc/sdio_func.h | 3 - trunk/include/linux/mod_devicetable.h | 11 - trunk/include/linux/nfsd/nfsd.h | 2 +- trunk/include/linux/proc_fs.h | 16 +- trunk/include/linux/sched.h | 11 - trunk/include/linux/spi/mc33880.h | 10 - trunk/include/linux/spi/spi.h | 51 +- trunk/include/linux/syscalls.h | 3 +- trunk/include/linux/ucb1400.h | 19 - trunk/include/linux/virtio.h | 2 +- trunk/include/linux/virtio_9p.h | 2 + trunk/include/linux/virtio_balloon.h | 3 + trunk/include/linux/virtio_blk.h | 18 +- trunk/include/linux/virtio_config.h | 3 +- trunk/include/linux/virtio_console.h | 3 + trunk/include/linux/virtio_ids.h | 17 - trunk/include/linux/virtio_net.h | 3 + trunk/include/linux/virtio_rng.h | 3 + trunk/include/video/da8xx-fb.h | 103 - trunk/ipc/util.c | 2 +- trunk/kernel/cgroup.c | 2 +- trunk/kernel/exit.c | 10 +- trunk/kernel/fork.c | 3 - trunk/kernel/kallsyms.c | 3 +- trunk/kernel/kmod.c | 13 +- trunk/kernel/kprobes.c | 2 +- trunk/kernel/lockdep.c | 3 - trunk/kernel/lockdep_proc.c | 2 +- trunk/kernel/printk.c | 27 +- trunk/kernel/resource.c | 23 +- trunk/kernel/smp.c | 29 +- trunk/kernel/sys.c | 14 - trunk/kernel/sysctl.c | 14 - trunk/kernel/trace/ftrace.c | 4 +- trunk/kernel/trace/trace.c | 4 +- trunk/mm/Makefile | 4 +- trunk/mm/memory_hotplug.c | 6 +- trunk/mm/nommu.c | 3 +- trunk/mm/vmalloc.c | 2 +- trunk/net/9p/trans_virtio.c | 5 +- trunk/net/ipv6/ip6mr.c | 2 +- trunk/net/socket.c | 3 +- trunk/scripts/conmakehash.c | 6 +- trunk/scripts/genksyms/genksyms.c | 6 +- trunk/scripts/kallsyms.c | 2 +- trunk/scripts/mod/file2alias.c | 13 - trunk/scripts/mod/modpost.c | 4 +- trunk/scripts/selinux/mdp/mdp.c | 4 +- trunk/security/integrity/ima/ima_fs.c | 4 +- trunk/security/smack/smack_lsm.c | 8 +- trunk/security/smack/smackfs.c | 6 +- trunk/usr/gen_init_cpio.c | 2 +- 382 files changed, 7048 insertions(+), 24137 deletions(-) delete mode 100644 trunk/Documentation/fb/ep93xx-fb.txt delete mode 100644 trunk/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c delete mode 100644 trunk/arch/arm/mach-ep93xx/include/mach/fb.h delete mode 100644 trunk/arch/arm/plat-mxc/include/mach/spi.h delete mode 100644 trunk/drivers/gpio/adp5520-gpio.c delete mode 100644 trunk/drivers/gpio/langwell_gpio.c delete mode 100644 trunk/drivers/gpio/mc33880.c delete mode 100644 trunk/drivers/gpio/ucb1400_gpio.c delete mode 100644 trunk/drivers/mmc/host/msm_sdcc.c delete mode 100644 trunk/drivers/mmc/host/msm_sdcc.h delete mode 100644 trunk/drivers/rtc/rtc-coh901331.c delete mode 100644 trunk/drivers/rtc/rtc-mxc.c delete mode 100644 trunk/drivers/rtc/rtc-pcap.c delete mode 100644 trunk/drivers/rtc/rtc-pcf2123.c delete mode 100644 trunk/drivers/rtc/rtc-stmp3xxx.c delete mode 100644 trunk/drivers/spi/mxc_spi.c create mode 100644 trunk/drivers/spi/spi_imx.c delete mode 100644 trunk/drivers/spi/spi_ppc4xx.c delete mode 100644 trunk/drivers/spi/spi_stmp.c delete mode 100644 trunk/drivers/video/da8xx-fb.c delete mode 100644 trunk/drivers/video/ep93xx-fb.c delete mode 100644 trunk/drivers/video/msm/Makefile delete mode 100644 trunk/drivers/video/msm/mddi.c delete mode 100644 trunk/drivers/video/msm/mddi_client_dummy.c delete mode 100644 trunk/drivers/video/msm/mddi_client_nt35399.c delete mode 100644 trunk/drivers/video/msm/mddi_client_toshiba.c delete mode 100644 trunk/drivers/video/msm/mddi_hw.h delete mode 100644 trunk/drivers/video/msm/mdp.c delete mode 100644 trunk/drivers/video/msm/mdp_csc_table.h delete mode 100644 trunk/drivers/video/msm/mdp_hw.h delete mode 100644 trunk/drivers/video/msm/mdp_ppp.c delete mode 100644 trunk/drivers/video/msm/mdp_scale_tables.c delete mode 100644 trunk/drivers/video/msm/mdp_scale_tables.h delete mode 100644 trunk/drivers/video/msm/msm_fb.c delete mode 100644 trunk/drivers/video/omap/lcd_2430sdp.c delete mode 100644 trunk/drivers/video/omap/lcd_ams_delta.c delete mode 100644 trunk/drivers/video/omap/lcd_apollon.c delete mode 100644 trunk/drivers/video/omap/lcd_ldp.c delete mode 100644 trunk/drivers/video/omap/lcd_mipid.c delete mode 100644 trunk/drivers/video/omap/lcd_omap2evm.c delete mode 100644 trunk/drivers/video/omap/lcd_omap3beagle.c delete mode 100644 trunk/drivers/video/omap/lcd_omap3evm.c delete mode 100644 trunk/drivers/video/omap/lcd_overo.c create mode 100644 trunk/fs/qnx4/file.c create mode 100644 trunk/fs/qnx4/truncate.c delete mode 100644 trunk/include/linux/spi/mc33880.h delete mode 100644 trunk/include/linux/virtio_ids.h delete mode 100644 trunk/include/video/da8xx-fb.h diff --git a/[refs] b/[refs] index 92a0b8d87517..a890872744c6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1f0918d03ff4b5c94540c71ce889672abdbc2f4a +refs/heads/master: e5dc8ae121592239c2a2521d383bcb789849b2a3 diff --git a/trunk/Documentation/ABI/testing/sysfs-gpio b/trunk/Documentation/ABI/testing/sysfs-gpio index 80f4c94c7bef..8aab8092ad35 100644 --- a/trunk/Documentation/ABI/testing/sysfs-gpio +++ b/trunk/Documentation/ABI/testing/sysfs-gpio @@ -19,7 +19,6 @@ 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 diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index 6e25c2659e0a..aa73e72fd793 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -116,7 +116,7 @@ static int create_nl_socket(int protocol) } -static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid, +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 @@ static 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 */ -static int get_family_id(int sd) +int get_family_id(int sd) { struct { struct nlmsghdr n; @@ -190,7 +190,7 @@ static int get_family_id(int sd) return id; } -static void print_delayacct(struct taskstats *t) +void print_delayacct(struct taskstats *t) { printf("\n\nCPU %15s%15s%15s%15s\n" " %15llu%15llu%15llu%15llu\n" @@ -216,7 +216,7 @@ static void print_delayacct(struct taskstats *t) (unsigned long long)t->freepages_delay_total); } -static void task_context_switch_counts(struct taskstats *t) +void task_context_switch_counts(struct taskstats *t) { printf("\n\nTask %15s%15s\n" " %15llu%15llu\n", @@ -224,7 +224,7 @@ static void task_context_switch_counts(struct taskstats *t) (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw); } -static void print_cgroupstats(struct cgroupstats *c) +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 @@ static void print_cgroupstats(struct cgroupstats *c) } -static void print_ioacct(struct taskstats *t) +void print_ioacct(struct taskstats *t) { printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n", t->ac_comm, diff --git a/trunk/Documentation/auxdisplay/cfag12864b-example.c b/trunk/Documentation/auxdisplay/cfag12864b-example.c index 1d2c010bae12..2caeea5e4993 100644 --- a/trunk/Documentation/auxdisplay/cfag12864b-example.c +++ b/trunk/Documentation/auxdisplay/cfag12864b-example.c @@ -62,7 +62,7 @@ unsigned char cfag12864b_buffer[CFAG12864B_SIZE]; * Unable to open: return = -1 * Unable to mmap: return = -2 */ -static int cfag12864b_init(char *path) +int cfag12864b_init(char *path) { cfag12864b_fd = open(path, O_RDWR); if (cfag12864b_fd == -1) @@ -81,7 +81,7 @@ static int cfag12864b_init(char *path) /* * exit a cfag12864b framebuffer device */ -static void cfag12864b_exit(void) +void cfag12864b_exit(void) { munmap(cfag12864b_mem, CFAG12864B_SIZE); close(cfag12864b_fd); @@ -90,7 +90,7 @@ static void cfag12864b_exit(void) /* * set (x, y) pixel */ -static void cfag12864b_set(unsigned char x, unsigned char y) +void cfag12864b_set(unsigned char x, unsigned char y) { if (CFAG12864B_CHECK(x, y)) cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |= @@ -100,7 +100,7 @@ static void cfag12864b_set(unsigned char x, unsigned char y) /* * unset (x, y) pixel */ -static void cfag12864b_unset(unsigned char x, unsigned char y) +void cfag12864b_unset(unsigned char x, unsigned char y) { if (CFAG12864B_CHECK(x, y)) cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &= @@ -113,7 +113,7 @@ static void cfag12864b_unset(unsigned char x, unsigned char y) * Pixel off: return = 0 * Pixel on: return = 1 */ -static unsigned char cfag12864b_isset(unsigned char x, unsigned char y) +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 @@ static unsigned char cfag12864b_isset(unsigned char x, unsigned char y) /* * not (x, y) pixel */ -static void cfag12864b_not(unsigned char x, unsigned char y) +void cfag12864b_not(unsigned char x, unsigned char y) { if (cfag12864b_isset(x, y)) cfag12864b_unset(x, y); @@ -137,7 +137,7 @@ static void cfag12864b_not(unsigned char x, unsigned char y) /* * fill (set all pixels) */ -static void cfag12864b_fill(void) +void cfag12864b_fill(void) { unsigned short i; @@ -148,7 +148,7 @@ static void cfag12864b_fill(void) /* * clear (unset all pixels) */ -static void cfag12864b_clear(void) +void cfag12864b_clear(void) { unsigned short i; @@ -162,7 +162,7 @@ static void cfag12864b_clear(void) * Pixel off: src[i] = 0 * Pixel on: src[i] > 0 */ -static void cfag12864b_format(unsigned char * matrix) +void cfag12864b_format(unsigned char * matrix) { unsigned char i, j, n; @@ -182,7 +182,7 @@ static void cfag12864b_format(unsigned char * matrix) /* * blit buffer to lcd */ -static void cfag12864b_blit(void) +void cfag12864b_blit(void) { memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE); } @@ -198,7 +198,7 @@ static void cfag12864b_blit(void) #define EXAMPLES 6 -static void example(unsigned char n) +void example(unsigned char n) { unsigned short i, j; unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT]; diff --git a/trunk/Documentation/fb/ep93xx-fb.txt b/trunk/Documentation/fb/ep93xx-fb.txt deleted file mode 100644 index 5af1bd9effae..000000000000 --- a/trunk/Documentation/fb/ep93xx-fb.txt +++ /dev/null @@ -1,135 +0,0 @@ -================================ -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. diff --git a/trunk/Documentation/fb/matroxfb.txt b/trunk/Documentation/fb/matroxfb.txt index e5ce8a1a978b..ad7a67707d62 100644 --- a/trunk/Documentation/fb/matroxfb.txt +++ b/trunk/Documentation/fb/matroxfb.txt @@ -186,7 +186,9 @@ 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. + Default is `every' known device for driver with multihead support + and first working device (usually dev:0) for driver without + multihead support. 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 diff --git a/trunk/Documentation/filesystems/ncpfs.txt b/trunk/Documentation/filesystems/ncpfs.txt index 5af164f4b37b..f12c30c93f2f 100644 --- a/trunk/Documentation/filesystems/ncpfs.txt +++ b/trunk/Documentation/filesystems/ncpfs.txt @@ -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. - -mars_nwe can be found on ftp.gwdg.de/pub/linux/misc/ncpfs. +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. diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index b5aee7838a00..75988ba26a51 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -176,7 +176,6 @@ 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 @@ -230,7 +229,6 @@ 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) @@ -309,7 +307,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 [threadstack:001ff4b4] +a7cb2000-a7eb2000 rw-p 00000000 00:00 0 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 @@ -345,7 +343,6 @@ 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. diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt index fa4dc077ae0e..e4b6985044a2 100644 --- a/trunk/Documentation/gpio.txt +++ b/trunk/Documentation/gpio.txt @@ -524,13 +524,6 @@ 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: @@ -562,11 +555,6 @@ 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 @@ -575,8 +563,3 @@ 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. diff --git a/trunk/Documentation/ia64/aliasing-test.c b/trunk/Documentation/ia64/aliasing-test.c index 3dfb76ca6931..d23610fb2ff9 100644 --- a/trunk/Documentation/ia64/aliasing-test.c +++ b/trunk/Documentation/ia64/aliasing-test.c @@ -24,7 +24,7 @@ int sum; -static int map_mem(char *path, off_t offset, size_t length, int touch) +int map_mem(char *path, off_t offset, size_t length, int touch) { int fd, rc; void *addr; @@ -62,7 +62,7 @@ static int map_mem(char *path, off_t offset, size_t length, int touch) return 0; } -static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch) +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 @@ static int scan_tree(char *path, char *file, off_t offset, size_t length, int to char buf[1024]; -static int read_rom(char *path) +int read_rom(char *path) { int fd, rc; size_t size = 0; @@ -146,7 +146,7 @@ static int read_rom(char *path) return size; } -static int scan_rom(char *path, char *file) +int scan_rom(char *path, char *file) { struct dirent **namelist; char *name, *path2; diff --git a/trunk/Documentation/lguest/lguest.c b/trunk/Documentation/lguest/lguest.c index ba9373f82ab5..950cde6d6e58 100644 --- a/trunk/Documentation/lguest/lguest.c +++ b/trunk/Documentation/lguest/lguest.c @@ -42,7 +42,6 @@ #include #include "linux/lguest_launcher.h" #include "linux/virtio_config.h" -#include #include "linux/virtio_net.h" #include "linux/virtio_blk.h" #include "linux/virtio_console.h" @@ -134,9 +133,6 @@ struct device { /* Is it operational */ bool running; - /* Does Guest want an intrrupt on empty? */ - bool irq_on_empty; - /* Device-specific data. */ void *priv; }; @@ -627,13 +623,10 @@ static void trigger_irq(struct virtqueue *vq) return; vq->pending_used = 0; - /* If they don't want an interrupt, don't send one... */ - if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { - /* ... unless they've asked us to force one on empty. */ - if (!vq->dev->irq_on_empty - || lg_last_avail(vq) != vq->vring.avail->idx) - return; - } + /* If they don't want an interrupt, don't send one, unless empty. */ + if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) + && lg_last_avail(vq) != vq->vring.avail->idx) + return; /* Send the Guest an interrupt tell them we used something up. */ if (write(lguest_fd, buf, sizeof(buf)) != 0) @@ -1049,15 +1042,6 @@ static void create_thread(struct virtqueue *vq) close(vq->eventfd); } -static bool accepted_feature(struct device *dev, unsigned int bit) -{ - const u8 *features = get_feature_bits(dev) + dev->feature_len; - - if (dev->feature_len < bit / CHAR_BIT) - return false; - return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT)); -} - static void start_device(struct device *dev) { unsigned int i; @@ -1071,8 +1055,6 @@ static void start_device(struct device *dev) verbose(" %02x", get_feature_bits(dev) [dev->feature_len+i]); - dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); - for (vq = dev->vq; vq; vq = vq->next) { if (vq->service) create_thread(vq); diff --git a/trunk/Documentation/pcmcia/crc32hash.c b/trunk/Documentation/pcmcia/crc32hash.c index 44f8beea7260..4210e5abab8a 100644 --- a/trunk/Documentation/pcmcia/crc32hash.c +++ b/trunk/Documentation/pcmcia/crc32hash.c @@ -8,7 +8,7 @@ #include #include -static unsigned int crc32(unsigned char const *p, unsigned int len) +unsigned int crc32(unsigned char const *p, unsigned int len) { int i; unsigned int crc = 0; diff --git a/trunk/Documentation/powerpc/dts-bindings/fsl/esdhc.txt b/trunk/Documentation/powerpc/dts-bindings/fsl/esdhc.txt index 8a0040738969..3ed3797b5086 100644 --- a/trunk/Documentation/powerpc/dts-bindings/fsl/esdhc.txt +++ b/trunk/Documentation/powerpc/dts-bindings/fsl/esdhc.txt @@ -10,8 +10,6 @@ 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. diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt index 9104c1062084..8deffcd68cb8 100644 --- a/trunk/Documentation/rtc.txt +++ b/trunk/Documentation/rtc.txt @@ -135,30 +135,6 @@ 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 @@ -209,8 +185,6 @@ 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! diff --git a/trunk/Documentation/spi/spi-summary b/trunk/Documentation/spi/spi-summary index deab51ddc33e..4a02d2508bc8 100644 --- a/trunk/Documentation/spi/spi-summary +++ b/trunk/Documentation/spi/spi-summary @@ -350,7 +350,7 @@ SPI protocol drivers somewhat resemble platform device drivers: .resume = CHIP_resume, }; -The driver core will automatically attempt to bind this driver to any SPI +The driver core will autmatically 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). diff --git a/trunk/Documentation/spi/spidev_test.c b/trunk/Documentation/spi/spidev_test.c index 10abd3773e49..c1a5aad3c75a 100644 --- a/trunk/Documentation/spi/spidev_test.c +++ b/trunk/Documentation/spi/spidev_test.c @@ -69,7 +69,7 @@ static void transfer(int fd) puts(""); } -static void print_usage(const char *prog) +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 @@ static void print_usage(const char *prog) exit(1); } -static void parse_opts(int argc, char *argv[]) +void parse_opts(int argc, char *argv[]) { while (1) { static const struct option lopts[] = { diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index b3d8b4922740..3e5b63ebb821 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -313,14 +313,6 @@ 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 diff --git a/trunk/Documentation/video4linux/v4lgrab.c b/trunk/Documentation/video4linux/v4lgrab.c index c8ded175796e..05769cff1009 100644 --- a/trunk/Documentation/video4linux/v4lgrab.c +++ b/trunk/Documentation/video4linux/v4lgrab.c @@ -89,7 +89,7 @@ } \ } -static int get_brightness_adj(unsigned char *image, long size, int *brightness) { +int get_brightness_adj(unsigned char *image, long size, int *brightness) { long i, tot = 0; for (i=0;i> 20; } -static void fatal(const char *x, ...) +void fatal(const char *x, ...) { va_list ap; @@ -178,7 +178,7 @@ static void fatal(const char *x, ...) * page flag names */ -static char *page_flag_name(uint64_t flags) +char *page_flag_name(uint64_t flags) { static char buf[65]; int present; @@ -197,7 +197,7 @@ static char *page_flag_name(uint64_t flags) return buf; } -static char *page_flag_longname(uint64_t flags) +char *page_flag_longname(uint64_t flags) { static char buf[1024]; int i, n; @@ -221,7 +221,7 @@ static char *page_flag_longname(uint64_t flags) * page list and summary */ -static void show_page_range(unsigned long offset, uint64_t flags) +void show_page_range(unsigned long offset, uint64_t flags) { static uint64_t flags0; static unsigned long index; @@ -241,12 +241,12 @@ static void show_page_range(unsigned long offset, uint64_t flags) count = 1; } -static void show_page(unsigned long offset, uint64_t flags) +void show_page(unsigned long offset, uint64_t flags) { printf("%lu\t%s\n", offset, page_flag_name(flags)); } -static void show_summary(void) +void show_summary(void) { int i; @@ -272,7 +272,7 @@ static void show_summary(void) * page flag filters */ -static int bit_mask_ok(uint64_t flags) +int bit_mask_ok(uint64_t flags) { int i; @@ -289,7 +289,7 @@ static int bit_mask_ok(uint64_t flags) return 1; } -static uint64_t expand_overloaded_flags(uint64_t flags) +uint64_t expand_overloaded_flags(uint64_t flags) { /* SLOB/SLUB overload several page flags */ if (flags & BIT(SLAB)) { @@ -308,7 +308,7 @@ static uint64_t expand_overloaded_flags(uint64_t flags) return flags; } -static uint64_t well_known_flags(uint64_t flags) +uint64_t well_known_flags(uint64_t flags) { /* hide flags intended only for kernel hacker */ flags &= ~KPF_HACKERS_BITS; @@ -325,7 +325,7 @@ static uint64_t well_known_flags(uint64_t flags) * page frame walker */ -static int hash_slot(uint64_t flags) +int hash_slot(uint64_t flags) { int k = HASH_KEY(flags); int i; @@ -352,7 +352,7 @@ static int hash_slot(uint64_t flags) exit(EXIT_FAILURE); } -static void add_page(unsigned long offset, uint64_t flags) +void add_page(unsigned long offset, uint64_t flags) { flags = expand_overloaded_flags(flags); @@ -371,7 +371,7 @@ static void add_page(unsigned long offset, uint64_t flags) total_pages++; } -static void walk_pfn(unsigned long index, unsigned long count) +void walk_pfn(unsigned long index, unsigned long count) { unsigned long batch; unsigned long n; @@ -404,7 +404,7 @@ static void walk_pfn(unsigned long index, unsigned long count) } } -static void walk_addr_ranges(void) +void walk_addr_ranges(void) { int i; @@ -428,7 +428,7 @@ static void walk_addr_ranges(void) * user interface */ -static const char *page_flag_type(uint64_t flag) +const char *page_flag_type(uint64_t flag) { if (flag & KPF_HACKERS_BITS) return "(r)"; @@ -437,7 +437,7 @@ static const char *page_flag_type(uint64_t flag) return " "; } -static void usage(void) +void usage(void) { int i, j; @@ -482,7 +482,7 @@ static void usage(void) "(r) raw mode bits (o) overloaded bits\n"); } -static unsigned long long parse_number(const char *str) +unsigned long long parse_number(const char *str) { unsigned long long n; @@ -494,16 +494,16 @@ static unsigned long long parse_number(const char *str) return n; } -static void parse_pid(const char *str) +void parse_pid(const char *str) { opt_pid = parse_number(str); } -static void parse_file(const char *name) +void parse_file(const char *name) { } -static void add_addr_range(unsigned long offset, unsigned long size) +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 @@ static void add_addr_range(unsigned long offset, unsigned long size) nr_addr_ranges++; } -static void parse_addr_range(const char *optarg) +void parse_addr_range(const char *optarg) { unsigned long offset; unsigned long size; @@ -547,7 +547,7 @@ static void parse_addr_range(const char *optarg) add_addr_range(offset, size); } -static void add_bits_filter(uint64_t mask, uint64_t bits) +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 @@ static void add_bits_filter(uint64_t mask, uint64_t bits) nr_bit_filters++; } -static uint64_t parse_flag_name(const char *str, int len) +uint64_t parse_flag_name(const char *str, int len) { int i; @@ -577,7 +577,7 @@ static uint64_t parse_flag_name(const char *str, int len) return parse_number(str); } -static uint64_t parse_flag_names(const char *str, int all) +uint64_t parse_flag_names(const char *str, int all) { const char *p = str; uint64_t flags = 0; @@ -596,7 +596,7 @@ static uint64_t parse_flag_names(const char *str, int all) return flags; } -static void parse_bits_mask(const char *optarg) +void parse_bits_mask(const char *optarg) { uint64_t mask; uint64_t bits; @@ -621,7 +621,7 @@ static void parse_bits_mask(const char *optarg) } -static struct option opts[] = { +struct option opts[] = { { "raw" , 0, NULL, 'r' }, { "pid" , 1, NULL, 'p' }, { "file" , 1, NULL, 'f' }, diff --git a/trunk/Documentation/vm/slabinfo.c b/trunk/Documentation/vm/slabinfo.c index 92e729f4b676..df3227605d59 100644 --- a/trunk/Documentation/vm/slabinfo.c +++ b/trunk/Documentation/vm/slabinfo.c @@ -87,7 +87,7 @@ int page_size; regex_t pattern; -static void fatal(const char *x, ...) +void fatal(const char *x, ...) { va_list ap; @@ -97,7 +97,7 @@ static void fatal(const char *x, ...) exit(EXIT_FAILURE); } -static void usage(void) +void usage(void) { printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n" "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n" @@ -131,7 +131,7 @@ static void usage(void) ); } -static unsigned long read_obj(const char *name) +unsigned long read_obj(const char *name) { FILE *f = fopen(name, "r"); @@ -151,7 +151,7 @@ static unsigned long read_obj(const char *name) /* * Get the contents of an attribute */ -static unsigned long get_obj(const char *name) +unsigned long get_obj(const char *name) { if (!read_obj(name)) return 0; @@ -159,7 +159,7 @@ static unsigned long get_obj(const char *name) return atol(buffer); } -static unsigned long get_obj_and_str(const char *name, char **x) +unsigned long get_obj_and_str(const char *name, char **x) { unsigned long result = 0; char *p; @@ -178,7 +178,7 @@ static unsigned long get_obj_and_str(const char *name, char **x) return result; } -static void set_obj(struct slabinfo *s, const char *name, int n) +void set_obj(struct slabinfo *s, const char *name, int n) { char x[100]; FILE *f; @@ -192,7 +192,7 @@ static void set_obj(struct slabinfo *s, const char *name, int n) fclose(f); } -static unsigned long read_slab_obj(struct slabinfo *s, const char *name) +unsigned long read_slab_obj(struct slabinfo *s, const char *name) { char x[100]; FILE *f; @@ -215,7 +215,7 @@ static unsigned long read_slab_obj(struct slabinfo *s, const char *name) /* * Put a size string together */ -static int store_size(char *buffer, unsigned long value) +int store_size(char *buffer, unsigned long value) { unsigned long divisor = 1; char trailer = 0; @@ -247,7 +247,7 @@ static int store_size(char *buffer, unsigned long value) return n; } -static void decode_numa_list(int *numa, char *t) +void decode_numa_list(int *numa, char *t) { int node; int nr; @@ -272,7 +272,7 @@ static void decode_numa_list(int *numa, char *t) } } -static void slab_validate(struct slabinfo *s) +void slab_validate(struct slabinfo *s) { if (strcmp(s->name, "*") == 0) return; @@ -280,7 +280,7 @@ static void slab_validate(struct slabinfo *s) set_obj(s, "validate", 1); } -static void slab_shrink(struct slabinfo *s) +void slab_shrink(struct slabinfo *s) { if (strcmp(s->name, "*") == 0) return; @@ -290,7 +290,7 @@ static void slab_shrink(struct slabinfo *s) int line = 0; -static void first_line(void) +void first_line(void) { if (show_activity) printf("Name Objects Alloc Free %%Fast Fallb O\n"); @@ -302,7 +302,7 @@ static void first_line(void) /* * Find the shortest alias of a slab */ -static struct aliasinfo *find_one_alias(struct slabinfo *find) +struct aliasinfo *find_one_alias(struct slabinfo *find) { struct aliasinfo *a; struct aliasinfo *best = NULL; @@ -318,18 +318,18 @@ static struct aliasinfo *find_one_alias(struct slabinfo *find) return best; } -static unsigned long slab_size(struct slabinfo *s) +unsigned long slab_size(struct slabinfo *s) { return s->slabs * (page_size << s->order); } -static unsigned long slab_activity(struct slabinfo *s) +unsigned long slab_activity(struct slabinfo *s) { return s->alloc_fastpath + s->free_fastpath + s->alloc_slowpath + s->free_slowpath; } -static void slab_numa(struct slabinfo *s, int mode) +void slab_numa(struct slabinfo *s, int mode) { int node; @@ -374,7 +374,7 @@ static void slab_numa(struct slabinfo *s, int mode) line++; } -static void show_tracking(struct slabinfo *s) +void show_tracking(struct slabinfo *s) { printf("\n%s: Kernel object allocation\n", s->name); printf("-----------------------------------------------------------------------\n"); @@ -392,7 +392,7 @@ static void show_tracking(struct slabinfo *s) } -static void ops(struct slabinfo *s) +void ops(struct slabinfo *s) { if (strcmp(s->name, "*") == 0) return; @@ -405,14 +405,14 @@ static void ops(struct slabinfo *s) printf("\n%s has no kmem_cache operations\n", s->name); } -static const char *onoff(int x) +const char *onoff(int x) { if (x) return "On "; return "Off"; } -static void slab_stats(struct slabinfo *s) +void slab_stats(struct slabinfo *s) { unsigned long total_alloc; unsigned long total_free; @@ -477,7 +477,7 @@ static void slab_stats(struct slabinfo *s) s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total); } -static void report(struct slabinfo *s) +void report(struct slabinfo *s) { if (strcmp(s->name, "*") == 0) return; @@ -518,7 +518,7 @@ static void report(struct slabinfo *s) slab_stats(s); } -static void slabcache(struct slabinfo *s) +void slabcache(struct slabinfo *s) { char size_str[20]; char dist_str[40]; @@ -593,7 +593,7 @@ static void slabcache(struct slabinfo *s) /* * Analyze debug options. Return false if something is amiss. */ -static int debug_opt_scan(char *opt) +int debug_opt_scan(char *opt) { if (!opt || !opt[0] || strcmp(opt, "-") == 0) return 1; @@ -642,7 +642,7 @@ static int debug_opt_scan(char *opt) return 1; } -static int slab_empty(struct slabinfo *s) +int slab_empty(struct slabinfo *s) { if (s->objects > 0) return 0; @@ -657,7 +657,7 @@ static int slab_empty(struct slabinfo *s) return 1; } -static void slab_debug(struct slabinfo *s) +void slab_debug(struct slabinfo *s) { if (strcmp(s->name, "*") == 0) return; @@ -717,7 +717,7 @@ static void slab_debug(struct slabinfo *s) set_obj(s, "trace", 1); } -static void totals(void) +void totals(void) { struct slabinfo *s; @@ -976,7 +976,7 @@ static void totals(void) b1, b2, b3); } -static void sort_slabs(void) +void sort_slabs(void) { struct slabinfo *s1,*s2; @@ -1005,7 +1005,7 @@ static void sort_slabs(void) } } -static void sort_aliases(void) +void sort_aliases(void) { struct aliasinfo *a1,*a2; @@ -1030,7 +1030,7 @@ static void sort_aliases(void) } } -static void link_slabs(void) +void link_slabs(void) { struct aliasinfo *a; struct slabinfo *s; @@ -1048,7 +1048,7 @@ static void link_slabs(void) } } -static void alias(void) +void alias(void) { struct aliasinfo *a; char *active = NULL; @@ -1079,7 +1079,7 @@ static void alias(void) } -static void rename_slabs(void) +void rename_slabs(void) { struct slabinfo *s; struct aliasinfo *a; @@ -1102,12 +1102,12 @@ static void rename_slabs(void) } } -static int slab_mismatch(char *slab) +int slab_mismatch(char *slab) { return regexec(&pattern, slab, 0, NULL, 0); } -static void read_slab_dir(void) +void read_slab_dir(void) { DIR *dir; struct dirent *de; @@ -1209,7 +1209,7 @@ static void read_slab_dir(void) fatal("Too many aliases\n"); } -static void output_slabs(void) +void output_slabs(void) { struct slabinfo *slab; diff --git a/trunk/Documentation/watchdog/src/watchdog-test.c b/trunk/Documentation/watchdog/src/watchdog-test.c index a750532ffcf8..65f6c19cb865 100644 --- a/trunk/Documentation/watchdog/src/watchdog-test.c +++ b/trunk/Documentation/watchdog/src/watchdog-test.c @@ -18,7 +18,7 @@ int fd; * the PC Watchdog card to reset its internal timer so it doesn't trigger * a computer reset. */ -static void keep_alive(void) +void keep_alive(void) { int dummy; diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index ed6cd99a57ba..d24c8823a8cb 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3527,6 +3527,7 @@ F: drivers/net/natsemi.c NCP FILESYSTEM M: Petr Vandrovec +L: linware@sh.cvut.cz S: Maintained F: fs/ncpfs/ @@ -3768,13 +3769,7 @@ OMAP MMC SUPPORT M: Jarkko Lavinen L: linux-omap@vger.kernel.org S: Maintained -F: drivers/mmc/host/omap.c - -OMAP HS MMC SUPPORT -M: Madhusudhan Chikkature -L: linux-omap@vger.kernel.org -S: Maintained -F: drivers/mmc/host/omap_hsmmc.c +F: drivers/mmc/host/*omap* OMAP RANDOM NUMBER GENERATOR SUPPORT M: Deepak Saxena @@ -4465,7 +4460,7 @@ SCORE ARCHITECTURE P: Chen Liqin M: liqin.chen@sunplusct.com P: Lennox Wu -M: lennox.wu@gmail.com +M: lennox.wu@sunplusct.com W: http://www.sunplusct.com S: Supported diff --git a/trunk/arch/arm/configs/n770_defconfig b/trunk/arch/arm/configs/n770_defconfig index a1657b73683f..672f6db06a52 100644 --- a/trunk/arch/arm/configs/n770_defconfig +++ b/trunk/arch/arm/configs/n770_defconfig @@ -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=y +# CONFIG_FB_OMAP_LCD_MIPID is not set # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # CONFIG_FB_OMAP_DMA_TUNE is not set diff --git a/trunk/arch/arm/configs/omap3_beagle_defconfig b/trunk/arch/arm/configs/omap3_beagle_defconfig index 357d4021e2d0..51c0fa8897cd 100644 --- a/trunk/arch/arm/configs/omap3_beagle_defconfig +++ b/trunk/arch/arm/configs/omap3_beagle_defconfig @@ -778,33 +778,7 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL 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_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -817,25 +791,6 @@ CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 # # 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 diff --git a/trunk/arch/arm/configs/omap_3430sdp_defconfig b/trunk/arch/arm/configs/omap_3430sdp_defconfig index 8a4a7e2ba87b..9a510eab75a6 100644 --- a/trunk/arch/arm/configs/omap_3430sdp_defconfig +++ b/trunk/arch/arm/configs/omap_3430sdp_defconfig @@ -1313,33 +1313,8 @@ CONFIG_DVB_ISL6421=m # Graphics support # # CONFIG_VGASTATE 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_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1356,16 +1331,6 @@ 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 diff --git a/trunk/arch/arm/configs/omap_ldp_defconfig b/trunk/arch/arm/configs/omap_ldp_defconfig index b9c48919a68c..679a4a3e265e 100644 --- a/trunk/arch/arm/configs/omap_ldp_defconfig +++ b/trunk/arch/arm/configs/omap_ldp_defconfig @@ -690,7 +690,6 @@ 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: @@ -743,7 +742,6 @@ 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 @@ -769,46 +767,8 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m -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 +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support @@ -820,16 +780,6 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=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_SND=y # CONFIG_SND_SEQUENCER is not set diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index e35d54d43e70..a24d824c428b 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -289,13 +289,6 @@ 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 # ---------------------------------------------------------- diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index ada440aab0c5..a6ed015d82ed 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -59,7 +59,6 @@ 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 diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index 07eb7b07e442..ee4ea0e720cf 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -278,102 +278,6 @@ 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/trunk/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/trunk/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c deleted file mode 100644 index a28e53faf71d..000000000000 --- a/trunk/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#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 diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 583f38a38df7..13f27a4b882d 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -37,7 +37,6 @@ #include #include #include -#include #include /* USB Device */ @@ -65,7 +64,6 @@ 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 */ @@ -75,9 +73,6 @@ 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; diff --git a/trunk/arch/arm/mach-ep93xx/clock.c b/trunk/arch/arm/mach-ep93xx/clock.c index dda19cd76194..3dd0e2a23095 100644 --- a/trunk/arch/arm/mach-ep93xx/clock.c +++ b/trunk/arch/arm/mach-ep93xx/clock.c @@ -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,13 +76,6 @@ 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, @@ -147,7 +140,6 @@ 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), @@ -244,84 +236,6 @@ 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) diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index f7ebed942f66..16b92c37ec99 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -683,37 +682,6 @@ 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) diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/trunk/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 0fbf87b16338..ea78e908fc82 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -70,7 +70,6 @@ #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) @@ -208,11 +207,6 @@ #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/trunk/arch/arm/mach-ep93xx/include/mach/fb.h b/trunk/arch/arm/mach-ep93xx/include/mach/fb.h deleted file mode 100644 index d5ae11d7c453..000000000000 --- a/trunk/arch/arm/mach-ep93xx/include/mach/fb.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 */ diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h index 01a0f0838e5b..5f5fa6574d34 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h @@ -6,7 +6,6 @@ struct i2c_board_info; struct platform_device; -struct ep93xxfb_mach_info; struct ep93xx_eth_data { @@ -34,7 +33,6 @@ 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); diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index e6e8290b7828..e70baa799018 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -103,7 +102,6 @@ static struct twl4030_hsmmc_info mmc[] = { .cover_only = true, .gpio_cd = 160, .gpio_wp = -EINVAL, - .power_saving = true, }, { .name = "internal", @@ -111,8 +109,6 @@ static struct twl4030_hsmmc_info mmc[] = { .wires = 8, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, - .nonremovable = true, - .power_saving = true, }, {} /* Terminator */ }; diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index bcfcfc7fdb9b..a2e915639b72 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -257,11 +257,6 @@ 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, }; @@ -306,8 +301,7 @@ static struct platform_device omap2_mcspi2 = { }, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) static struct omap2_mcspi_platform_config omap2_mcspi3_config = { .num_cs = 2, }; @@ -331,7 +325,7 @@ static struct platform_device omap2_mcspi3 = { }; #endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP3 static struct omap2_mcspi_platform_config omap2_mcspi4_config = { .num_cs = 1, }; @@ -357,25 +351,14 @@ 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) || \ - defined(CONFIG_ARCH_OMAP4) - if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) + if (cpu_is_omap2430() || cpu_is_omap343x()) platform_device_register(&omap2_mcspi3); #endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) - if (cpu_is_omap343x() || cpu_is_omap44xx()) +#ifdef CONFIG_ARCH_OMAP3 + if (cpu_is_omap343x()) platform_device_register(&omap2_mcspi4); #endif } @@ -414,7 +397,7 @@ static inline void omap_init_sha1_md5(void) { } /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP3 #define MMCHS_SYSCONFIG 0x0010 #define MMCHS_SYSCONFIG_SWRESET (1 << 1) @@ -441,8 +424,8 @@ static struct platform_device dummy_pdev = { **/ static void __init omap_hsmmc_reset(void) { - u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : - (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); + u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : + OMAP24XX_NR_MMC; for (i = 0; i < nr_controllers; i++) { u32 v, base = 0; @@ -459,21 +442,8 @@ 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"); @@ -611,23 +581,11 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, irq = INT_24XX_MMC2_IRQ; break; case 2: - if (!cpu_is_omap44xx() && !cpu_is_omap34xx()) + if (!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; } @@ -635,15 +593,8 @@ 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 = OMAP3_HSMMC_SIZE; + size = HSMMC_SIZE; name = "mmci-omap-hs"; } omap_mmc_add(name, i, base, size, irq, mmc_data[i]); diff --git a/trunk/arch/arm/mach-omap2/mmc-twl4030.c b/trunk/arch/arm/mach-omap2/mmc-twl4030.c index c9c59a2db4e2..3c04c2f1b23f 100644 --- a/trunk/arch/arm/mach-omap2/mmc-twl4030.c +++ b/trunk/arch/arm/mach-omap2/mmc-twl4030.c @@ -198,18 +198,6 @@ 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) { @@ -340,61 +328,6 @@ 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) @@ -457,9 +390,6 @@ 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"); @@ -470,12 +400,6 @@ 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. @@ -488,7 +412,6 @@ 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) @@ -499,7 +422,6 @@ 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); diff --git a/trunk/arch/arm/mach-omap2/mmc-twl4030.h b/trunk/arch/arm/mach-omap2/mmc-twl4030.h index a47e68563fb6..3807c45c9a6c 100644 --- a/trunk/arch/arm/mach-omap2/mmc-twl4030.h +++ b/trunk/arch/arm/mach-omap2/mmc-twl4030.h @@ -12,8 +12,6 @@ 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/trunk/arch/arm/plat-mxc/include/mach/spi.h b/trunk/arch/arm/plat-mxc/include/mach/spi.h deleted file mode 100644 index 08be445e8eb8..000000000000 --- a/trunk/arch/arm/plat-mxc/include/mach/spi.h +++ /dev/null @@ -1,27 +0,0 @@ - -#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_*/ diff --git a/trunk/arch/arm/plat-omap/include/mach/irqs.h b/trunk/arch/arm/plat-omap/include/mach/irqs.h index 28a165058b61..fb7cb7723990 100644 --- a/trunk/arch/arm/plat-omap/include/mach/irqs.h +++ b/trunk/arch/arm/plat-omap/include/mach/irqs.h @@ -503,7 +503,6 @@ #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) @@ -512,7 +511,6 @@ #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 diff --git a/trunk/arch/arm/plat-omap/include/mach/lcd_mipid.h b/trunk/arch/arm/plat-omap/include/mach/lcd_mipid.h index 8e52c6572281..f8fbc4801e52 100644 --- a/trunk/arch/arm/plat-omap/include/mach/lcd_mipid.h +++ b/trunk/arch/arm/plat-omap/include/mach/lcd_mipid.h @@ -16,12 +16,7 @@ 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 diff --git a/trunk/arch/arm/plat-omap/include/mach/mmc.h b/trunk/arch/arm/plat-omap/include/mach/mmc.h index 7229b9593301..81d5b36534b3 100644 --- a/trunk/arch/arm/plat-omap/include/mach/mmc.h +++ b/trunk/arch/arm/plat-omap/include/mach/mmc.h @@ -25,18 +25,11 @@ #define OMAP24XX_NR_MMC 2 #define OMAP34XX_NR_MMC 3 -#define OMAP44XX_NR_MMC 5 #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE -#define OMAP3_HSMMC_SIZE 0x200 -#define OMAP4_HSMMC_SIZE 0x1000 +#define HSMMC_SIZE 0x200 #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) @@ -66,9 +59,6 @@ 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 { @@ -90,20 +80,12 @@ 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. * diff --git a/trunk/arch/arm/plat-omap/include/mach/omapfb.h b/trunk/arch/arm/plat-omap/include/mach/omapfb.h index b226bdf45739..7b74d1255e0b 100644 --- a/trunk/arch/arm/plat-omap/include/mach/omapfb.h +++ b/trunk/arch/arm/plat-omap/include/mach/omapfb.h @@ -276,8 +276,8 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, void *fbi); struct omapfb_mem_region { - u32 paddr; - void __iomem *vaddr; + dma_addr_t paddr; + void *vaddr; unsigned long size; u8 type; /* OMAPFB_PLANE_MEM_* */ unsigned alloc:1; /* allocated by the driver */ diff --git a/trunk/arch/blackfin/include/asm/sections.h b/trunk/arch/blackfin/include/asm/sections.h index ae4dae1e370b..e7fd0ecd73f7 100644 --- a/trunk/arch/blackfin/include/asm/sections.h +++ b/trunk/arch/blackfin/include/asm/sections.h @@ -1,6 +1,9 @@ #ifndef _BLACKFIN_SECTIONS_H #define _BLACKFIN_SECTIONS_H +/* nothing to see, move along */ +#include + /* only used when MTD_UCLINUX */ extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; @@ -12,39 +15,4 @@ 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 - -/* 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 - #endif diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 6851e52ed5a2..011a1cdf0eb5 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -500,10 +500,6 @@ 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 diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 1857766a63c1..1d286244a562 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -617,6 +617,7 @@ 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); @@ -638,6 +639,10 @@ 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); diff --git a/trunk/arch/mips/mm/init.c b/trunk/arch/mips/mm/init.c index 15aa1902a788..1f4ee4797a6e 100644 --- a/trunk/arch/mips/mm/init.c +++ b/trunk/arch/mips/mm/init.c @@ -352,6 +352,7 @@ 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 @@ -408,9 +409,11 @@ 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, KCORE_TEXT); + kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4); #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", diff --git a/trunk/arch/mn10300/kernel/setup.c b/trunk/arch/mn10300/kernel/setup.c index 3f24c298a3af..79890edfd67a 100644 --- a/trunk/arch/mn10300/kernel/setup.c +++ b/trunk/arch/mn10300/kernel/setup.c @@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, void *v) { } -const struct seq_operations cpuinfo_op = { +struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts index 855782c5e5ec..f32c2811c6d9 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -159,7 +159,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts index 9e2264b10008..28e022ac4179 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -173,7 +173,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_wlan.dts b/trunk/arch/powerpc/boot/dts/mpc8377_wlan.dts index 9a603695723b..3febc4e91b10 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_wlan.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_wlan.dts @@ -150,7 +150,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; clock-frequency = <133333333>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts index f70cf6000839..f720ab9af30d 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -159,7 +159,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4e6a1a407bbd..a11ead8214b4 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -173,7 +173,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts index 645ec51cc6e1..4fa221fd9bdc 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -157,7 +157,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <0>; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts index 72336d504528..e35dfba587c8 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -171,7 +171,6 @@ reg = <0x2e000 0x1000>; interrupts = <42 0x8>; interrupt-parent = <&ipic>; - sdhci,wp-inverted; /* Filled in by U-Boot */ clock-frequency = <111111111>; }; diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index 1d5570a1e456..02fed27af7f6 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, void *v) { } -const struct seq_operations cpuinfo_op = { +struct seq_operations cpuinfo_op = { .start =c_start, .next = c_next, .stop = c_stop, diff --git a/trunk/arch/powerpc/mm/init_32.c b/trunk/arch/powerpc/mm/init_32.c index 9ddcfb4dc139..3ef5084b90ca 100644 --- a/trunk/arch/powerpc/mm/init_32.c +++ b/trunk/arch/powerpc/mm/init_32.c @@ -242,3 +242,39 @@ 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 diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index 335c578b9cc3..31582329cd67 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -109,6 +109,35 @@ 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); diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 59736317bf0e..0e5c59b995ef 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -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_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, - void *arg, int (*func)(unsigned long, unsigned long, void *)) +walk_memory_resource(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_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, } return ret; } -EXPORT_SYMBOL_GPL(walk_system_ram_range); +EXPORT_SYMBOL_GPL(walk_memory_resource); /* * Initialize the bootmem system and give it all the memory we diff --git a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c index 3631a4f277eb..eae51ef9af24 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, void *p) return 0; } -static const struct seq_operations hcall_inst_seq_ops = { +static struct seq_operations hcall_inst_seq_ops = { .start = hc_start, .next = hc_next, .stop = hc_stop, diff --git a/trunk/arch/score/include/asm/page.h b/trunk/arch/score/include/asm/page.h index d92a5a2d36d4..ee5821042fcc 100644 --- a/trunk/arch/score/include/asm/page.h +++ b/trunk/arch/score/include/asm/page.h @@ -2,11 +2,10 @@ #define _ASM_SCORE_PAGE_H #include -#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT (12) -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #ifdef __KERNEL__ diff --git a/trunk/arch/score/include/asm/thread_info.h b/trunk/arch/score/include/asm/thread_info.h index 55939992c27d..3a1122885528 100644 --- a/trunk/arch/score/include/asm/thread_info.h +++ b/trunk/arch/score/include/asm/thread_info.h @@ -7,15 +7,6 @@ #define KU_USER 0x08 #define KU_KERN 0x00 -#include -#include - -/* thread information allocation */ -#define THREAD_SIZE_ORDER (1) -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) -#define THREAD_MASK (THREAD_SIZE - _AC(1,UL)) -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR - #ifndef __ASSEMBLY__ #include @@ -71,6 +62,12 @@ struct thread_info { register struct thread_info *__current_thread_info __asm__("r28"); #define current_thread_info() __current_thread_info +/* thread information allocation */ +#define THREAD_SIZE_ORDER (1) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_MASK (THREAD_SIZE - 1UL) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) #define free_thread_info(info) kfree(info) diff --git a/trunk/arch/score/kernel/vmlinux.lds.S b/trunk/arch/score/kernel/vmlinux.lds.S index eebcbaa4e978..f85569831d5c 100644 --- a/trunk/arch/score/kernel/vmlinux.lds.S +++ b/trunk/arch/score/kernel/vmlinux.lds.S @@ -24,8 +24,6 @@ */ #include -#include -#include OUTPUT_ARCH(score) ENTRY(_stext) @@ -51,9 +49,21 @@ SECTIONS . = ALIGN(16); RODATA - EXCEPTION_TABLE(16) + /* Exception table */ + . = ALIGN(16); + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } - RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) + /* writeable */ + .data ALIGN (4096): { + *(.data.init_task) + + DATA_DATA + CONSTRUCTORS + } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so @@ -62,14 +72,45 @@ SECTIONS .sdata : { *(.sdata) } + + . = ALIGN(32); + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } _edata = .; /* End of data section */ /* will be freed after init */ - . = ALIGN(PAGE_SIZE); /* Init code and data */ + . = ALIGN(4096); /* Init code and data */ __init_begin = .; - INIT_TEXT_SECTION(PAGE_SIZE) - INIT_DATA_SECTION(16) + . = ALIGN(4096); + .init.text : { + _sinittext = .; + INIT_TEXT + _einittext = .; + } + .init.data : { + INIT_DATA + } + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + SECURITY_INIT /* .exit.text is discarded at runtime, not link time, to deal with * references from .rodata @@ -80,10 +121,28 @@ SECTIONS .exit.data : { EXIT_DATA } - . = ALIGN(PAGE_SIZE); +#if defined(CONFIG_BLK_DEV_INITRD) + .init.ramfs ALIGN(4096): { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + . = ALIGN(4); + LONG(0); + } +#endif + . = ALIGN(4096); __init_end = .; /* freed after init ends here */ - BSS_SECTION(0, 0, 0) + __bss_start = .; /* BSS */ + .sbss : { + *(.sbss) + *(.scommon) + } + .bss : { + *(.bss) + *(COMMON) + } + __bss_stop = .; _end = .; } diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index 8173e38afd38..fabb7c6f48d2 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -186,6 +186,8 @@ 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; @@ -224,6 +226,10 @@ 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), diff --git a/trunk/arch/sparc/include/asm/vio.h b/trunk/arch/sparc/include/asm/vio.h index 6cdbf7e7351d..d4de32f0f8af 100644 --- a/trunk/arch/sparc/include/asm/vio.h +++ b/trunk/arch/sparc/include/asm/vio.h @@ -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) { - MAYBE_BUILD_BUG_ON(!is_power_of_2(ring_size)); + BUILD_BUG_ON(!is_power_of_2(ring_size)); return (dr->pending - ((dr->prod - dr->cons) & (ring_size - 1))); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 7c7a54bed4a6..e4ff5d1280ca 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1204,10 +1204,6 @@ 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 diff --git a/trunk/arch/x86/include/asm/syscall.h b/trunk/arch/x86/include/asm/syscall.h index 8d33bc5462d1..d82f39bb7905 100644 --- a/trunk/arch/x86/include/asm/syscall.h +++ b/trunk/arch/x86/include/asm/syscall.h @@ -1,7 +1,7 @@ /* * Access to user system call parameters and results * - * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. + * Copyright (C) 2008 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 @@ -16,13 +16,13 @@ #include #include -/* - * 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) +static inline long 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; } diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 7b058a2dc66a..8d7d5c9c1be3 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -325,6 +325,16 @@ 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; @@ -1116,15 +1126,10 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value) case offsetof(struct user32, regs.orig_eax): /* - * 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. + * Sign-extend the value so that orig_eax = -1 + * causes (long)orig_ax < 0 tests to fire correctly. */ - regs->orig_ax = value; - if (syscall_get_nr(child, regs) >= 0) - task_thread_info(child)->status |= TS_COMPAT; + regs->orig_ax = (long) (s32) value; break; case offsetof(struct user32, regs.eflags): diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index 7e59dc1d3fc2..4cb7d5d18b8e 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -1135,6 +1135,11 @@ static struct notifier_block paniced = { /* Setting up memory is fairly easy. */ static __init char *lguest_memory_setup(void) { + /* We do this here and not earlier because lockcheck used to barf if we + * did it before start_kernel(). I think we fixed that, so it'd be + * nice to move it back to lguest_init. Patch welcome... */ + atomic_notifier_chain_register(&panic_notifier_list, &paniced); + /* *The Linux bootloader header contains an "e820" memory map: the * Launcher populated the first entry with our memory limit. @@ -1359,13 +1364,10 @@ __init void lguest_init(void) /* * If we don't initialize the lock dependency checker now, it crashes - * atomic_notifier_chain_register, then paravirt_disable_iospace. + * paravirt_disable_iospace. */ lockdep_init(); - /* Hook in our special panic hypercall code. */ - atomic_notifier_chain_register(&panic_notifier_list, &paniced); - /* * The IDE code spends about 3 seconds probing for disks: if we reserve * all the I/O ports up front it can't get them and so doesn't probe. diff --git a/trunk/arch/x86/mm/init_32.c b/trunk/arch/x86/mm/init_32.c index 30938c1d8d5d..b49b4f67453d 100644 --- a/trunk/arch/x86/mm/init_32.c +++ b/trunk/arch/x86/mm/init_32.c @@ -857,6 +857,8 @@ 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; @@ -884,6 +886,10 @@ 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), diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index 5a4398a6006b..810bd31e7f5f 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -647,7 +647,8 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif /* CONFIG_MEMORY_HOTPLUG */ -static struct kcore_list kcore_vsyscall; +static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, + kcore_modules, kcore_vsyscall; void __init mem_init(void) { @@ -676,8 +677,13 @@ 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, KCORE_OTHER); + VSYSCALL_END - VSYSCALL_START); printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n", diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 6fa7b0fdbdfd..c77b6f3c28ea 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -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 (Length > 0 && CommandBuffer[Length-1] == '\n') + if (CommandBuffer[Length-1] == '\n') CommandBuffer[--Length] = '\0'; if (Controller->FirmwareType == DAC960_V1_Controller) return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer) diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 24c3e21ab263..4f19105f755c 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -363,7 +363,7 @@ static void cciss_seq_stop(struct seq_file *seq, void *v) h->busy_configuring = 0; } -static const struct seq_operations cciss_seq_ops = { +static struct seq_operations cciss_seq_ops = { .start = cciss_seq_start, .show = cciss_seq_show, .next = cciss_seq_next, diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 43f19389647a..aa89fe45237d 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -92,26 +91,15 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, return false; vbr->req = req; - switch (req->cmd_type) { - case REQ_TYPE_FS: + if (blk_fs_request(vbr->req)) { vbr->out_hdr.type = 0; vbr->out_hdr.sector = blk_rq_pos(vbr->req); vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); - break; - case REQ_TYPE_BLOCK_PC: + } else if (blk_pc_request(vbr->req)) { vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); - break; - case REQ_TYPE_LINUX_BLOCK: - if (req->cmd[0] == REQ_LB_OP_FLUSH) { - vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; - vbr->out_hdr.sector = 0; - vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); - break; - } - /*FALLTHRU*/ - default: + } else { /* We don't put anything else in the queue. */ BUG(); } @@ -151,7 +139,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, } } - if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { + if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) { mempool_free(vbr, vblk->pool); return false; } @@ -211,12 +199,6 @@ static int virtblk_identify(struct gendisk *disk, void *argp) return err; } -static void virtblk_prepare_flush(struct request_queue *q, struct request *req) -{ - req->cmd_type = REQ_TYPE_LINUX_BLOCK; - req->cmd[0] = REQ_LB_OP_FLUSH; -} - static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { @@ -355,10 +337,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) index++; /* If barriers are supported, tell block layer that queue is ordered */ - if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) - blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_DRAIN_FLUSH, - virtblk_prepare_flush); - else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) + if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); /* If disk is read-only in the host, the guest should obey */ @@ -445,7 +424,7 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, - VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH + VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY }; /* diff --git a/trunk/drivers/char/hw_random/virtio-rng.c b/trunk/drivers/char/hw_random/virtio-rng.c index 962968f05b94..32216b623248 100644 --- a/trunk/drivers/char/hw_random/virtio-rng.c +++ b/trunk/drivers/char/hw_random/virtio-rng.c @@ -21,7 +21,6 @@ #include #include #include -#include #include /* The host will fill any buffer we give it with sweet, sweet randomness. We @@ -52,7 +51,7 @@ static void register_buffer(void) sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left); /* There should always be room for one buffer. */ - if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0) + if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) != 0) BUG(); vq->vq_ops->kick(vq); } diff --git a/trunk/drivers/char/misc.c b/trunk/drivers/char/misc.c index 07fa612a58d5..1ee27cc23426 100644 --- a/trunk/drivers/char/misc.c +++ b/trunk/drivers/char/misc.c @@ -91,7 +91,7 @@ static int misc_seq_show(struct seq_file *seq, void *v) } -static const struct seq_operations misc_seq_ops = { +static struct seq_operations misc_seq_ops = { .start = misc_seq_start, .next = misc_seq_next, .stop = misc_seq_stop, diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 32b957efa420..b0603b2e5684 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -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); - BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE); + BUILD_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; - BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE); + BUILD_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, diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index bf2170fb1cdd..0c2f55a38b95 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -343,14 +343,14 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) return 0; } -static const struct seq_operations tpm_ascii_b_measurments_seqops = { +static 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 const struct seq_operations tpm_binary_b_measurments_seqops = { +static struct seq_operations tpm_binary_b_measurments_seqops = { .start = tpm_bios_measurements_start, .next = tpm_bios_measurements_next, .stop = tpm_bios_measurements_stop, diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index 0d328b59568d..c74dacfa6795 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "hvc_console.h" @@ -66,7 +65,7 @@ static int put_chars(u32 vtermno, const char *buf, int count) /* add_buf wants a token to identify this buffer: we hand it any * non-NULL pointer, since there's only ever one buffer. */ - if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) >= 0) { + if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) { /* Tell Host to go! */ out_vq->vq_ops->kick(out_vq); /* Chill out until it's done with the buffer. */ @@ -86,7 +85,7 @@ static void add_inbuf(void) sg_init_one(sg, inbuf, PAGE_SIZE); /* We should always be able to add one buffer to an empty queue. */ - if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) < 0) + if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) != 0) BUG(); in_vq->vq_ops->kick(in_vq); } diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index abf4a2529f80..85e5dc0431fe 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -139,31 +139,6 @@ 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; diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 2ad0128c63c6..6b4c484a699a 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -162,16 +162,6 @@ 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 @@ -190,12 +180,6 @@ 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 @@ -211,23 +195,4 @@ 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 diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile index 00a532c9a1e2..ea7c745f26a8 100644 --- a/trunk/drivers/gpio/Makefile +++ b/trunk/drivers/gpio/Makefile @@ -4,17 +4,13 @@ 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/trunk/drivers/gpio/adp5520-gpio.c b/trunk/drivers/gpio/adp5520-gpio.c deleted file mode 100644 index ad05bbc7ffd5..000000000000 --- a/trunk/drivers/gpio/adp5520-gpio.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * GPIO driver for Analog Devices ADP5520 MFD PMICs - * - * Copyright 2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include - -#include - -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, ®_val); - else - adp5520_read(dev->master, GPIO_IN, ®_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 "); -MODULE_DESCRIPTION("GPIO ADP5520 Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:adp5520-gpio"); diff --git a/trunk/drivers/gpio/bt8xxgpio.c b/trunk/drivers/gpio/bt8xxgpio.c index 2559f2289409..55904140213b 100644 --- a/trunk/drivers/gpio/bt8xxgpio.c +++ b/trunk/drivers/gpio/bt8xxgpio.c @@ -46,7 +46,8 @@ #include #include #include -#include + +#include /* Steal the hardware definitions from the bttv driver. */ #include "../media/video/bt8xx/bt848.h" diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index bb11a429394a..51a8d4103be5 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -8,7 +7,6 @@ #include #include #include -#include /* Optional implementation infrastructure for GPIO interfaces. @@ -51,13 +49,6 @@ 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; @@ -65,15 +56,6 @@ 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 @@ -206,10 +188,10 @@ static DEFINE_MUTEX(sysfs_lock); * /value * * always readable, subject to hardware behavior * * may be writable, as zero/nonzero - * /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" + * + * 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". */ static ssize_t gpio_direction_show(struct device *dev, @@ -306,175 +288,6 @@ 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, @@ -660,7 +473,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, @@ -668,14 +481,6 @@ 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 @@ -699,51 +504,6 @@ 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 @@ -767,7 +527,6 @@ 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); @@ -852,8 +611,6 @@ 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/trunk/drivers/gpio/langwell_gpio.c b/trunk/drivers/gpio/langwell_gpio.c deleted file mode 100644 index 5711ce5353c6..000000000000 --- a/trunk/drivers/gpio/langwell_gpio.c +++ /dev/null @@ -1,297 +0,0 @@ -/* 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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); diff --git a/trunk/drivers/gpio/max7301.c b/trunk/drivers/gpio/max7301.c index 480956f1ca50..7b82eaae2621 100644 --- a/trunk/drivers/gpio/max7301.c +++ b/trunk/drivers/gpio/max7301.c @@ -339,4 +339,3 @@ 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/trunk/drivers/gpio/mc33880.c b/trunk/drivers/gpio/mc33880.c deleted file mode 100644 index e7d01bd8fdb3..000000000000 --- a/trunk/drivers/gpio/mc33880.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -#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 "); -MODULE_LICENSE("GPL v2"); - diff --git a/trunk/drivers/gpio/mcp23s08.c b/trunk/drivers/gpio/mcp23s08.c index cd651ec8d034..f6fae0e50e65 100644 --- a/trunk/drivers/gpio/mcp23s08.c +++ b/trunk/drivers/gpio/mcp23s08.c @@ -6,10 +6,12 @@ #include #include #include -#include + #include #include +#include + /* Registers are all 8 bits wide. * @@ -431,4 +433,3 @@ static void __exit mcp23s08_exit(void) module_exit(mcp23s08_exit); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:mcp23s08"); diff --git a/trunk/drivers/gpio/pca953x.c b/trunk/drivers/gpio/pca953x.c index 6a2fb3fbb3d9..cdb6574d25a6 100644 --- a/trunk/drivers/gpio/pca953x.c +++ b/trunk/drivers/gpio/pca953x.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #ifdef CONFIG_OF_GPIO @@ -21,6 +20,8 @@ #include #endif +#include + #define PCA953X_INPUT 0 #define PCA953X_OUTPUT 1 #define PCA953X_INVERT 2 @@ -39,7 +40,6 @@ static const struct i2c_device_id pca953x_id[] = { { "pca9557", 8, }, { "max7310", 8, }, - { "max7315", 8, }, { "pca6107", 8, }, { "tca6408", 8, }, { "tca6416", 16, }, diff --git a/trunk/drivers/gpio/pcf857x.c b/trunk/drivers/gpio/pcf857x.c index 72f2449c1c87..9525724be731 100644 --- a/trunk/drivers/gpio/pcf857x.c +++ b/trunk/drivers/gpio/pcf857x.c @@ -20,10 +20,11 @@ #include #include -#include #include #include +#include + static const struct i2c_device_id pcf857x_id[] = { { "pcf8574", 8 }, diff --git a/trunk/drivers/gpio/ucb1400_gpio.c b/trunk/drivers/gpio/ucb1400_gpio.c deleted file mode 100644 index 50e6bd1392ce..000000000000 --- a/trunk/drivers/gpio/ucb1400_gpio.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Philips UCB1400 GPIO driver - * - * Author: Marek Vasut - * - * 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 -#include - -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"); diff --git a/trunk/drivers/hwmon/adcxx.c b/trunk/drivers/hwmon/adcxx.c index 5e9e095f1136..242294db3db6 100644 --- a/trunk/drivers/hwmon/adcxx.c +++ b/trunk/drivers/hwmon/adcxx.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #define DRVNAME "adcxx" @@ -158,9 +157,8 @@ static struct sensor_device_attribute ad_input[] = { /*----------------------------------------------------------------------*/ -static int __devinit adcxx_probe(struct spi_device *spi) +static int __devinit adcxx_probe(struct spi_device *spi, int channels) { - int channels = spi_get_device_id(spi)->driver_data; struct adcxx *adc; int status; int i; @@ -206,6 +204,26 @@ static int __devinit adcxx_probe(struct spi_device *spi) 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); @@ -223,33 +241,79 @@ static int __devexit adcxx_remove(struct spi_device *spi) return 0; } -static const struct spi_device_id adcxx_ids[] = { - { "adcxx1s", 1 }, - { "adcxx2s", 2 }, - { "adcxx4s", 4 }, - { "adcxx8s", 8 }, - { }, +static struct spi_driver adcxx1s_driver = { + .driver = { + .name = "adcxx1s", + .owner = THIS_MODULE, + }, + .probe = adcxx1s_probe, + .remove = __devexit_p(adcxx_remove), }; -MODULE_DEVICE_TABLE(spi, adcxx_ids); -static struct spi_driver adcxx_driver = { +static struct spi_driver adcxx2s_driver = { .driver = { - .name = "adcxx", + .name = "adcxx2s", .owner = THIS_MODULE, }, - .id_table = adcxx_ids, - .probe = adcxx_probe, + .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, .remove = __devexit_p(adcxx_remove), }; static int __init init_adcxx(void) { - return spi_register_driver(&adcxx_driver); + 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; } static void __exit exit_adcxx(void) { - spi_unregister_driver(&adcxx_driver); + spi_unregister_driver(&adcxx1s_driver); + spi_unregister_driver(&adcxx2s_driver); + spi_unregister_driver(&adcxx4s_driver); + spi_unregister_driver(&adcxx8s_driver); } module_init(init_adcxx); @@ -258,3 +322,8 @@ 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"); diff --git a/trunk/drivers/hwmon/dme1737.c b/trunk/drivers/hwmon/dme1737.c index 2c2cb1ec94c5..9814d51b3af4 100644 --- a/trunk/drivers/hwmon/dme1737.c +++ b/trunk/drivers/hwmon/dme1737.c @@ -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]); diff --git a/trunk/drivers/hwmon/lis3lv02d_spi.c b/trunk/drivers/hwmon/lis3lv02d_spi.c index ecd739534f6a..82ebca5a699c 100644 --- a/trunk/drivers/hwmon/lis3lv02d_spi.c +++ b/trunk/drivers/hwmon/lis3lv02d_spi.c @@ -139,4 +139,4 @@ module_exit(lis302dl_exit); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("lis3lv02d SPI glue layer"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:" DRV_NAME); + diff --git a/trunk/drivers/hwmon/lm70.c b/trunk/drivers/hwmon/lm70.c index ab8a5d3c7690..ae6204f33214 100644 --- a/trunk/drivers/hwmon/lm70.c +++ b/trunk/drivers/hwmon/lm70.c @@ -32,7 +32,6 @@ #include #include #include -#include #include @@ -131,20 +130,11 @@ static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); /*----------------------------------------------------------------------*/ -static int __devinit lm70_probe(struct spi_device *spi) +static int __devinit common_probe(struct spi_device *spi, int chip) { - 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); @@ -180,6 +170,24 @@ static int __devinit lm70_probe(struct spi_device *spi) 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); @@ -193,32 +201,41 @@ static int __devexit lm70_remove(struct spi_device *spi) return 0; } - -static const struct spi_device_id lm70_ids[] = { - { "lm70", LM70_CHIP_LM70 }, - { "tmp121", LM70_CHIP_TMP121 }, - { }, +static struct spi_driver tmp121_driver = { + .driver = { + .name = "tmp121", + .owner = THIS_MODULE, + }, + .probe = tmp121_probe, + .remove = __devexit_p(lm70_remove), }; -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) { - return spi_register_driver(&lm70_driver); + 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; } static void __exit cleanup_lm70(void) { spi_unregister_driver(&lm70_driver); + spi_unregister_driver(&tmp121_driver); } module_init(init_lm70); diff --git a/trunk/drivers/hwmon/max1111.c b/trunk/drivers/hwmon/max1111.c index 9ac497271adf..bfaa665ccf32 100644 --- a/trunk/drivers/hwmon/max1111.c +++ b/trunk/drivers/hwmon/max1111.c @@ -242,4 +242,3 @@ module_exit(max1111_exit); MODULE_AUTHOR("Eric Miao "); MODULE_DESCRIPTION("MAX1111 ADC Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:max1111"); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c index 7550a534005c..7663a2a9f130 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -2463,7 +2463,7 @@ int ehca_create_busmap(void) int ret; ehca_mr_len = 0; - ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL, + ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL, ehca_create_busmap_callback); return ret; } diff --git a/trunk/drivers/input/touchscreen/ad7877.c b/trunk/drivers/input/touchscreen/ad7877.c index eb83939c705e..ecaeb7e8e75e 100644 --- a/trunk/drivers/input/touchscreen/ad7877.c +++ b/trunk/drivers/input/touchscreen/ad7877.c @@ -842,4 +842,3 @@ module_exit(ad7877_exit); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("AD7877 touchscreen Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:ad7877"); diff --git a/trunk/drivers/input/touchscreen/ad7879.c b/trunk/drivers/input/touchscreen/ad7879.c index 19b4db7e974d..5d8a70398807 100644 --- a/trunk/drivers/input/touchscreen/ad7879.c +++ b/trunk/drivers/input/touchscreen/ad7879.c @@ -779,4 +779,3 @@ module_exit(ad7879_exit); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:ad7879"); diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 09c810999b92..ba9d38c3f412 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -1256,4 +1256,3 @@ module_exit(ads7846_exit); MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:ads7846"); diff --git a/trunk/drivers/isdn/capi/kcapi_proc.c b/trunk/drivers/isdn/capi/kcapi_proc.c index 09d4db764d22..50ed778f63fc 100644 --- a/trunk/drivers/isdn/capi/kcapi_proc.c +++ b/trunk/drivers/isdn/capi/kcapi_proc.c @@ -89,14 +89,14 @@ static int contrstats_show(struct seq_file *seq, void *v) return 0; } -static const struct seq_operations seq_controller_ops = { +static struct seq_operations seq_controller_ops = { .start = controller_start, .next = controller_next, .stop = controller_stop, .show = controller_show, }; -static const struct seq_operations seq_contrstats_ops = { +static 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 const struct seq_operations seq_applications_ops = { +static struct seq_operations seq_applications_ops = { .start = applications_start, .next = applications_next, .stop = applications_stop, .show = applications_show, }; -static const struct seq_operations seq_applstats_ops = { +static 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 const struct seq_operations seq_capi_driver_ops = { +static struct seq_operations seq_capi_driver_ops = { .start = capi_driver_start, .next = capi_driver_next, .stop = capi_driver_stop, diff --git a/trunk/drivers/leds/leds-dac124s085.c b/trunk/drivers/leds/leds-dac124s085.c index 2913d76ad3d2..098d9aae7259 100644 --- a/trunk/drivers/leds/leds-dac124s085.c +++ b/trunk/drivers/leds/leds-dac124s085.c @@ -148,4 +148,3 @@ module_exit(dac124s085_leds_exit); MODULE_AUTHOR("Guennadi Liakhovetski "); MODULE_DESCRIPTION("DAC124S085 LED driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:dac124s085"); diff --git a/trunk/drivers/lguest/core.c b/trunk/drivers/lguest/core.c index 8744d24ac6e6..1e2cb846b3c9 100644 --- a/trunk/drivers/lguest/core.c +++ b/trunk/drivers/lguest/core.c @@ -67,11 +67,12 @@ static __init int map_switcher(void) * so we make sure they're zeroed. */ for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) { - switcher_page[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); - if (!switcher_page[i]) { + unsigned long addr = get_zeroed_page(GFP_KERNEL); + if (!addr) { err = -ENOMEM; goto free_some_pages; } + switcher_page[i] = virt_to_page(addr); } /* diff --git a/trunk/drivers/lguest/page_tables.c b/trunk/drivers/lguest/page_tables.c index cf94326f1b59..8aaad65c3bb5 100644 --- a/trunk/drivers/lguest/page_tables.c +++ b/trunk/drivers/lguest/page_tables.c @@ -380,7 +380,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) * And we copy the flags to the shadow PMD entry. The page * number in the shadow PMD is the page we just allocated. */ - set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); + native_set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); } /* @@ -447,7 +447,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) * we will come back here when a write does actually occur, so * we can update the Guest's _PAGE_DIRTY flag. */ - set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); + native_set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); /* * Finally, we write the Guest PTE entry back: we've set the @@ -528,7 +528,7 @@ static void release_pmd(pmd_t *spmd) /* Now we can free the page of PTEs */ free_page((long)ptepage); /* And zero out the PMD entry so we never release it twice. */ - set_pmd(spmd, __pmd(0)); + native_set_pmd(spmd, __pmd(0)); } } @@ -833,15 +833,15 @@ static void do_set_pte(struct lg_cpu *cpu, int idx, */ if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) { check_gpte(cpu, gpte); - set_pte(spte, - gpte_to_spte(cpu, gpte, + native_set_pte(spte, + gpte_to_spte(cpu, gpte, pte_flags(gpte) & _PAGE_DIRTY)); } else { /* * Otherwise kill it and we can demand_page() * it in later. */ - set_pte(spte, __pte(0)); + native_set_pte(spte, __pte(0)); } #ifdef CONFIG_X86_PAE } @@ -983,22 +983,25 @@ static unsigned long setup_pagetables(struct lguest *lg, */ for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD; i += PTRS_PER_PTE, j++) { - pmd = pfn_pmd(((unsigned long)&linear[i] - mem_base)/PAGE_SIZE, - __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER)); + /* FIXME: native_set_pmd is overkill here. */ + native_set_pmd(&pmd, __pmd(((unsigned long)(linear + i) + - mem_base) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER)); if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0) return -EFAULT; } /* One PGD entry, pointing to that PMD page. */ - pgd = __pgd(((unsigned long)pmds - mem_base) | _PAGE_PRESENT); + set_pgd(&pgd, __pgd(((u32)pmds - mem_base) | _PAGE_PRESENT)); /* Copy it in as the first PGD entry (ie. addresses 0-1G). */ if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0) return -EFAULT; /* - * And the other PGD entry to make the linear mapping at PAGE_OFFSET + * And the third PGD entry (ie. addresses 3G-4G). + * + * FIXME: This assumes that PAGE_OFFSET for the Guest is 0xC0000000. */ - if (copy_to_user(&pgdir[KERNEL_PGD_BOUNDARY], &pgd, sizeof(pgd))) + if (copy_to_user(&pgdir[3], &pgd, sizeof(pgd)) != 0) return -EFAULT; #else /* @@ -1138,13 +1141,15 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) { pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); pte_t regs_pte; + unsigned long pfn; #ifdef CONFIG_X86_PAE pmd_t switcher_pmd; pmd_t *pmd_table; - switcher_pmd = pfn_pmd(__pa(switcher_pte_page) >> PAGE_SHIFT, - PAGE_KERNEL_EXEC); + /* FIXME: native_set_pmd is overkill here. */ + native_set_pmd(&switcher_pmd, pfn_pmd(__pa(switcher_pte_page) >> + PAGE_SHIFT, PAGE_KERNEL_EXEC)); /* Figure out where the pmd page is, by reading the PGD, and converting * it to a virtual address. */ @@ -1152,7 +1157,7 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX]) << PAGE_SHIFT); /* Now write it into the shadow page table. */ - set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd); + native_set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd); #else pgd_t switcher_pgd; @@ -1174,8 +1179,10 @@ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) * page is already mapped there, we don't have to copy them out * again. */ - regs_pte = pfn_pte(__pa(cpu->regs_page) >> PAGE_SHIFT, PAGE_KERNEL); - set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], regs_pte); + pfn = __pa(cpu->regs_page) >> PAGE_SHIFT; + native_set_pte(®s_pte, pfn_pte(pfn, PAGE_KERNEL)); + native_set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], + regs_pte); } /*:*/ @@ -1202,7 +1209,7 @@ static __init void populate_switcher_pte_page(unsigned int cpu, /* The first entries are easy: they map the Switcher code. */ for (i = 0; i < pages; i++) { - set_pte(&pte[i], mk_pte(switcher_page[i], + native_set_pte(&pte[i], mk_pte(switcher_page[i], __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); } @@ -1210,14 +1217,14 @@ static __init void populate_switcher_pte_page(unsigned int cpu, i = pages + cpu*2; /* First page (Guest registers) is writable from the Guest */ - set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]), + native_set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]), __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW))); /* * The second page contains the "struct lguest_ro_state", and is * read-only. */ - set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]), + native_set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]), __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED))); } diff --git a/trunk/drivers/mfd/ezx-pcap.c b/trunk/drivers/mfd/ezx-pcap.c index 876288917976..016be4938e4c 100644 --- a/trunk/drivers/mfd/ezx-pcap.c +++ b/trunk/drivers/mfd/ezx-pcap.c @@ -548,4 +548,3 @@ 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"); diff --git a/trunk/drivers/mfd/ucb1400_core.c b/trunk/drivers/mfd/ucb1400_core.c index 2afc08006e6d..78c2135c5de6 100644 --- a/trunk/drivers/mfd/ucb1400_core.c +++ b/trunk/drivers/mfd/ucb1400_core.c @@ -48,11 +48,9 @@ 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) { @@ -70,44 +68,25 @@ 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 err2; + goto err0; } err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts, sizeof(ucb_ts)); if (err) - goto err3; + goto err1; err = platform_device_add(ucb->ucb1400_ts); if (err) - goto err3; + goto err1; return 0; -err3: - platform_device_put(ucb->ucb1400_ts); -err2: - platform_device_unregister(ucb->ucb1400_gpio); err1: - platform_device_put(ucb->ucb1400_gpio); + platform_device_put(ucb->ucb1400_ts); err0: kfree(ucb); err: @@ -119,8 +98,6 @@ 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; } diff --git a/trunk/drivers/misc/eeprom/at25.c b/trunk/drivers/misc/eeprom/at25.c index d902d81dde39..2e535a0ccd5e 100644 --- a/trunk/drivers/misc/eeprom/at25.c +++ b/trunk/drivers/misc/eeprom/at25.c @@ -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"); + diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index 3648b23d5c92..1bfe5d16963b 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -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: diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index 7dab2e5f4bc9..d84c880fac84 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -343,101 +343,6 @@ 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 @@ -461,110 +366,24 @@ 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 || host->claimer == current) + if (stop || !host->claimed) 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; - host->claimer = current; - host->claim_cnt += 1; - } else + 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 @@ -574,11 +393,15 @@ EXPORT_SYMBOL(mmc_host_lazy_disable); */ void mmc_release_host(struct mmc_host *host) { + unsigned long flags; + WARN_ON(!host->claimed); - mmc_host_lazy_disable(host); + spin_lock_irqsave(&host->lock, flags); + host->claimed = 0; + spin_unlock_irqrestore(&host->lock, flags); - mmc_do_release_host(host); + wake_up(&host->wq); } EXPORT_SYMBOL(mmc_release_host); @@ -864,13 +687,7 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) */ static void mmc_power_up(struct mmc_host *host) { - int bit; - - /* If ocr is set, we use it */ - if (host->ocr) - bit = ffs(host->ocr) - 1; - else - bit = fls(host->ocr_avail) - 1; + int bit = fls(host->ocr_avail) - 1; host->ios.vdd = bit; if (mmc_host_is_spi(host)) { @@ -1130,8 +947,6 @@ 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(); @@ -1143,8 +958,6 @@ 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); @@ -1153,80 +966,6 @@ 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 /** @@ -1236,36 +975,27 @@ EXPORT_SYMBOL(mmc_card_can_sleep); */ 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) - 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. - */ + host->bus_ops->suspend(host); + if (!host->bus_ops->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); - if (!err) - mmc_power_off(host); + mmc_power_off(host); - return err; + return 0; } EXPORT_SYMBOL(mmc_suspend_host); @@ -1276,26 +1006,12 @@ 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); - 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; - } + host->bus_ops->resume(host); } mmc_bus_put(host); @@ -1305,7 +1021,7 @@ int mmc_resume_host(struct mmc_host *host) */ mmc_detect_change(host, 1); - return err; + return 0; } EXPORT_SYMBOL(mmc_resume_host); diff --git a/trunk/drivers/mmc/core/core.h b/trunk/drivers/mmc/core/core.h index 67ae6abc4230..c819effa1032 100644 --- a/trunk/drivers/mmc/core/core.h +++ b/trunk/drivers/mmc/core/core.h @@ -16,14 +16,10 @@ #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 *); - int (*suspend)(struct mmc_host *); - int (*resume)(struct mmc_host *); - void (*power_save)(struct mmc_host *); - void (*power_restore)(struct mmc_host *); + void (*suspend)(struct mmc_host *); + void (*resume)(struct mmc_host *); }; void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); diff --git a/trunk/drivers/mmc/core/host.c b/trunk/drivers/mmc/core/host.c index a268d12f1af0..5e945e64ead7 100644 --- a/trunk/drivers/mmc/core/host.c +++ b/trunk/drivers/mmc/core/host.c @@ -83,7 +83,6 @@ 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. diff --git a/trunk/drivers/mmc/core/host.h b/trunk/drivers/mmc/core/host.h index 8c87e1109a34..c2dc3d2d9f9a 100644 --- a/trunk/drivers/mmc/core/host.h +++ b/trunk/drivers/mmc/core/host.h @@ -14,7 +14,5 @@ int mmc_register_host_class(void); void mmc_unregister_host_class(void); -void mmc_host_deeper_disable(struct work_struct *work); - #endif diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index bfefce365ae7..2fb9d5f271ea 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -160,6 +160,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) { int err; u8 *ext_csd; + unsigned int ext_csd_struct; BUG_ON(!card); @@ -179,11 +180,11 @@ static int mmc_read_ext_csd(struct mmc_card *card) err = mmc_send_ext_csd(card, ext_csd); if (err) { - /* If the host or the card can't do the switch, - * fail more gracefully. */ - if ((err != -EINVAL) - && (err != -ENOSYS) - && (err != -EFAULT)) + /* + * We all hosts that cannot perform the command + * to fail more gracefully + */ + if (err != -EINVAL) goto out; /* @@ -206,16 +207,16 @@ static int mmc_read_ext_csd(struct mmc_card *card) goto out; } - card->ext_csd.rev = ext_csd[EXT_CSD_REV]; - if (card->ext_csd.rev > 3) { + ext_csd_struct = ext_csd[EXT_CSD_REV]; + if (ext_csd_struct > 3) { printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), - card->ext_csd.rev); + ext_csd_struct); err = -EINVAL; goto out; } - if (card->ext_csd.rev >= 2) { + if (ext_csd_struct >= 2) { card->ext_csd.sectors = ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | @@ -240,15 +241,6 @@ 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); @@ -416,17 +408,12 @@ 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 && err != -EBADMSG) + if (err) goto free_card; - 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); - } + mmc_card_set_highspeed(card); + + mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* @@ -461,17 +448,10 @@ 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 && err != -EBADMSG) + if (err) goto free_card; - 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); - } + mmc_set_bus_width(card->host, bus_width); } if (!oldcard) @@ -527,10 +507,12 @@ static void mmc_detect(struct mmc_host *host) } } +#ifdef CONFIG_MMC_UNSAFE_RESUME + /* * Suspend callback from host. */ -static int mmc_suspend(struct mmc_host *host) +static void mmc_suspend(struct mmc_host *host) { BUG_ON(!host); BUG_ON(!host->card); @@ -540,8 +522,6 @@ static int mmc_suspend(struct mmc_host *host) mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - - return 0; } /* @@ -550,7 +530,7 @@ static int 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 int mmc_resume(struct mmc_host *host) +static void mmc_resume(struct mmc_host *host) { int err; @@ -561,99 +541,30 @@ static int mmc_resume(struct mmc_host *host) err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); - return err; -} - -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", - mmc_hostname(host), err); - } - - return err; -} + if (err) { + mmc_remove(host); -static int mmc_awake(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, 0); - if (err < 0) - pr_debug("%s: Error %d while awaking sleeping card", - mmc_hostname(host), err); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_release_host(host); } - return err; } -#ifdef CONFIG_MMC_UNSAFE_RESUME - -static const struct mmc_bus_ops mmc_ops = { - .awake = mmc_awake, - .sleep = mmc_sleep, - .remove = mmc_remove, - .detect = mmc_detect, - .suspend = mmc_suspend, - .resume = mmc_resume, - .power_restore = mmc_power_restore, -}; +#else -static void mmc_attach_bus_ops(struct mmc_host *host) -{ - mmc_attach_bus(host, &mmc_ops); -} +#define mmc_suspend NULL +#define mmc_resume NULL -#else +#endif static const struct mmc_bus_ops mmc_ops = { - .awake = mmc_awake, - .sleep = mmc_sleep, - .remove = mmc_remove, - .detect = mmc_detect, - .suspend = NULL, - .resume = NULL, - .power_restore = mmc_power_restore, -}; - -static const struct mmc_bus_ops mmc_ops_unsafe = { - .awake = mmc_awake, - .sleep = mmc_sleep, .remove = mmc_remove, .detect = mmc_detect, .suspend = mmc_suspend, .resume = mmc_resume, - .power_restore = mmc_power_restore, }; -static void mmc_attach_bus_ops(struct mmc_host *host) -{ - const struct mmc_bus_ops *bus_ops; - - if (host->caps & MMC_CAP_NONREMOVABLE) - bus_ops = &mmc_ops_unsafe; - else - bus_ops = &mmc_ops; - mmc_attach_bus(host, bus_ops); -} - -#endif - /* * Starting point for MMC card init. */ @@ -664,7 +575,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) BUG_ON(!host); WARN_ON(!host->claimed); - mmc_attach_bus_ops(host); + mmc_attach_bus(host, &mmc_ops); /* * We need to get OCR a different way for SPI. diff --git a/trunk/drivers/mmc/core/mmc_ops.c b/trunk/drivers/mmc/core/mmc_ops.c index d2cb5c634392..34ce2703d29a 100644 --- a/trunk/drivers/mmc/core/mmc_ops.c +++ b/trunk/drivers/mmc/core/mmc_ops.c @@ -57,42 +57,6 @@ int mmc_deselect_cards(struct mmc_host *host) return _mmc_select_card(host, NULL); } -int mmc_card_sleepawake(struct mmc_host *host, int sleep) -{ - struct mmc_command cmd; - struct mmc_card *card = host->card; - int err; - - if (sleep) - mmc_deselect_cards(host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SLEEP_AWAKE; - cmd.arg = card->rca << 16; - if (sleep) - cmd.arg |= 1 << 15; - - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - err = mmc_wait_for_cmd(host, &cmd, 0); - if (err) - return err; - - /* - * If the host does not wait while the card signals busy, then we will - * will have to wait the sleep/awake timeout. Note, we cannot use the - * SEND_STATUS command to poll the status because that command (and most - * others) is invalid while the card sleeps. - */ - if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) - mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); - - if (!sleep) - err = mmc_select_card(card); - - return err; -} - int mmc_go_idle(struct mmc_host *host) { int err; @@ -390,7 +354,6 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) { int err; struct mmc_command cmd; - u32 status; BUG_ON(!card); BUG_ON(!card->host); @@ -408,28 +371,6 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) if (err) return err; - /* Must check status to be sure of no errors */ - do { - err = mmc_send_status(card, &status); - if (err) - return err; - if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) - break; - if (mmc_host_is_spi(card->host)) - break; - } while (R1_CURRENT_STATE(status) == 7); - - if (mmc_host_is_spi(card->host)) { - if (status & R1_SPI_ILLEGAL_COMMAND) - return -EBADMSG; - } else { - if (status & 0xFDFFA000) - printk(KERN_WARNING "%s: unexpected status %#x after " - "switch", mmc_hostname(card->host), status); - if (status & R1_SWITCH_ERROR) - return -EBADMSG; - } - return 0; } diff --git a/trunk/drivers/mmc/core/mmc_ops.h b/trunk/drivers/mmc/core/mmc_ops.h index 653eb8e84178..17854bf7cf0d 100644 --- a/trunk/drivers/mmc/core/mmc_ops.h +++ b/trunk/drivers/mmc/core/mmc_ops.h @@ -25,7 +25,6 @@ int mmc_send_status(struct mmc_card *card, u32 *status); int mmc_send_cid(struct mmc_host *host, u32 *cid); int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); int mmc_spi_set_crc(struct mmc_host *host, int use_crc); -int mmc_card_sleepawake(struct mmc_host *host, int sleep); #endif diff --git a/trunk/drivers/mmc/core/sd.c b/trunk/drivers/mmc/core/sd.c index 10b2a4d20f5a..7ad646fe077e 100644 --- a/trunk/drivers/mmc/core/sd.c +++ b/trunk/drivers/mmc/core/sd.c @@ -210,11 +210,11 @@ static int mmc_read_switch(struct mmc_card *card) err = mmc_sd_switch(card, 0, 0, 1, status); if (err) { - /* If the host or the card can't do the switch, - * fail more gracefully. */ - if ((err != -EINVAL) - && (err != -ENOSYS) - && (err != -EFAULT)) + /* + * We all hosts that cannot perform the command + * to fail more gracefully + */ + if (err != -EINVAL) goto out; printk(KERN_WARNING "%s: problem reading switch " @@ -561,10 +561,12 @@ static void mmc_sd_detect(struct mmc_host *host) } } +#ifdef CONFIG_MMC_UNSAFE_RESUME + /* * Suspend callback from host. */ -static int mmc_sd_suspend(struct mmc_host *host) +static void mmc_sd_suspend(struct mmc_host *host) { BUG_ON(!host); BUG_ON(!host->card); @@ -574,8 +576,6 @@ static int mmc_sd_suspend(struct mmc_host *host) mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - - return 0; } /* @@ -584,7 +584,7 @@ static int mmc_sd_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 int mmc_sd_resume(struct mmc_host *host) +static void mmc_sd_resume(struct mmc_host *host) { int err; @@ -595,63 +595,30 @@ static int mmc_sd_resume(struct mmc_host *host) err = mmc_sd_init_card(host, host->ocr, host->card); mmc_release_host(host); - return err; -} - -static void mmc_sd_power_restore(struct mmc_host *host) -{ - host->card->state &= ~MMC_STATE_HIGHSPEED; - mmc_claim_host(host); - mmc_sd_init_card(host, host->ocr, host->card); - mmc_release_host(host); -} - -#ifdef CONFIG_MMC_UNSAFE_RESUME + if (err) { + mmc_sd_remove(host); -static const struct mmc_bus_ops mmc_sd_ops = { - .remove = mmc_sd_remove, - .detect = mmc_sd_detect, - .suspend = mmc_sd_suspend, - .resume = mmc_sd_resume, - .power_restore = mmc_sd_power_restore, -}; + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_release_host(host); + } -static void mmc_sd_attach_bus_ops(struct mmc_host *host) -{ - mmc_attach_bus(host, &mmc_sd_ops); } #else -static const struct mmc_bus_ops mmc_sd_ops = { - .remove = mmc_sd_remove, - .detect = mmc_sd_detect, - .suspend = NULL, - .resume = NULL, - .power_restore = mmc_sd_power_restore, -}; +#define mmc_sd_suspend NULL +#define mmc_sd_resume NULL -static const struct mmc_bus_ops mmc_sd_ops_unsafe = { +#endif + +static const struct mmc_bus_ops mmc_sd_ops = { .remove = mmc_sd_remove, .detect = mmc_sd_detect, .suspend = mmc_sd_suspend, .resume = mmc_sd_resume, - .power_restore = mmc_sd_power_restore, }; -static void mmc_sd_attach_bus_ops(struct mmc_host *host) -{ - const struct mmc_bus_ops *bus_ops; - - if (host->caps & MMC_CAP_NONREMOVABLE) - bus_ops = &mmc_sd_ops_unsafe; - else - bus_ops = &mmc_sd_ops; - mmc_attach_bus(host, bus_ops); -} - -#endif - /* * Starting point for SD card init. */ @@ -662,7 +629,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) BUG_ON(!host); WARN_ON(!host->claimed); - mmc_sd_attach_bus_ops(host); + mmc_attach_bus(host, &mmc_sd_ops); /* * We need to get OCR a different way for SPI. diff --git a/trunk/drivers/mmc/core/sdio.c b/trunk/drivers/mmc/core/sdio.c index cdb845b68ab5..fb99ccff9080 100644 --- a/trunk/drivers/mmc/core/sdio.c +++ b/trunk/drivers/mmc/core/sdio.c @@ -164,29 +164,6 @@ static int sdio_enable_wide(struct mmc_card *card) return 0; } -/* - * If desired, disconnect the pull-up resistor on CD/DAT[3] (pin 1) - * of the card. This may be required on certain setups of boards, - * controllers and embedded sdio device which do not need the card's - * pull-up. As a result, card detection is disabled and power is saved. - */ -static int sdio_disable_cd(struct mmc_card *card) -{ - int ret; - u8 ctrl; - - if (!card->cccr.disable_cd) - return 0; - - ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); - if (ret) - return ret; - - ctrl |= SDIO_BUS_CD_DISABLE; - - return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); -} - /* * Test if the card supports high-speed mode and, if so, switch to it. */ @@ -217,135 +194,6 @@ static int sdio_enable_hs(struct mmc_card *card) return 0; } -/* - * Handle the detection and initialisation of a card. - * - * In the case of a resume, "oldcard" will contain the card - * we're trying to reinitialise. - */ -static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, - struct mmc_card *oldcard) -{ - struct mmc_card *card; - int err; - - BUG_ON(!host); - WARN_ON(!host->claimed); - - /* - * Inform the card of the voltage - */ - err = mmc_send_io_op_cond(host, host->ocr, &ocr); - if (err) - goto err; - - /* - * For SPI, enable CRC as appropriate. - */ - if (mmc_host_is_spi(host)) { - err = mmc_spi_set_crc(host, use_spi_crc); - if (err) - goto err; - } - - /* - * Allocate card structure. - */ - card = mmc_alloc_card(host, NULL); - if (IS_ERR(card)) { - err = PTR_ERR(card); - goto err; - } - - card->type = MMC_TYPE_SDIO; - - /* - * For native busses: set card RCA and quit open drain mode. - */ - if (!mmc_host_is_spi(host)) { - err = mmc_send_relative_addr(host, &card->rca); - if (err) - goto remove; - - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); - } - - /* - * Select card, as all following commands rely on that. - */ - if (!mmc_host_is_spi(host)) { - err = mmc_select_card(card); - if (err) - goto remove; - } - - /* - * Read the common registers. - */ - err = sdio_read_cccr(card); - if (err) - goto remove; - - /* - * Read the common CIS tuples. - */ - err = sdio_read_common_cis(card); - if (err) - goto remove; - - if (oldcard) { - int same = (card->cis.vendor == oldcard->cis.vendor && - card->cis.device == oldcard->cis.device); - mmc_remove_card(card); - if (!same) { - err = -ENOENT; - goto err; - } - card = oldcard; - return 0; - } - - /* - * Switch to high-speed (if supported). - */ - err = sdio_enable_hs(card); - if (err) - goto remove; - - /* - * Change to the card's maximum speed. - */ - if (mmc_card_highspeed(card)) { - /* - * The SDIO specification doesn't mention how - * the CIS transfer speed register relates to - * high-speed, but it seems that 50 MHz is - * mandatory. - */ - mmc_set_clock(host, 50000000); - } else { - mmc_set_clock(host, card->cis.max_dtr); - } - - /* - * Switch to wider bus (if supported). - */ - err = sdio_enable_wide(card); - if (err) - goto remove; - - if (!oldcard) - host->card = card; - return 0; - -remove: - if (!oldcard) - mmc_remove_card(card); - -err: - return err; -} - /* * Host is being removed. Free up the current card. */ @@ -395,77 +243,10 @@ static void mmc_sdio_detect(struct mmc_host *host) } } -/* - * SDIO suspend. We need to suspend all functions separately. - * Therefore all registered functions must have drivers with suspend - * and resume methods. Failing that we simply remove the whole card. - */ -static int mmc_sdio_suspend(struct mmc_host *host) -{ - int i, err = 0; - - for (i = 0; i < host->card->sdio_funcs; i++) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - if (!pmops || !pmops->suspend || !pmops->resume) { - /* force removal of entire card in that case */ - err = -ENOSYS; - } else - err = pmops->suspend(&func->dev); - if (err) - break; - } - } - while (err && --i >= 0) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - pmops->resume(&func->dev); - } - } - - return err; -} - -static int mmc_sdio_resume(struct mmc_host *host) -{ - int i, err; - - BUG_ON(!host); - BUG_ON(!host->card); - - /* Basic card reinitialization. */ - mmc_claim_host(host); - err = mmc_sdio_init_card(host, host->ocr, host->card); - mmc_release_host(host); - - /* - * If the card looked to be the same as before suspending, then - * we proceed to resume all card functions. If one of them returns - * an error then we simply return that error to the core and the - * card will be redetected as new. It is the responsibility of - * the function driver to perform further tests with the extra - * knowledge it has of the card to confirm the card is indeed the - * same as before suspending (same MAC address for network cards, - * etc.) and return an error otherwise. - */ - for (i = 0; !err && i < host->card->sdio_funcs; i++) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - err = pmops->resume(&func->dev); - } - } - - return err; -} static const struct mmc_bus_ops mmc_sdio_ops = { .remove = mmc_sdio_remove, .detect = mmc_sdio_detect, - .suspend = mmc_sdio_suspend, - .resume = mmc_sdio_resume, }; @@ -494,6 +275,13 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) ocr &= ~0x7F; } + if (ocr & MMC_VDD_165_195) { + printk(KERN_WARNING "%s: SDIO card claims to support the " + "incompletely defined 'low voltage range'. This " + "will be ignored.\n", mmc_hostname(host)); + ocr &= ~MMC_VDD_165_195; + } + host->ocr = mmc_select_voltage(host, ocr); /* @@ -505,23 +293,101 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) } /* - * Detect and init the card. + * Inform the card of the voltage */ - err = mmc_sdio_init_card(host, host->ocr, NULL); + err = mmc_send_io_op_cond(host, host->ocr, &ocr); if (err) goto err; - card = host->card; + + /* + * For SPI, enable CRC as appropriate. + */ + if (mmc_host_is_spi(host)) { + err = mmc_spi_set_crc(host, use_spi_crc); + if (err) + goto err; + } /* * The number of functions on the card is encoded inside * the ocr. */ - card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; + funcs = (ocr & 0x70000000) >> 28; + + /* + * Allocate card structure. + */ + card = mmc_alloc_card(host, NULL); + if (IS_ERR(card)) { + err = PTR_ERR(card); + goto err; + } + + card->type = MMC_TYPE_SDIO; + card->sdio_funcs = funcs; + + host->card = card; + + /* + * For native busses: set card RCA and quit open drain mode. + */ + if (!mmc_host_is_spi(host)) { + err = mmc_send_relative_addr(host, &card->rca); + if (err) + goto remove; + + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + } + + /* + * Select card, as all following commands rely on that. + */ + if (!mmc_host_is_spi(host)) { + err = mmc_select_card(card); + if (err) + goto remove; + } /* - * If needed, disconnect card detection pull-up resistor. + * Read the common registers. */ - err = sdio_disable_cd(card); + err = sdio_read_cccr(card); + if (err) + goto remove; + + /* + * Read the common CIS tuples. + */ + err = sdio_read_common_cis(card); + if (err) + goto remove; + + /* + * Switch to high-speed (if supported). + */ + err = sdio_enable_hs(card); + if (err) + goto remove; + + /* + * Change to the card's maximum speed. + */ + if (mmc_card_highspeed(card)) { + /* + * The SDIO specification doesn't mention how + * the CIS transfer speed register relates to + * high-speed, but it seems that 50 MHz is + * mandatory. + */ + mmc_set_clock(host, 50000000); + } else { + mmc_set_clock(host, card->cis.max_dtr); + } + + /* + * Switch to wider bus (if supported). + */ + err = sdio_enable_wide(card); if (err) goto remove; diff --git a/trunk/drivers/mmc/core/sdio_bus.c b/trunk/drivers/mmc/core/sdio_bus.c index d37464e296a5..46284b527397 100644 --- a/trunk/drivers/mmc/core/sdio_bus.c +++ b/trunk/drivers/mmc/core/sdio_bus.c @@ -20,6 +20,9 @@ #include "sdio_cis.h" #include "sdio_bus.h" +#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) +#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) + /* show configuration fields */ #define sdio_config_attr(field, format_string) \ static ssize_t \ diff --git a/trunk/drivers/mmc/core/sdio_cis.c b/trunk/drivers/mmc/core/sdio_cis.c index 6636354b48ce..963f2937c5e3 100644 --- a/trunk/drivers/mmc/core/sdio_cis.c +++ b/trunk/drivers/mmc/core/sdio_cis.c @@ -40,7 +40,7 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, nr_strings++; } - if (nr_strings < 4) { + if (buf[i-1] != '\0') { printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n"); return 0; } diff --git a/trunk/drivers/mmc/core/sdio_io.c b/trunk/drivers/mmc/core/sdio_io.c index f9aa8a7deffa..f61fc2d4cd0a 100644 --- a/trunk/drivers/mmc/core/sdio_io.c +++ b/trunk/drivers/mmc/core/sdio_io.c @@ -624,7 +624,7 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, BUG_ON(!func); - if ((addr < 0xF0 || addr > 0xFF) && (!mmc_card_lenient_fn0(func->card))) { + if (addr < 0xF0 || addr > 0xFF) { if (err_ret) *err_ret = -EINVAL; return; diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig index 7cb057f3f883..891ef18bd77b 100644 --- a/trunk/drivers/mmc/host/Kconfig +++ b/trunk/drivers/mmc/host/Kconfig @@ -132,11 +132,11 @@ config MMC_OMAP config MMC_OMAP_HS tristate "TI OMAP High Speed Multimedia Card Interface support" - depends on ARCH_OMAP2430 || ARCH_OMAP3 || ARCH_OMAP4 + depends on ARCH_OMAP2430 || ARCH_OMAP3 help This selects the TI OMAP High Speed Multimedia card Interface. - If you have an OMAP2430 or OMAP3 board or OMAP4 board with a - Multimedia Card slot, say Y or M here. + If you have an OMAP2430 or OMAP3 board with a Multimedia Card slot, + say Y or M here. If unsure, say N. @@ -160,12 +160,6 @@ config MMC_AU1X If unsure, say N. -choice - prompt "Atmel SD/MMC Driver" - default MMC_ATMELMCI if AVR32 - help - Choose which driver to use for the Atmel MCI Silicon - config MMC_AT91 tristate "AT91 SD/MMC Card Interface support" depends on ARCH_AT91 @@ -176,19 +170,17 @@ config MMC_AT91 config MMC_ATMELMCI tristate "Atmel Multimedia Card Interface support" - depends on AVR32 || ARCH_AT91 + depends on AVR32 help This selects the Atmel Multimedia Card Interface driver. If - you have an AT32 (AVR32) or AT91 platform with a Multimedia - Card slot, say Y or M here. + you have an AT32 (AVR32) platform with a Multimedia Card + slot, say Y or M here. If unsure, say N. -endchoice - config MMC_ATMELMCI_DMA bool "Atmel MCI DMA support (EXPERIMENTAL)" - depends on MMC_ATMELMCI && AVR32 && DMA_ENGINE && EXPERIMENTAL + depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL help Say Y here to have the Atmel MCI driver use a DMA engine to do data transfers and thus increase the throughput and @@ -207,13 +199,6 @@ config MMC_IMX If unsure, say N. -config MMC_MSM7X00A - tristate "Qualcomm MSM 7X00A SDCC Controller Support" - depends on MMC && ARCH_MSM - help - This provides support for the SD/MMC cell found in the - MSM 7X00A controllers from Qualcomm. - config MMC_MXC tristate "Freescale i.MX2/3 Multimedia Card Interface support" depends on ARCH_MXC diff --git a/trunk/drivers/mmc/host/Makefile b/trunk/drivers/mmc/host/Makefile index abcb0400e06d..cf153f628457 100644 --- a/trunk/drivers/mmc/host/Makefile +++ b/trunk/drivers/mmc/host/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o -obj-$(CONFIG_MMC_MSM7X00A) += msm_sdcc.o obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o ifeq ($(CONFIG_OF),y) diff --git a/trunk/drivers/mmc/host/atmel-mci.c b/trunk/drivers/mmc/host/atmel-mci.c index 065fa818be57..7b603e4b41db 100644 --- a/trunk/drivers/mmc/host/atmel-mci.c +++ b/trunk/drivers/mmc/host/atmel-mci.c @@ -30,7 +30,6 @@ #include #include -#include #include #include "atmel-mci-regs.h" @@ -210,18 +209,6 @@ struct atmel_mci_slot { #define atmci_set_pending(host, event) \ set_bit(event, &host->pending_events) -/* - * Enable or disable features/registers based on - * whether the processor supports them - */ -static bool mci_has_rwproof(void) -{ - if (cpu_is_at91sam9261() || cpu_is_at91rm9200()) - return false; - else - return true; -} - /* * The debugfs stuff below is mostly optimized away when * CONFIG_DEBUG_FS is not set. @@ -289,13 +276,8 @@ static void atmci_show_status_reg(struct seq_file *s, [3] = "BLKE", [4] = "DTIP", [5] = "NOTBUSY", - [6] = "ENDRX", - [7] = "ENDTX", [8] = "SDIOIRQA", [9] = "SDIOIRQB", - [12] = "SDIOWAIT", - [14] = "RXBUFF", - [15] = "TXBUFE", [16] = "RINDE", [17] = "RDIRE", [18] = "RCRCE", @@ -303,11 +285,6 @@ static void atmci_show_status_reg(struct seq_file *s, [20] = "RTOE", [21] = "DCRCE", [22] = "DTOE", - [23] = "CSTOE", - [24] = "BLKOVRE", - [25] = "DMADONE", - [26] = "FIFOEMPTY", - [27] = "XFRDONE", [30] = "OVRE", [31] = "UNRE", }; @@ -872,15 +849,13 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) clkdiv = 255; } - host->mode_reg = MCI_MR_CLKDIV(clkdiv); - /* * WRPROOF and RDPROOF prevent overruns/underruns by * stopping the clock when the FIFO is full/empty. * This state is not expected to last for long. */ - if (mci_has_rwproof()) - host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF); + host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF + | MCI_MR_RDPROOF; if (list_empty(&host->queue)) mci_writel(host, MR, host->mode_reg); @@ -1673,10 +1648,8 @@ static int __init atmci_probe(struct platform_device *pdev) nr_slots++; } - if (!nr_slots) { - dev_err(&pdev->dev, "init failed: no slot defined\n"); + if (!nr_slots) goto err_init_slot; - } dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", diff --git a/trunk/drivers/mmc/host/mmc_spi.c b/trunk/drivers/mmc/host/mmc_spi.c index d55fe4fb7935..a461017ce5ce 100644 --- a/trunk/drivers/mmc/host/mmc_spi.c +++ b/trunk/drivers/mmc/host/mmc_spi.c @@ -1562,4 +1562,3 @@ MODULE_AUTHOR("Mike Lavender, David Brownell, " "Hans-Peter Nilsson, Jan Nikitenko"); MODULE_DESCRIPTION("SPI SD/MMC host driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:mmc_spi"); diff --git a/trunk/drivers/mmc/host/msm_sdcc.c b/trunk/drivers/mmc/host/msm_sdcc.c deleted file mode 100644 index dba4600bcdb4..000000000000 --- a/trunk/drivers/mmc/host/msm_sdcc.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* - * linux/drivers/mmc/host/msm_sdcc.c - Qualcomm MSM 7X00A SDCC Driver - * - * Copyright (C) 2007 Google Inc, - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * 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. - * - * Based on mmci.c - * - * Author: San Mehat (san@android.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "msm_sdcc.h" - -#define DRIVER_NAME "msm-sdcc" - -static unsigned int msmsdcc_fmin = 144000; -static unsigned int msmsdcc_fmax = 50000000; -static unsigned int msmsdcc_4bit = 1; -static unsigned int msmsdcc_pwrsave = 1; -static unsigned int msmsdcc_piopoll = 1; -static unsigned int msmsdcc_sdioirq; - -#define PIO_SPINMAX 30 -#define CMD_SPINMAX 20 - -static void -msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, - u32 c); - -static void -msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) -{ - writel(0, host->base + MMCICOMMAND); - - BUG_ON(host->curr.data); - - host->curr.mrq = NULL; - host->curr.cmd = NULL; - - if (mrq->data) - mrq->data->bytes_xfered = host->curr.data_xfered; - if (mrq->cmd->error == -ETIMEDOUT) - mdelay(5); - - /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); - mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); -} - -static void -msmsdcc_stop_data(struct msmsdcc_host *host) -{ - writel(0, host->base + MMCIDATACTRL); - host->curr.data = NULL; - host->curr.got_dataend = host->curr.got_datablkend = 0; -} - -uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) -{ - switch (host->pdev_id) { - case 1: - return MSM_SDC1_PHYS + MMCIFIFO; - case 2: - return MSM_SDC2_PHYS + MMCIFIFO; - case 3: - return MSM_SDC3_PHYS + MMCIFIFO; - case 4: - return MSM_SDC4_PHYS + MMCIFIFO; - } - BUG(); - return 0; -} - -static void -msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, - unsigned int result, - struct msm_dmov_errdata *err) -{ - struct msmsdcc_dma_data *dma_data = - container_of(cmd, struct msmsdcc_dma_data, hdr); - struct msmsdcc_host *host = dma_data->host; - unsigned long flags; - struct mmc_request *mrq; - - spin_lock_irqsave(&host->lock, flags); - mrq = host->curr.mrq; - BUG_ON(!mrq); - - if (!(result & DMOV_RSLT_VALID)) { - pr_err("msmsdcc: Invalid DataMover result\n"); - goto out; - } - - if (result & DMOV_RSLT_DONE) { - host->curr.data_xfered = host->curr.xfer_size; - } else { - /* Error or flush */ - if (result & DMOV_RSLT_ERROR) - pr_err("%s: DMA error (0x%.8x)\n", - mmc_hostname(host->mmc), result); - if (result & DMOV_RSLT_FLUSH) - pr_err("%s: DMA channel flushed (0x%.8x)\n", - mmc_hostname(host->mmc), result); - if (err) - pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", - err->flush[0], err->flush[1], err->flush[2], - err->flush[3], err->flush[4], err->flush[5]); - if (!mrq->data->error) - mrq->data->error = -EIO; - } - host->dma.busy = 0; - dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, - host->dma.dir); - - if (host->curr.user_pages) { - struct scatterlist *sg = host->dma.sg; - int i; - - for (i = 0; i < host->dma.num_ents; i++) - flush_dcache_page(sg_page(sg++)); - } - - host->dma.sg = NULL; - - if ((host->curr.got_dataend && host->curr.got_datablkend) - || mrq->data->error) { - - /* - * If we've already gotten our DATAEND / DATABLKEND - * for this request, then complete it through here. - */ - msmsdcc_stop_data(host); - - if (!mrq->data->error) - host->curr.data_xfered = host->curr.xfer_size; - if (!mrq->data->stop || mrq->cmd->error) { - writel(0, host->base + MMCICOMMAND); - host->curr.mrq = NULL; - host->curr.cmd = NULL; - mrq->data->bytes_xfered = host->curr.data_xfered; - - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(host->mmc, mrq); - return; - } else - msmsdcc_start_command(host, mrq->data->stop, 0); - } - -out: - spin_unlock_irqrestore(&host->lock, flags); - return; -} - -static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) -{ - if (host->dma.channel == -1) - return -ENOENT; - - if ((data->blksz * data->blocks) < MCI_FIFOSIZE) - return -EINVAL; - if ((data->blksz * data->blocks) % MCI_FIFOSIZE) - return -EINVAL; - return 0; -} - -static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) -{ - struct msmsdcc_nc_dmadata *nc; - dmov_box *box; - uint32_t rows; - uint32_t crci; - unsigned int n; - int i, rc; - struct scatterlist *sg = data->sg; - - rc = validate_dma(host, data); - if (rc) - return rc; - - host->dma.sg = data->sg; - host->dma.num_ents = data->sg_len; - - nc = host->dma.nc; - - switch (host->pdev_id) { - case 1: - crci = MSMSDCC_CRCI_SDC1; - break; - case 2: - crci = MSMSDCC_CRCI_SDC2; - break; - case 3: - crci = MSMSDCC_CRCI_SDC3; - break; - case 4: - crci = MSMSDCC_CRCI_SDC4; - break; - default: - host->dma.sg = NULL; - host->dma.num_ents = 0; - return -ENOENT; - } - - if (data->flags & MMC_DATA_READ) - host->dma.dir = DMA_FROM_DEVICE; - else - host->dma.dir = DMA_TO_DEVICE; - - host->curr.user_pages = 0; - - n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg, - host->dma.num_ents, host->dma.dir); - - if (n != host->dma.num_ents) { - pr_err("%s: Unable to map in all sg elements\n", - mmc_hostname(host->mmc)); - host->dma.sg = NULL; - host->dma.num_ents = 0; - return -ENOMEM; - } - - box = &nc->cmd[0]; - for (i = 0; i < host->dma.num_ents; i++) { - box->cmd = CMD_MODE_BOX; - - if (i == (host->dma.num_ents - 1)) - box->cmd |= CMD_LC; - rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? - (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 : - (sg_dma_len(sg) / MCI_FIFOSIZE) ; - - if (data->flags & MMC_DATA_READ) { - box->src_row_addr = msmsdcc_fifo_addr(host); - box->dst_row_addr = sg_dma_address(sg); - - box->src_dst_len = (MCI_FIFOSIZE << 16) | - (MCI_FIFOSIZE); - box->row_offset = MCI_FIFOSIZE; - - box->num_rows = rows * ((1 << 16) + 1); - box->cmd |= CMD_SRC_CRCI(crci); - } else { - box->src_row_addr = sg_dma_address(sg); - box->dst_row_addr = msmsdcc_fifo_addr(host); - - box->src_dst_len = (MCI_FIFOSIZE << 16) | - (MCI_FIFOSIZE); - box->row_offset = (MCI_FIFOSIZE << 16); - - box->num_rows = rows * ((1 << 16) + 1); - box->cmd |= CMD_DST_CRCI(crci); - } - box++; - sg++; - } - - /* location of command block must be 64 bit aligned */ - BUG_ON(host->dma.cmd_busaddr & 0x07); - - nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP; - host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | - DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); - host->dma.hdr.complete_func = msmsdcc_dma_complete_func; - - return 0; -} - -static void -msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) -{ - unsigned int datactrl, timeout; - unsigned long long clks; - void __iomem *base = host->base; - unsigned int pio_irqmask = 0; - - host->curr.data = data; - host->curr.xfer_size = data->blksz * data->blocks; - host->curr.xfer_remain = host->curr.xfer_size; - host->curr.data_xfered = 0; - host->curr.got_dataend = 0; - host->curr.got_datablkend = 0; - - memset(&host->pio, 0, sizeof(host->pio)); - - clks = (unsigned long long)data->timeout_ns * host->clk_rate; - do_div(clks, NSEC_PER_SEC); - timeout = data->timeout_clks + (unsigned int)clks; - writel(timeout, base + MMCIDATATIMER); - - writel(host->curr.xfer_size, base + MMCIDATALENGTH); - - datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); - - if (!msmsdcc_config_dma(host, data)) - datactrl |= MCI_DPSM_DMAENABLE; - else { - host->pio.sg = data->sg; - host->pio.sg_len = data->sg_len; - host->pio.sg_off = 0; - - if (data->flags & MMC_DATA_READ) { - pio_irqmask = MCI_RXFIFOHALFFULLMASK; - if (host->curr.xfer_remain < MCI_FIFOSIZE) - pio_irqmask |= MCI_RXDATAAVLBLMASK; - } else - pio_irqmask = MCI_TXFIFOHALFEMPTYMASK; - } - - if (data->flags & MMC_DATA_READ) - datactrl |= MCI_DPSM_DIRECTION; - - writel(pio_irqmask, base + MMCIMASK1); - writel(datactrl, base + MMCIDATACTRL); - - if (datactrl & MCI_DPSM_DMAENABLE) { - host->dma.busy = 1; - msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); - } -} - -static void -msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) -{ - void __iomem *base = host->base; - - if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { - writel(0, base + MMCICOMMAND); - udelay(2 + ((5 * 1000000) / host->clk_rate)); - } - - c |= cmd->opcode | MCI_CPSM_ENABLE; - - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) - c |= MCI_CPSM_LONGRSP; - c |= MCI_CPSM_RESPONSE; - } - - if (cmd->opcode == 17 || cmd->opcode == 18 || - cmd->opcode == 24 || cmd->opcode == 25 || - cmd->opcode == 53) - c |= MCI_CSPM_DATCMD; - - if (cmd == cmd->mrq->stop) - c |= MCI_CSPM_MCIABORT; - - host->curr.cmd = cmd; - - host->stats.cmds++; - - writel(cmd->arg, base + MMCIARGUMENT); - writel(c, base + MMCICOMMAND); -} - -static void -msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data, - unsigned int status) -{ - if (status & MCI_DATACRCFAIL) { - pr_err("%s: Data CRC error\n", mmc_hostname(host->mmc)); - pr_err("%s: opcode 0x%.8x\n", __func__, - data->mrq->cmd->opcode); - pr_err("%s: blksz %d, blocks %d\n", __func__, - data->blksz, data->blocks); - data->error = -EILSEQ; - } else if (status & MCI_DATATIMEOUT) { - pr_err("%s: Data timeout\n", mmc_hostname(host->mmc)); - data->error = -ETIMEDOUT; - } else if (status & MCI_RXOVERRUN) { - pr_err("%s: RX overrun\n", mmc_hostname(host->mmc)); - data->error = -EIO; - } else if (status & MCI_TXUNDERRUN) { - pr_err("%s: TX underrun\n", mmc_hostname(host->mmc)); - data->error = -EIO; - } else { - pr_err("%s: Unknown error (0x%.8x)\n", - mmc_hostname(host->mmc), status); - data->error = -EIO; - } -} - - -static int -msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain) -{ - void __iomem *base = host->base; - uint32_t *ptr = (uint32_t *) buffer; - int count = 0; - - while (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL) { - - *ptr = readl(base + MMCIFIFO + (count % MCI_FIFOSIZE)); - ptr++; - count += sizeof(uint32_t); - - remain -= sizeof(uint32_t); - if (remain == 0) - break; - } - return count; -} - -static int -msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer, - unsigned int remain, u32 status) -{ - void __iomem *base = host->base; - char *ptr = buffer; - - do { - unsigned int count, maxcnt; - - maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : - MCI_FIFOHALFSIZE; - count = min(remain, maxcnt); - - writesl(base + MMCIFIFO, ptr, count >> 2); - ptr += count; - remain -= count; - - if (remain == 0) - break; - - status = readl(base + MMCISTATUS); - } while (status & MCI_TXFIFOHALFEMPTY); - - return ptr - buffer; -} - -static int -msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin) -{ - while (maxspin) { - if ((readl(host->base + MMCISTATUS) & mask)) - return 0; - udelay(1); - --maxspin; - } - return -ETIMEDOUT; -} - -static int -msmsdcc_pio_irq(int irq, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; - void __iomem *base = host->base; - uint32_t status; - - status = readl(base + MMCISTATUS); - - do { - unsigned long flags; - unsigned int remain, len; - char *buffer; - - if (!(status & (MCI_TXFIFOHALFEMPTY | MCI_RXDATAAVLBL))) { - if (host->curr.xfer_remain == 0 || !msmsdcc_piopoll) - break; - - if (msmsdcc_spin_on_status(host, - (MCI_TXFIFOHALFEMPTY | - MCI_RXDATAAVLBL), - PIO_SPINMAX)) { - break; - } - } - - /* Map the current scatter buffer */ - local_irq_save(flags); - buffer = kmap_atomic(sg_page(host->pio.sg), - KM_BIO_SRC_IRQ) + host->pio.sg->offset; - buffer += host->pio.sg_off; - remain = host->pio.sg->length - host->pio.sg_off; - len = 0; - if (status & MCI_RXACTIVE) - len = msmsdcc_pio_read(host, buffer, remain); - if (status & MCI_TXACTIVE) - len = msmsdcc_pio_write(host, buffer, remain, status); - - /* Unmap the buffer */ - kunmap_atomic(buffer, KM_BIO_SRC_IRQ); - local_irq_restore(flags); - - host->pio.sg_off += len; - host->curr.xfer_remain -= len; - host->curr.data_xfered += len; - remain -= len; - - if (remain == 0) { - /* This sg page is full - do some housekeeping */ - if (status & MCI_RXACTIVE && host->curr.user_pages) - flush_dcache_page(sg_page(host->pio.sg)); - - if (!--host->pio.sg_len) { - memset(&host->pio, 0, sizeof(host->pio)); - break; - } - - /* Advance to next sg */ - host->pio.sg++; - host->pio.sg_off = 0; - } - - status = readl(base + MMCISTATUS); - } while (1); - - if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) - writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); - - if (!host->curr.xfer_remain) - writel(0, base + MMCIMASK1); - - return IRQ_HANDLED; -} - -static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) -{ - struct mmc_command *cmd = host->curr.cmd; - void __iomem *base = host->base; - - host->curr.cmd = NULL; - cmd->resp[0] = readl(base + MMCIRESPONSE0); - cmd->resp[1] = readl(base + MMCIRESPONSE1); - cmd->resp[2] = readl(base + MMCIRESPONSE2); - cmd->resp[3] = readl(base + MMCIRESPONSE3); - - del_timer(&host->command_timer); - if (status & MCI_CMDTIMEOUT) { - cmd->error = -ETIMEDOUT; - } else if (status & MCI_CMDCRCFAIL && - cmd->flags & MMC_RSP_CRC) { - pr_err("%s: Command CRC error\n", mmc_hostname(host->mmc)); - cmd->error = -EILSEQ; - } - - if (!cmd->data || cmd->error) { - if (host->curr.data && host->dma.sg) - msm_dmov_stop_cmd(host->dma.channel, - &host->dma.hdr, 0); - else if (host->curr.data) { /* Non DMA */ - msmsdcc_stop_data(host); - msmsdcc_request_end(host, cmd->mrq); - } else /* host->data == NULL */ - msmsdcc_request_end(host, cmd->mrq); - } else if (!(cmd->data->flags & MMC_DATA_READ)) - msmsdcc_start_data(host, cmd->data); -} - -static void -msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, - void __iomem *base) -{ - struct mmc_data *data = host->curr.data; - - if (!data) - return; - - /* Check for data errors */ - if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | - MCI_TXUNDERRUN | MCI_RXOVERRUN)) { - msmsdcc_data_err(host, data, status); - host->curr.data_xfered = 0; - if (host->dma.sg) - msm_dmov_stop_cmd(host->dma.channel, - &host->dma.hdr, 0); - else { - msmsdcc_stop_data(host); - if (!data->stop) - msmsdcc_request_end(host, data->mrq); - else - msmsdcc_start_command(host, data->stop, 0); - } - } - - /* Check for data done */ - if (!host->curr.got_dataend && (status & MCI_DATAEND)) - host->curr.got_dataend = 1; - - if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND)) - host->curr.got_datablkend = 1; - - /* - * If DMA is still in progress, we complete via the completion handler - */ - if (host->curr.got_dataend && host->curr.got_datablkend && - !host->dma.busy) { - /* - * There appears to be an issue in the controller where - * if you request a small block transfer (< fifo size), - * you may get your DATAEND/DATABLKEND irq without the - * PIO data irq. - * - * Check to see if there is still data to be read, - * and simulate a PIO irq. - */ - if (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL) - msmsdcc_pio_irq(1, host); - - msmsdcc_stop_data(host); - if (!data->error) - host->curr.data_xfered = host->curr.xfer_size; - - if (!data->stop) - msmsdcc_request_end(host, data->mrq); - else - msmsdcc_start_command(host, data->stop, 0); - } -} - -static irqreturn_t -msmsdcc_irq(int irq, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; - void __iomem *base = host->base; - u32 status; - int ret = 0; - int cardint = 0; - - spin_lock(&host->lock); - - do { - status = readl(base + MMCISTATUS); - - status &= (readl(base + MMCIMASK0) | MCI_DATABLOCKENDMASK); - writel(status, base + MMCICLEAR); - - msmsdcc_handle_irq_data(host, status, base); - - if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | - MCI_CMDTIMEOUT) && host->curr.cmd) { - msmsdcc_do_cmdirq(host, status); - } - - if (status & MCI_SDIOINTOPER) { - cardint = 1; - status &= ~MCI_SDIOINTOPER; - } - ret = 1; - } while (status); - - spin_unlock(&host->lock); - - /* - * We have to delay handling the card interrupt as it calls - * back into the driver. - */ - if (cardint) - mmc_signal_sdio_irq(host->mmc); - - return IRQ_RETVAL(ret); -} - -static void -msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct msmsdcc_host *host = mmc_priv(mmc); - unsigned long flags; - - WARN_ON(host->curr.mrq != NULL); - WARN_ON(host->pwr == 0); - - spin_lock_irqsave(&host->lock, flags); - - host->stats.reqs++; - - if (host->eject) { - if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) { - mrq->cmd->error = 0; - mrq->data->bytes_xfered = mrq->data->blksz * - mrq->data->blocks; - } else - mrq->cmd->error = -ENOMEDIUM; - - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(mmc, mrq); - return; - } - - host->curr.mrq = mrq; - - if (mrq->data && mrq->data->flags & MMC_DATA_READ) - msmsdcc_start_data(host, mrq->data); - - msmsdcc_start_command(host, mrq->cmd, 0); - - if (host->cmdpoll && !msmsdcc_spin_on_status(host, - MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, - CMD_SPINMAX)) { - uint32_t status = readl(host->base + MMCISTATUS); - msmsdcc_do_cmdirq(host, status); - writel(MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT, - host->base + MMCICLEAR); - host->stats.cmdpoll_hits++; - } else { - host->stats.cmdpoll_misses++; - mod_timer(&host->command_timer, jiffies + HZ); - } - spin_unlock_irqrestore(&host->lock, flags); -} - -static void -msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct msmsdcc_host *host = mmc_priv(mmc); - u32 clk = 0, pwr = 0; - int rc; - - if (ios->clock) { - - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; - } - if (ios->clock != host->clk_rate) { - rc = clk_set_rate(host->clk, ios->clock); - if (rc < 0) - pr_err("%s: Error setting clock rate (%d)\n", - mmc_hostname(host->mmc), rc); - else - host->clk_rate = ios->clock; - } - clk |= MCI_CLK_ENABLE; - } - - if (ios->bus_width == MMC_BUS_WIDTH_4) - clk |= (2 << 10); /* Set WIDEBUS */ - - if (ios->clock > 400000 && msmsdcc_pwrsave) - clk |= (1 << 9); /* PWRSAVE */ - - clk |= (1 << 12); /* FLOW_ENA */ - clk |= (1 << 15); /* feedback clock */ - - if (host->plat->translate_vdd) - pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd); - - switch (ios->power_mode) { - case MMC_POWER_OFF: - htc_pwrsink_set(PWRSINK_SDCARD, 0); - break; - case MMC_POWER_UP: - pwr |= MCI_PWR_UP; - break; - case MMC_POWER_ON: - htc_pwrsink_set(PWRSINK_SDCARD, 100); - pwr |= MCI_PWR_ON; - break; - } - - if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) - pwr |= MCI_OD; - - writel(clk, host->base + MMCICLOCK); - - if (host->pwr != pwr) { - host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); - } - - if (!(clk & MCI_CLK_ENABLE) && host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } -} - -static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) -{ - struct msmsdcc_host *host = mmc_priv(mmc); - unsigned long flags; - u32 status; - - spin_lock_irqsave(&host->lock, flags); - if (msmsdcc_sdioirq == 1) { - status = readl(host->base + MMCIMASK0); - if (enable) - status |= MCI_SDIOINTOPERMASK; - else - status &= ~MCI_SDIOINTOPERMASK; - host->saved_irq0mask = status; - writel(status, host->base + MMCIMASK0); - } - spin_unlock_irqrestore(&host->lock, flags); -} - -static const struct mmc_host_ops msmsdcc_ops = { - .request = msmsdcc_request, - .set_ios = msmsdcc_set_ios, - .enable_sdio_irq = msmsdcc_enable_sdio_irq, -}; - -static void -msmsdcc_check_status(unsigned long data) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *)data; - unsigned int status; - - if (!host->plat->status) { - mmc_detect_change(host->mmc, 0); - goto out; - } - - status = host->plat->status(mmc_dev(host->mmc)); - host->eject = !status; - if (status ^ host->oldstat) { - pr_info("%s: Slot status change detected (%d -> %d)\n", - mmc_hostname(host->mmc), host->oldstat, status); - if (status) - mmc_detect_change(host->mmc, (5 * HZ) / 2); - else - mmc_detect_change(host->mmc, 0); - } - - host->oldstat = status; - -out: - if (host->timer.function) - mod_timer(&host->timer, jiffies + HZ); -} - -static irqreturn_t -msmsdcc_platform_status_irq(int irq, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; - - printk(KERN_DEBUG "%s: %d\n", __func__, irq); - msmsdcc_check_status((unsigned long) host); - return IRQ_HANDLED; -} - -static void -msmsdcc_status_notify_cb(int card_present, void *dev_id) -{ - struct msmsdcc_host *host = dev_id; - - printk(KERN_DEBUG "%s: card_present %d\n", mmc_hostname(host->mmc), - card_present); - msmsdcc_check_status((unsigned long) host); -} - -/* - * called when a command expires. - * Dump some debugging, and then error - * out the transaction. - */ -static void -msmsdcc_command_expired(unsigned long _data) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *) _data; - struct mmc_request *mrq; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - mrq = host->curr.mrq; - - if (!mrq) { - pr_info("%s: Command expiry misfire\n", - mmc_hostname(host->mmc)); - spin_unlock_irqrestore(&host->lock, flags); - return; - } - - pr_err("%s: Command timeout (%p %p %p %p)\n", - mmc_hostname(host->mmc), mrq, mrq->cmd, - mrq->data, host->dma.sg); - - mrq->cmd->error = -ETIMEDOUT; - msmsdcc_stop_data(host); - - writel(0, host->base + MMCICOMMAND); - - host->curr.mrq = NULL; - host->curr.cmd = NULL; - - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(host->mmc, mrq); -} - -static int -msmsdcc_init_dma(struct msmsdcc_host *host) -{ - memset(&host->dma, 0, sizeof(struct msmsdcc_dma_data)); - host->dma.host = host; - host->dma.channel = -1; - - if (!host->dmares) - return -ENODEV; - - host->dma.nc = dma_alloc_coherent(NULL, - sizeof(struct msmsdcc_nc_dmadata), - &host->dma.nc_busaddr, - GFP_KERNEL); - if (host->dma.nc == NULL) { - pr_err("Unable to allocate DMA buffer\n"); - return -ENOMEM; - } - memset(host->dma.nc, 0x00, sizeof(struct msmsdcc_nc_dmadata)); - host->dma.cmd_busaddr = host->dma.nc_busaddr; - host->dma.cmdptr_busaddr = host->dma.nc_busaddr + - offsetof(struct msmsdcc_nc_dmadata, cmdptr); - host->dma.channel = host->dmares->start; - - return 0; -} - -#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ -static void -do_resume_work(struct work_struct *work) -{ - struct msmsdcc_host *host = - container_of(work, struct msmsdcc_host, resume_task); - struct mmc_host *mmc = host->mmc; - - if (mmc) { - mmc_resume_host(mmc); - if (host->stat_irq) - enable_irq(host->stat_irq); - } -} -#endif - -static int -msmsdcc_probe(struct platform_device *pdev) -{ - struct mmc_platform_data *plat = pdev->dev.platform_data; - struct msmsdcc_host *host; - struct mmc_host *mmc; - struct resource *cmd_irqres = NULL; - struct resource *pio_irqres = NULL; - struct resource *stat_irqres = NULL; - struct resource *memres = NULL; - struct resource *dmares = NULL; - int ret; - - /* must have platform data */ - if (!plat) { - pr_err("%s: Platform data not available\n", __func__); - ret = -EINVAL; - goto out; - } - - if (pdev->id < 1 || pdev->id > 4) - return -EINVAL; - - if (pdev->resource == NULL || pdev->num_resources < 2) { - pr_err("%s: Invalid resource\n", __func__); - return -ENXIO; - } - - memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); - cmd_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "cmd_irq"); - pio_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "pio_irq"); - stat_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "status_irq"); - - if (!cmd_irqres || !pio_irqres || !memres) { - pr_err("%s: Invalid resource\n", __func__); - return -ENXIO; - } - - /* - * Setup our host structure - */ - - mmc = mmc_alloc_host(sizeof(struct msmsdcc_host), &pdev->dev); - if (!mmc) { - ret = -ENOMEM; - goto out; - } - - host = mmc_priv(mmc); - host->pdev_id = pdev->id; - host->plat = plat; - host->mmc = mmc; - - host->cmdpoll = 1; - - host->base = ioremap(memres->start, PAGE_SIZE); - if (!host->base) { - ret = -ENOMEM; - goto out; - } - - host->cmd_irqres = cmd_irqres; - host->pio_irqres = pio_irqres; - host->memres = memres; - host->dmares = dmares; - spin_lock_init(&host->lock); - - /* - * Setup DMA - */ - msmsdcc_init_dma(host); - - /* - * Setup main peripheral bus clock - */ - host->pclk = clk_get(&pdev->dev, "sdc_pclk"); - if (IS_ERR(host->pclk)) { - ret = PTR_ERR(host->pclk); - goto host_free; - } - - ret = clk_enable(host->pclk); - if (ret) - goto pclk_put; - - host->pclk_rate = clk_get_rate(host->pclk); - - /* - * Setup SDC MMC clock - */ - host->clk = clk_get(&pdev->dev, "sdc_clk"); - if (IS_ERR(host->clk)) { - ret = PTR_ERR(host->clk); - goto pclk_disable; - } - - ret = clk_enable(host->clk); - if (ret) - goto clk_put; - - ret = clk_set_rate(host->clk, msmsdcc_fmin); - if (ret) { - pr_err("%s: Clock rate set failed (%d)\n", __func__, ret); - goto clk_disable; - } - - host->clk_rate = clk_get_rate(host->clk); - - host->clks_on = 1; - - /* - * Setup MMC host structure - */ - mmc->ops = &msmsdcc_ops; - mmc->f_min = msmsdcc_fmin; - mmc->f_max = msmsdcc_fmax; - mmc->ocr_avail = plat->ocr_mask; - - if (msmsdcc_4bit) - mmc->caps |= MMC_CAP_4_BIT_DATA; - if (msmsdcc_sdioirq) - mmc->caps |= MMC_CAP_SDIO_IRQ; - mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; - - mmc->max_phys_segs = NR_SG; - mmc->max_hw_segs = NR_SG; - mmc->max_blk_size = 4096; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */ - mmc->max_blk_count = 65536; - - mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */ - mmc->max_seg_size = mmc->max_req_size; - - writel(0, host->base + MMCIMASK0); - writel(0x5e007ff, host->base + MMCICLEAR); /* Add: 1 << 25 */ - - writel(MCI_IRQENABLE, host->base + MMCIMASK0); - host->saved_irq0mask = MCI_IRQENABLE; - - /* - * Setup card detect change - */ - - memset(&host->timer, 0, sizeof(host->timer)); - - if (stat_irqres && !(stat_irqres->flags & IORESOURCE_DISABLED)) { - unsigned long irqflags = IRQF_SHARED | - (stat_irqres->flags & IRQF_TRIGGER_MASK); - - host->stat_irq = stat_irqres->start; - ret = request_irq(host->stat_irq, - msmsdcc_platform_status_irq, - irqflags, - DRIVER_NAME " (slot)", - host); - if (ret) { - pr_err("%s: Unable to get slot IRQ %d (%d)\n", - mmc_hostname(mmc), host->stat_irq, ret); - goto clk_disable; - } - } else if (plat->register_status_notify) { - plat->register_status_notify(msmsdcc_status_notify_cb, host); - } else if (!plat->status) - pr_err("%s: No card detect facilities available\n", - mmc_hostname(mmc)); - else { - init_timer(&host->timer); - host->timer.data = (unsigned long)host; - host->timer.function = msmsdcc_check_status; - host->timer.expires = jiffies + HZ; - add_timer(&host->timer); - } - - if (plat->status) { - host->oldstat = host->plat->status(mmc_dev(host->mmc)); - host->eject = !host->oldstat; - } - - /* - * Setup a command timer. We currently need this due to - * some 'strange' timeout / error handling situations. - */ - init_timer(&host->command_timer); - host->command_timer.data = (unsigned long) host; - host->command_timer.function = msmsdcc_command_expired; - - ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED, - DRIVER_NAME " (cmd)", host); - if (ret) - goto stat_irq_free; - - ret = request_irq(pio_irqres->start, msmsdcc_pio_irq, IRQF_SHARED, - DRIVER_NAME " (pio)", host); - if (ret) - goto cmd_irq_free; - - mmc_set_drvdata(pdev, mmc); - mmc_add_host(mmc); - - pr_info("%s: Qualcomm MSM SDCC at 0x%016llx irq %d,%d dma %d\n", - mmc_hostname(mmc), (unsigned long long)memres->start, - (unsigned int) cmd_irqres->start, - (unsigned int) host->stat_irq, host->dma.channel); - pr_info("%s: 4 bit data mode %s\n", mmc_hostname(mmc), - (mmc->caps & MMC_CAP_4_BIT_DATA ? "enabled" : "disabled")); - pr_info("%s: MMC clock %u -> %u Hz, PCLK %u Hz\n", - mmc_hostname(mmc), msmsdcc_fmin, msmsdcc_fmax, host->pclk_rate); - pr_info("%s: Slot eject status = %d\n", mmc_hostname(mmc), host->eject); - pr_info("%s: Power save feature enable = %d\n", - mmc_hostname(mmc), msmsdcc_pwrsave); - - if (host->dma.channel != -1) { - pr_info("%s: DM non-cached buffer at %p, dma_addr 0x%.8x\n", - mmc_hostname(mmc), host->dma.nc, host->dma.nc_busaddr); - pr_info("%s: DM cmd busaddr 0x%.8x, cmdptr busaddr 0x%.8x\n", - mmc_hostname(mmc), host->dma.cmd_busaddr, - host->dma.cmdptr_busaddr); - } else - pr_info("%s: PIO transfer enabled\n", mmc_hostname(mmc)); - if (host->timer.function) - pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); - - return 0; - cmd_irq_free: - free_irq(cmd_irqres->start, host); - stat_irq_free: - if (host->stat_irq) - free_irq(host->stat_irq, host); - clk_disable: - clk_disable(host->clk); - clk_put: - clk_put(host->clk); - pclk_disable: - clk_disable(host->pclk); - pclk_put: - clk_put(host->pclk); - host_free: - mmc_free_host(mmc); - out: - return ret; -} - -static int -msmsdcc_suspend(struct platform_device *dev, pm_message_t state) -{ - struct mmc_host *mmc = mmc_get_drvdata(dev); - int rc = 0; - - if (mmc) { - struct msmsdcc_host *host = mmc_priv(mmc); - - if (host->stat_irq) - disable_irq(host->stat_irq); - - if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) - rc = mmc_suspend_host(mmc, state); - if (!rc) { - writel(0, host->base + MMCIMASK0); - - if (host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } - } - } - return rc; -} - -static int -msmsdcc_resume(struct platform_device *dev) -{ - struct mmc_host *mmc = mmc_get_drvdata(dev); - unsigned long flags; - - if (mmc) { - struct msmsdcc_host *host = mmc_priv(mmc); - - spin_lock_irqsave(&host->lock, flags); - - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; - } - - writel(host->saved_irq0mask, host->base + MMCIMASK0); - - spin_unlock_irqrestore(&host->lock, flags); - - if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) - mmc_resume_host(mmc); - if (host->stat_irq) - enable_irq(host->stat_irq); - else if (host->stat_irq) - enable_irq(host->stat_irq); - } - return 0; -} - -static struct platform_driver msmsdcc_driver = { - .probe = msmsdcc_probe, - .suspend = msmsdcc_suspend, - .resume = msmsdcc_resume, - .driver = { - .name = "msm_sdcc", - }, -}; - -static int __init msmsdcc_init(void) -{ - return platform_driver_register(&msmsdcc_driver); -} - -static void __exit msmsdcc_exit(void) -{ - platform_driver_unregister(&msmsdcc_driver); -} - -module_init(msmsdcc_init); -module_exit(msmsdcc_exit); - -MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mmc/host/msm_sdcc.h b/trunk/drivers/mmc/host/msm_sdcc.h deleted file mode 100644 index 8c8448469811..000000000000 --- a/trunk/drivers/mmc/host/msm_sdcc.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * linux/drivers/mmc/host/msmsdcc.h - QCT MSM7K SDC Controller - * - * Copyright (C) 2008 Google, All Rights Reserved. - * - * 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. - * - * - Based on mmci.h - */ - -#ifndef _MSM_SDCC_H -#define _MSM_SDCC_H - -#define MSMSDCC_CRCI_SDC1 6 -#define MSMSDCC_CRCI_SDC2 7 -#define MSMSDCC_CRCI_SDC3 12 -#define MSMSDCC_CRCI_SDC4 13 - -#define MMCIPOWER 0x000 -#define MCI_PWR_OFF 0x00 -#define MCI_PWR_UP 0x02 -#define MCI_PWR_ON 0x03 -#define MCI_OD (1 << 6) - -#define MMCICLOCK 0x004 -#define MCI_CLK_ENABLE (1 << 8) -#define MCI_CLK_PWRSAVE (1 << 9) -#define MCI_CLK_WIDEBUS (1 << 10) -#define MCI_CLK_FLOWENA (1 << 12) -#define MCI_CLK_INVERTOUT (1 << 13) -#define MCI_CLK_SELECTIN (1 << 14) - -#define MMCIARGUMENT 0x008 -#define MMCICOMMAND 0x00c -#define MCI_CPSM_RESPONSE (1 << 6) -#define MCI_CPSM_LONGRSP (1 << 7) -#define MCI_CPSM_INTERRUPT (1 << 8) -#define MCI_CPSM_PENDING (1 << 9) -#define MCI_CPSM_ENABLE (1 << 10) -#define MCI_CPSM_PROGENA (1 << 11) -#define MCI_CSPM_DATCMD (1 << 12) -#define MCI_CSPM_MCIABORT (1 << 13) -#define MCI_CSPM_CCSENABLE (1 << 14) -#define MCI_CSPM_CCSDISABLE (1 << 15) - - -#define MMCIRESPCMD 0x010 -#define MMCIRESPONSE0 0x014 -#define MMCIRESPONSE1 0x018 -#define MMCIRESPONSE2 0x01c -#define MMCIRESPONSE3 0x020 -#define MMCIDATATIMER 0x024 -#define MMCIDATALENGTH 0x028 - -#define MMCIDATACTRL 0x02c -#define MCI_DPSM_ENABLE (1 << 0) -#define MCI_DPSM_DIRECTION (1 << 1) -#define MCI_DPSM_MODE (1 << 2) -#define MCI_DPSM_DMAENABLE (1 << 3) - -#define MMCIDATACNT 0x030 -#define MMCISTATUS 0x034 -#define MCI_CMDCRCFAIL (1 << 0) -#define MCI_DATACRCFAIL (1 << 1) -#define MCI_CMDTIMEOUT (1 << 2) -#define MCI_DATATIMEOUT (1 << 3) -#define MCI_TXUNDERRUN (1 << 4) -#define MCI_RXOVERRUN (1 << 5) -#define MCI_CMDRESPEND (1 << 6) -#define MCI_CMDSENT (1 << 7) -#define MCI_DATAEND (1 << 8) -#define MCI_DATABLOCKEND (1 << 10) -#define MCI_CMDACTIVE (1 << 11) -#define MCI_TXACTIVE (1 << 12) -#define MCI_RXACTIVE (1 << 13) -#define MCI_TXFIFOHALFEMPTY (1 << 14) -#define MCI_RXFIFOHALFFULL (1 << 15) -#define MCI_TXFIFOFULL (1 << 16) -#define MCI_RXFIFOFULL (1 << 17) -#define MCI_TXFIFOEMPTY (1 << 18) -#define MCI_RXFIFOEMPTY (1 << 19) -#define MCI_TXDATAAVLBL (1 << 20) -#define MCI_RXDATAAVLBL (1 << 21) -#define MCI_SDIOINTR (1 << 22) -#define MCI_PROGDONE (1 << 23) -#define MCI_ATACMDCOMPL (1 << 24) -#define MCI_SDIOINTOPER (1 << 25) -#define MCI_CCSTIMEOUT (1 << 26) - -#define MMCICLEAR 0x038 -#define MCI_CMDCRCFAILCLR (1 << 0) -#define MCI_DATACRCFAILCLR (1 << 1) -#define MCI_CMDTIMEOUTCLR (1 << 2) -#define MCI_DATATIMEOUTCLR (1 << 3) -#define MCI_TXUNDERRUNCLR (1 << 4) -#define MCI_RXOVERRUNCLR (1 << 5) -#define MCI_CMDRESPENDCLR (1 << 6) -#define MCI_CMDSENTCLR (1 << 7) -#define MCI_DATAENDCLR (1 << 8) -#define MCI_DATABLOCKENDCLR (1 << 10) - -#define MMCIMASK0 0x03c -#define MCI_CMDCRCFAILMASK (1 << 0) -#define MCI_DATACRCFAILMASK (1 << 1) -#define MCI_CMDTIMEOUTMASK (1 << 2) -#define MCI_DATATIMEOUTMASK (1 << 3) -#define MCI_TXUNDERRUNMASK (1 << 4) -#define MCI_RXOVERRUNMASK (1 << 5) -#define MCI_CMDRESPENDMASK (1 << 6) -#define MCI_CMDSENTMASK (1 << 7) -#define MCI_DATAENDMASK (1 << 8) -#define MCI_DATABLOCKENDMASK (1 << 10) -#define MCI_CMDACTIVEMASK (1 << 11) -#define MCI_TXACTIVEMASK (1 << 12) -#define MCI_RXACTIVEMASK (1 << 13) -#define MCI_TXFIFOHALFEMPTYMASK (1 << 14) -#define MCI_RXFIFOHALFFULLMASK (1 << 15) -#define MCI_TXFIFOFULLMASK (1 << 16) -#define MCI_RXFIFOFULLMASK (1 << 17) -#define MCI_TXFIFOEMPTYMASK (1 << 18) -#define MCI_RXFIFOEMPTYMASK (1 << 19) -#define MCI_TXDATAAVLBLMASK (1 << 20) -#define MCI_RXDATAAVLBLMASK (1 << 21) -#define MCI_SDIOINTMASK (1 << 22) -#define MCI_PROGDONEMASK (1 << 23) -#define MCI_ATACMDCOMPLMASK (1 << 24) -#define MCI_SDIOINTOPERMASK (1 << 25) -#define MCI_CCSTIMEOUTMASK (1 << 26) - -#define MMCIMASK1 0x040 -#define MMCIFIFOCNT 0x044 -#define MCICCSTIMER 0x058 - -#define MMCIFIFO 0x080 /* to 0x0bc */ - -#define MCI_IRQENABLE \ - (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ - MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ - MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK) - -/* - * The size of the FIFO in bytes. - */ -#define MCI_FIFOSIZE (16*4) - -#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2) - -#define NR_SG 32 - -struct clk; - -struct msmsdcc_nc_dmadata { - dmov_box cmd[NR_SG]; - uint32_t cmdptr; -}; - -struct msmsdcc_dma_data { - struct msmsdcc_nc_dmadata *nc; - dma_addr_t nc_busaddr; - dma_addr_t cmd_busaddr; - dma_addr_t cmdptr_busaddr; - - struct msm_dmov_cmd hdr; - enum dma_data_direction dir; - - struct scatterlist *sg; - int num_ents; - - int channel; - struct msmsdcc_host *host; - int busy; /* Set if DM is busy */ -}; - -struct msmsdcc_pio_data { - struct scatterlist *sg; - unsigned int sg_len; - unsigned int sg_off; -}; - -struct msmsdcc_curr_req { - struct mmc_request *mrq; - struct mmc_command *cmd; - struct mmc_data *data; - unsigned int xfer_size; /* Total data size */ - unsigned int xfer_remain; /* Bytes remaining to send */ - unsigned int data_xfered; /* Bytes acked by BLKEND irq */ - int got_dataend; - int got_datablkend; - int user_pages; -}; - -struct msmsdcc_stats { - unsigned int reqs; - unsigned int cmds; - unsigned int cmdpoll_hits; - unsigned int cmdpoll_misses; -}; - -struct msmsdcc_host { - struct resource *cmd_irqres; - struct resource *pio_irqres; - struct resource *memres; - struct resource *dmares; - void __iomem *base; - int pdev_id; - unsigned int stat_irq; - - struct msmsdcc_curr_req curr; - - struct mmc_host *mmc; - struct clk *clk; /* main MMC bus clock */ - struct clk *pclk; /* SDCC peripheral bus clock */ - unsigned int clks_on; /* set if clocks are enabled */ - struct timer_list command_timer; - - unsigned int eject; /* eject state */ - - spinlock_t lock; - - unsigned int clk_rate; /* Current clock rate */ - unsigned int pclk_rate; - - u32 pwr; - u32 saved_irq0mask; /* MMCIMASK0 reg value */ - struct mmc_platform_data *plat; - - struct timer_list timer; - unsigned int oldstat; - - struct msmsdcc_dma_data dma; - struct msmsdcc_pio_data pio; - int cmdpoll; - struct msmsdcc_stats stats; -}; - -#endif diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index 4487cc097911..1cf9cfb3b64f 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -17,8 +17,6 @@ #include #include -#include -#include #include #include #include @@ -27,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +35,6 @@ /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSCONFIG 0x0010 -#define OMAP_HSMMC_SYSSTATUS 0x0014 #define OMAP_HSMMC_CON 0x002C #define OMAP_HSMMC_BLK 0x0104 #define OMAP_HSMMC_ARG 0x0108 @@ -74,8 +70,6 @@ #define DTO_MASK 0x000F0000 #define DTO_SHIFT 16 #define INT_EN_MASK 0x307F0033 -#define BWR_ENABLE (1 << 4) -#define BRR_ENABLE (1 << 5) #define INIT_STREAM (1 << 1) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) @@ -98,8 +92,6 @@ #define DUAL_VOLT_OCR_BIT 7 #define SRC (1 << 25) #define SRD (1 << 26) -#define SOFTRESET (1 << 1) -#define RESETDONE (1 << 0) /* * FIXME: Most likely all the data using these _DEVID defines should come @@ -109,18 +101,11 @@ #define OMAP_MMC1_DEVID 0 #define OMAP_MMC2_DEVID 1 #define OMAP_MMC3_DEVID 2 -#define OMAP_MMC4_DEVID 3 -#define OMAP_MMC5_DEVID 4 #define MMC_TIMEOUT_MS 20 #define OMAP_MMC_MASTER_CLOCK 96000000 #define DRIVER_NAME "mmci-omap-hs" -/* Timeouts for entering power saving states on inactivity, msec */ -#define OMAP_MMC_DISABLED_TIMEOUT 100 -#define OMAP_MMC_SLEEP_TIMEOUT 1000 -#define OMAP_MMC_OFF_TIMEOUT 8000 - /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -137,7 +122,7 @@ #define OMAP_HSMMC_WRITE(base, reg, val) \ __raw_writel((val), (base) + OMAP_HSMMC_##reg) -struct omap_hsmmc_host { +struct mmc_omap_host { struct device *dev; struct mmc_host *mmc; struct mmc_request *mrq; @@ -150,35 +135,27 @@ struct omap_hsmmc_host { struct work_struct mmc_carddetect_work; void __iomem *base; resource_size_t mapbase; - spinlock_t irq_lock; /* Prevent races with irq handler */ - unsigned long flags; unsigned int id; unsigned int dma_len; unsigned int dma_sg_idx; unsigned char bus_mode; - unsigned char power_mode; u32 *buffer; u32 bytesleft; int suspended; int irq; + int carddetect; int use_dma, dma_ch; int dma_line_tx, dma_line_rx; int slot_id; - int got_dbclk; + int dbclk_enabled; int response_busy; - int context_loss; - int dpm_state; - int vdd; - int protect_card; - int reqs_blocked; - struct omap_mmc_platform_data *pdata; }; /* * Stop clock to the card */ -static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) +static void omap_mmc_stop_clock(struct mmc_omap_host *host) { OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN); @@ -186,178 +163,15 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); } -#ifdef CONFIG_PM - -/* - * Restore the MMC host context, if it was lost as result of a - * power state change. - */ -static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) -{ - struct mmc_ios *ios = &host->mmc->ios; - struct omap_mmc_platform_data *pdata = host->pdata; - int context_loss = 0; - u32 hctl, capa, con; - u16 dsor = 0; - unsigned long timeout; - - if (pdata->get_context_loss_count) { - context_loss = pdata->get_context_loss_count(host->dev); - if (context_loss < 0) - return 1; - } - - dev_dbg(mmc_dev(host->mmc), "context was %slost\n", - context_loss == host->context_loss ? "not " : ""); - if (host->context_loss == context_loss) - return 1; - - /* Wait for hardware reset */ - timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE - && time_before(jiffies, timeout)) - ; - - /* Do software reset */ - OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET); - timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE - && time_before(jiffies, timeout)) - ; - - OMAP_HSMMC_WRITE(host->base, SYSCONFIG, - OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE); - - if (host->id == OMAP_MMC1_DEVID) { - if (host->power_mode != MMC_POWER_OFF && - (1 << ios->vdd) <= MMC_VDD_23_24) - hctl = SDVS18; - else - hctl = SDVS30; - capa = VS30 | VS18; - } else { - hctl = SDVS18; - capa = VS18; - } - - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) | hctl); - - OMAP_HSMMC_WRITE(host->base, CAPA, - OMAP_HSMMC_READ(host->base, CAPA) | capa); - - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) | SDBP); - - timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((OMAP_HSMMC_READ(host->base, HCTL) & SDBP) != SDBP - && time_before(jiffies, timeout)) - ; - - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - /* Do not initialize card-specific things if the power is off */ - if (host->power_mode == MMC_POWER_OFF) - goto out; - - con = OMAP_HSMMC_READ(host->base, CON); - switch (ios->bus_width) { - case MMC_BUS_WIDTH_8: - OMAP_HSMMC_WRITE(host->base, CON, con | DW8); - break; - case MMC_BUS_WIDTH_4: - OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8); - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT); - break; - case MMC_BUS_WIDTH_1: - OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8); - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT); - break; - } - - if (ios->clock) { - dsor = OMAP_MMC_MASTER_CLOCK / ios->clock; - if (dsor < 1) - dsor = 1; - - if (OMAP_MMC_MASTER_CLOCK / dsor > ios->clock) - dsor++; - - if (dsor > 250) - dsor = 250; - } - - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN); - OMAP_HSMMC_WRITE(host->base, SYSCTL, (dsor << 6) | (DTO << 16)); - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); - - timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != ICS - && time_before(jiffies, timeout)) - ; - - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) | CEN); - - con = OMAP_HSMMC_READ(host->base, CON); - if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) - OMAP_HSMMC_WRITE(host->base, CON, con | OD); - else - OMAP_HSMMC_WRITE(host->base, CON, con & ~OD); -out: - host->context_loss = context_loss; - - dev_dbg(mmc_dev(host->mmc), "context is restored\n"); - return 0; -} - -/* - * Save the MMC host context (store the number of power state changes so far). - */ -static void omap_hsmmc_context_save(struct omap_hsmmc_host *host) -{ - struct omap_mmc_platform_data *pdata = host->pdata; - int context_loss; - - if (pdata->get_context_loss_count) { - context_loss = pdata->get_context_loss_count(host->dev); - if (context_loss < 0) - return; - host->context_loss = context_loss; - } -} - -#else - -static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) -{ - return 0; -} - -static void omap_hsmmc_context_save(struct omap_hsmmc_host *host) -{ -} - -#endif - /* * Send init stream sequence to card * before sending IDLE command */ -static void send_init_stream(struct omap_hsmmc_host *host) +static void send_init_stream(struct mmc_omap_host *host) { int reg = 0; unsigned long timeout; - if (host->protect_card) - return; - disable_irq(host->irq); OMAP_HSMMC_WRITE(host->base, CON, OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM); @@ -369,53 +183,51 @@ static void send_init_stream(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host->base, CON, OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM); - - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_READ(host->base, STAT); - enable_irq(host->irq); } static inline -int omap_hsmmc_cover_is_closed(struct omap_hsmmc_host *host) +int mmc_omap_cover_is_closed(struct mmc_omap_host *host) { int r = 1; - if (mmc_slot(host).get_cover_state) - r = mmc_slot(host).get_cover_state(host->dev, host->slot_id); + if (host->pdata->slots[host->slot_id].get_cover_state) + r = host->pdata->slots[host->slot_id].get_cover_state(host->dev, + host->slot_id); return r; } static ssize_t -omap_hsmmc_show_cover_switch(struct device *dev, struct device_attribute *attr, +mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr, char *buf) { struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev); - struct omap_hsmmc_host *host = mmc_priv(mmc); + struct mmc_omap_host *host = mmc_priv(mmc); - return sprintf(buf, "%s\n", - omap_hsmmc_cover_is_closed(host) ? "closed" : "open"); + return sprintf(buf, "%s\n", mmc_omap_cover_is_closed(host) ? "closed" : + "open"); } -static DEVICE_ATTR(cover_switch, S_IRUGO, omap_hsmmc_show_cover_switch, NULL); +static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL); static ssize_t -omap_hsmmc_show_slot_name(struct device *dev, struct device_attribute *attr, +mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr, char *buf) { struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev); - struct omap_hsmmc_host *host = mmc_priv(mmc); + struct mmc_omap_host *host = mmc_priv(mmc); + struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id]; - return sprintf(buf, "%s\n", mmc_slot(host).name); + return sprintf(buf, "%s\n", slot.name); } -static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL); +static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL); /* * Configure the response type and send the cmd. */ static void -omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, +mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd, struct mmc_data *data) { int cmdreg = 0, resptype = 0, cmdtype = 0; @@ -429,12 +241,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, */ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - - if (host->use_dma) - OMAP_HSMMC_WRITE(host->base, IE, - INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); - else - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); host->response_busy = 0; if (cmd->flags & MMC_RSP_PRESENT) { @@ -468,20 +275,12 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, if (host->use_dma) cmdreg |= DMA_EN; - /* - * In an interrupt context (i.e. STOP command), the spinlock is unlocked - * by the interrupt handler, otherwise (i.e. for a new request) it is - * unlocked here. - */ - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); - OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg); OMAP_HSMMC_WRITE(host->base, CMD, cmdreg); } static int -omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) +mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data) { if (data->flags & MMC_DATA_WRITE) return DMA_TO_DEVICE; @@ -493,18 +292,11 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) * Notify the transfer complete to MMC core */ static void -omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) +mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) { if (!data) { struct mmc_request *mrq = host->mrq; - /* TC before CC from CMD6 - don't know why, but it happens */ - if (host->cmd && host->cmd->opcode == 6 && - host->response_busy) { - host->response_busy = 0; - return; - } - host->mrq = NULL; mmc_request_done(host->mmc, mrq); return; @@ -514,7 +306,7 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) if (host->use_dma && host->dma_ch != -1) dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, - omap_hsmmc_get_dma_dir(host, data)); + mmc_omap_get_dma_dir(host, data)); if (!data->error) data->bytes_xfered += data->blocks * (data->blksz); @@ -526,14 +318,14 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) mmc_request_done(host->mmc, data->mrq); return; } - omap_hsmmc_start_command(host, data->stop, NULL); + mmc_omap_start_command(host, data->stop, NULL); } /* * Notify the core about command completion */ static void -omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) +mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) { host->cmd = NULL; @@ -558,13 +350,13 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) /* * DMA clean up for command errors */ -static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) +static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno) { host->data->error = errno; if (host->use_dma && host->dma_ch != -1) { dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len, - omap_hsmmc_get_dma_dir(host, host->data)); + mmc_omap_get_dma_dir(host, host->data)); omap_free_dma(host->dma_ch); host->dma_ch = -1; up(&host->sem); @@ -576,10 +368,10 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) * Readable error output */ #ifdef CONFIG_MMC_DEBUG -static void omap_hsmmc_report_irq(struct omap_hsmmc_host *host, u32 status) +static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status) { /* --- means reserved bit without definition at documentation */ - static const char *omap_hsmmc_status_bits[] = { + static const char *mmc_omap_status_bits[] = { "CC", "TC", "BGE", "---", "BWR", "BRR", "---", "---", "CIRQ", "OBI", "---", "---", "---", "---", "---", "ERRI", "CTO", "CCRC", "CEB", "CIE", "DTO", "DCRC", "DEB", "---", "ACE", "---", @@ -592,9 +384,9 @@ static void omap_hsmmc_report_irq(struct omap_hsmmc_host *host, u32 status) len = sprintf(buf, "MMC IRQ 0x%x :", status); buf += len; - for (i = 0; i < ARRAY_SIZE(omap_hsmmc_status_bits); i++) + for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++) if (status & (1 << i)) { - len = sprintf(buf, " %s", omap_hsmmc_status_bits[i]); + len = sprintf(buf, " %s", mmc_omap_status_bits[i]); buf += len; } @@ -609,8 +401,8 @@ static void omap_hsmmc_report_irq(struct omap_hsmmc_host *host, u32 status) * SRC or SRD bit of SYSCTL register * Can be called from interrupt context */ -static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, - unsigned long bit) +static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host, + unsigned long bit) { unsigned long i = 0; unsigned long limit = (loops_per_jiffy * @@ -632,20 +424,17 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, /* * MMC controller IRQ handler */ -static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) +static irqreturn_t mmc_omap_irq(int irq, void *dev_id) { - struct omap_hsmmc_host *host = dev_id; + struct mmc_omap_host *host = dev_id; struct mmc_data *data; int end_cmd = 0, end_trans = 0, status; - spin_lock(&host->irq_lock); - if (host->mrq == NULL) { OMAP_HSMMC_WRITE(host->base, STAT, OMAP_HSMMC_READ(host->base, STAT)); /* Flush posted write */ OMAP_HSMMC_READ(host->base, STAT); - spin_unlock(&host->irq_lock); return IRQ_HANDLED; } @@ -655,14 +444,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) if (status & ERR) { #ifdef CONFIG_MMC_DEBUG - omap_hsmmc_report_irq(host, status); + mmc_omap_report_irq(host, status); #endif if ((status & CMD_TIMEOUT) || (status & CMD_CRC)) { if (host->cmd) { if (status & CMD_TIMEOUT) { - omap_hsmmc_reset_controller_fsm(host, - SRC); + mmc_omap_reset_controller_fsm(host, SRC); host->cmd->error = -ETIMEDOUT; } else { host->cmd->error = -EILSEQ; @@ -671,10 +459,9 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) } if (host->data || host->response_busy) { if (host->data) - omap_hsmmc_dma_cleanup(host, - -ETIMEDOUT); + mmc_dma_cleanup(host, -ETIMEDOUT); host->response_busy = 0; - omap_hsmmc_reset_controller_fsm(host, SRD); + mmc_omap_reset_controller_fsm(host, SRD); } } if ((status & DATA_TIMEOUT) || @@ -684,11 +471,11 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) -ETIMEDOUT : -EILSEQ; if (host->data) - omap_hsmmc_dma_cleanup(host, err); + mmc_dma_cleanup(host, err); else host->mrq->cmd->error = err; host->response_busy = 0; - omap_hsmmc_reset_controller_fsm(host, SRD); + mmc_omap_reset_controller_fsm(host, SRD); end_trans = 1; } } @@ -707,16 +494,14 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) OMAP_HSMMC_READ(host->base, STAT); if (end_cmd || ((status & CC) && host->cmd)) - omap_hsmmc_cmd_done(host, host->cmd); - if ((end_trans || (status & TC)) && host->mrq) - omap_hsmmc_xfer_done(host, data); - - spin_unlock(&host->irq_lock); + mmc_omap_cmd_done(host, host->cmd); + if (end_trans || (status & TC)) + mmc_omap_xfer_done(host, data); return IRQ_HANDLED; } -static void set_sd_bus_power(struct omap_hsmmc_host *host) +static void set_sd_bus_power(struct mmc_omap_host *host) { unsigned long i; @@ -736,7 +521,7 @@ static void set_sd_bus_power(struct omap_hsmmc_host *host) * The MMC2 transceiver controls are used instead of DAT4..DAT7. * Some chips, like eMMC ones, use internal transceivers. */ -static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) +static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) { u32 reg_val = 0; int ret; @@ -744,24 +529,22 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) /* Disable the clocks */ clk_disable(host->fclk); clk_disable(host->iclk); - if (host->got_dbclk) - clk_disable(host->dbclk); + clk_disable(host->dbclk); /* Turn the power off */ ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); + if (ret != 0) + goto err; /* Turn the power ON with given VDD 1.8 or 3.0v */ - if (!ret) - ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, - vdd); - clk_enable(host->iclk); - clk_enable(host->fclk); - if (host->got_dbclk) - clk_enable(host->dbclk); - + ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd); if (ret != 0) goto err; + clk_enable(host->fclk); + clk_enable(host->iclk); + clk_enable(host->dbclk); + OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); reg_val = OMAP_HSMMC_READ(host->base, HCTL); @@ -769,7 +552,7 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) /* * If a MMC dual voltage card is detected, the set_ios fn calls * this fn with VDD bit set for 1.8V. Upon card removal from the - * slot, omap_hsmmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. + * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. * * Cope with a bit of slop in the range ... per data sheets: * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, @@ -795,59 +578,25 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) return ret; } -/* Protect the card while the cover is open */ -static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) -{ - if (!mmc_slot(host).get_cover_state) - return; - - host->reqs_blocked = 0; - if (mmc_slot(host).get_cover_state(host->dev, host->slot_id)) { - if (host->protect_card) { - printk(KERN_INFO "%s: cover is closed, " - "card is now accessible\n", - mmc_hostname(host->mmc)); - host->protect_card = 0; - } - } else { - if (!host->protect_card) { - printk(KERN_INFO "%s: cover is open, " - "card is now inaccessible\n", - mmc_hostname(host->mmc)); - host->protect_card = 1; - } - } -} - /* * Work Item to notify the core about card insertion/removal */ -static void omap_hsmmc_detect(struct work_struct *work) +static void mmc_omap_detect(struct work_struct *work) { - struct omap_hsmmc_host *host = - container_of(work, struct omap_hsmmc_host, mmc_carddetect_work); + struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, + mmc_carddetect_work); struct omap_mmc_slot_data *slot = &mmc_slot(host); - int carddetect; - if (host->suspended) - return; + if (mmc_slot(host).card_detect) + host->carddetect = slot->card_detect(slot->card_detect_irq); + else + host->carddetect = -ENOSYS; sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); - - if (slot->card_detect) - carddetect = slot->card_detect(slot->card_detect_irq); - else { - omap_hsmmc_protect_card(host); - carddetect = -ENOSYS; - } - - if (carddetect) { + if (host->carddetect) { mmc_detect_change(host->mmc, (HZ * 200) / 1000); } else { - mmc_host_enable(host->mmc); - omap_hsmmc_reset_controller_fsm(host, SRD); - mmc_host_lazy_disable(host->mmc); - + mmc_omap_reset_controller_fsm(host, SRD); mmc_detect_change(host->mmc, (HZ * 50) / 1000); } } @@ -855,18 +604,16 @@ static void omap_hsmmc_detect(struct work_struct *work) /* * ISR for handling card insertion and removal */ -static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id) +static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id) { - struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id; + struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id; - if (host->suspended) - return IRQ_HANDLED; schedule_work(&host->mmc_carddetect_work); return IRQ_HANDLED; } -static int omap_hsmmc_get_dma_sync_dev(struct omap_hsmmc_host *host, +static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host, struct mmc_data *data) { int sync_dev; @@ -878,7 +625,7 @@ static int omap_hsmmc_get_dma_sync_dev(struct omap_hsmmc_host *host, return sync_dev; } -static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, +static void mmc_omap_config_dma_params(struct mmc_omap_host *host, struct mmc_data *data, struct scatterlist *sgl) { @@ -892,7 +639,7 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, sg_dma_address(sgl), 0, 0); } else { omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, - (host->mapbase + OMAP_HSMMC_DATA), 0, 0); + (host->mapbase + OMAP_HSMMC_DATA), 0, 0); omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC, sg_dma_address(sgl), 0, 0); } @@ -902,7 +649,7 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32, blksz / 4, nblk, OMAP_DMA_SYNC_FRAME, - omap_hsmmc_get_dma_sync_dev(host, data), + mmc_omap_get_dma_sync_dev(host, data), !(data->flags & MMC_DATA_WRITE)); omap_start_dma(dma_ch); @@ -911,9 +658,9 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, /* * DMA call back function */ -static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) +static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) { - struct omap_hsmmc_host *host = data; + struct mmc_omap_host *host = data; if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ) dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n"); @@ -924,7 +671,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) host->dma_sg_idx++; if (host->dma_sg_idx < host->dma_len) { /* Fire up the next transfer. */ - omap_hsmmc_config_dma_params(host, host->data, + mmc_omap_config_dma_params(host, host->data, host->data->sg + host->dma_sg_idx); return; } @@ -941,14 +688,14 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) /* * Routine to configure and start DMA for the MMC card */ -static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, - struct mmc_request *req) +static int +mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req) { int dma_ch = 0, ret = 0, err = 1, i; struct mmc_data *data = req->data; /* Sanity check: all the SG entries must be aligned by block size. */ - for (i = 0; i < data->sg_len; i++) { + for (i = 0; i < host->dma_len; i++) { struct scatterlist *sgl; sgl = data->sg + i; @@ -979,8 +726,8 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, return err; } - ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data), - "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch); + ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD", + mmc_omap_dma_cb,host, &dma_ch); if (ret != 0) { dev_err(mmc_dev(host->mmc), "%s: omap_request_dma() failed with %d\n", @@ -989,18 +736,17 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, } host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, omap_hsmmc_get_dma_dir(host, data)); + data->sg_len, mmc_omap_get_dma_dir(host, data)); host->dma_ch = dma_ch; host->dma_sg_idx = 0; - omap_hsmmc_config_dma_params(host, data, data->sg); + mmc_omap_config_dma_params(host, data, data->sg); return 0; } -static void set_data_timeout(struct omap_hsmmc_host *host, - unsigned int timeout_ns, - unsigned int timeout_clks) +static void set_data_timeout(struct mmc_omap_host *host, + struct mmc_request *req) { unsigned int timeout, cycle_ns; uint32_t reg, clkd, dto = 0; @@ -1011,8 +757,8 @@ static void set_data_timeout(struct omap_hsmmc_host *host, clkd = 1; cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); - timeout = timeout_ns / cycle_ns; - timeout += timeout_clks; + timeout = req->data->timeout_ns / cycle_ns; + timeout += req->data->timeout_clks; if (timeout) { while ((timeout & 0x80000000) == 0) { dto += 1; @@ -1039,28 +785,22 @@ static void set_data_timeout(struct omap_hsmmc_host *host, * Configure block length for MMC/SD cards and initiate the transfer. */ static int -omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) +mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) { int ret; host->data = req->data; if (req->data == NULL) { OMAP_HSMMC_WRITE(host->base, BLK, 0); - /* - * Set an arbitrary 100ms data timeout for commands with - * busy signal. - */ - if (req->cmd->flags & MMC_RSP_BUSY) - set_data_timeout(host, 100000000U, 0); return 0; } OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) | (req->data->blocks << 16)); - set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks); + set_data_timeout(host, req); if (host->use_dma) { - ret = omap_hsmmc_start_dma_transfer(host, req); + ret = mmc_omap_start_dma_transfer(host, req); if (ret != 0) { dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n"); return ret; @@ -1072,92 +812,35 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) /* * Request function. for read/write operation */ -static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) +static void omap_mmc_request(struct mmc_host *mmc, struct mmc_request *req) { - struct omap_hsmmc_host *host = mmc_priv(mmc); - int err; + struct mmc_omap_host *host = mmc_priv(mmc); - /* - * Prevent races with the interrupt handler because of unexpected - * interrupts, but not if we are already in interrupt context i.e. - * retries. - */ - if (!in_interrupt()) { - spin_lock_irqsave(&host->irq_lock, host->flags); - /* - * Protect the card from I/O if there is a possibility - * it can be removed. - */ - if (host->protect_card) { - if (host->reqs_blocked < 3) { - /* - * Ensure the controller is left in a consistent - * state by resetting the command and data state - * machines. - */ - omap_hsmmc_reset_controller_fsm(host, SRD); - omap_hsmmc_reset_controller_fsm(host, SRC); - host->reqs_blocked += 1; - } - req->cmd->error = -EBADF; - if (req->data) - req->data->error = -EBADF; - spin_unlock_irqrestore(&host->irq_lock, host->flags); - mmc_request_done(mmc, req); - return; - } else if (host->reqs_blocked) - host->reqs_blocked = 0; - } WARN_ON(host->mrq != NULL); host->mrq = req; - err = omap_hsmmc_prepare_data(host, req); - if (err) { - req->cmd->error = err; - if (req->data) - req->data->error = err; - host->mrq = NULL; - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); - mmc_request_done(mmc, req); - return; - } - - omap_hsmmc_start_command(host, req->cmd, req->data); + mmc_omap_prepare_data(host, req); + mmc_omap_start_command(host, req->cmd, req->data); } + /* Routine to configure clock values. Exposed API to core */ -static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { - struct omap_hsmmc_host *host = mmc_priv(mmc); + struct mmc_omap_host *host = mmc_priv(mmc); u16 dsor = 0; unsigned long regval; unsigned long timeout; u32 con; - int do_send_init_stream = 0; - - mmc_host_enable(host->mmc); - if (ios->power_mode != host->power_mode) { - switch (ios->power_mode) { - case MMC_POWER_OFF: - mmc_slot(host).set_power(host->dev, host->slot_id, - 0, 0); - host->vdd = 0; - break; - case MMC_POWER_UP: - mmc_slot(host).set_power(host->dev, host->slot_id, - 1, ios->vdd); - host->vdd = ios->vdd; - break; - case MMC_POWER_ON: - do_send_init_stream = 1; - break; - } - host->power_mode = ios->power_mode; + switch (ios->power_mode) { + case MMC_POWER_OFF: + mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); + break; + case MMC_POWER_UP: + mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd); + break; } - /* FIXME: set registers based only on changes to ios */ - con = OMAP_HSMMC_READ(host->base, CON); switch (mmc->ios.bus_width) { case MMC_BUS_WIDTH_8: @@ -1187,8 +870,8 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * MMC_POWER_UP upon recalculating the voltage. * vdd 1.8v. */ - if (omap_hsmmc_switch_opcond(host, ios->vdd) != 0) - dev_dbg(mmc_dev(host->mmc), + if (omap_mmc_switch_opcond(host, ios->vdd) != 0) + dev_dbg(mmc_dev(host->mmc), "Switch operation failed\n"); } } @@ -1204,7 +887,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (dsor > 250) dsor = 250; } - omap_hsmmc_stop_clock(host); + omap_mmc_stop_clock(host); regval = OMAP_HSMMC_READ(host->base, SYSCTL); regval = regval & ~(CLKD_MASK); regval = regval | (dsor << 6) | (DTO << 16); @@ -1214,47 +897,42 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* Wait till the ICS bit is set */ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); - while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != ICS + while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != 0x2 && time_before(jiffies, timeout)) msleep(1); OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | CEN); - if (do_send_init_stream) + if (ios->power_mode == MMC_POWER_ON) send_init_stream(host); - con = OMAP_HSMMC_READ(host->base, CON); if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) - OMAP_HSMMC_WRITE(host->base, CON, con | OD); - else - OMAP_HSMMC_WRITE(host->base, CON, con & ~OD); - - if (host->power_mode == MMC_POWER_OFF) - mmc_host_disable(host->mmc); - else - mmc_host_lazy_disable(host->mmc); + OMAP_HSMMC_WRITE(host->base, CON, + OMAP_HSMMC_READ(host->base, CON) | OD); } static int omap_hsmmc_get_cd(struct mmc_host *mmc) { - struct omap_hsmmc_host *host = mmc_priv(mmc); + struct mmc_omap_host *host = mmc_priv(mmc); + struct omap_mmc_platform_data *pdata = host->pdata; - if (!mmc_slot(host).card_detect) + if (!pdata->slots[0].card_detect) return -ENOSYS; - return mmc_slot(host).card_detect(mmc_slot(host).card_detect_irq); + return pdata->slots[0].card_detect(pdata->slots[0].card_detect_irq); } static int omap_hsmmc_get_ro(struct mmc_host *mmc) { - struct omap_hsmmc_host *host = mmc_priv(mmc); + struct mmc_omap_host *host = mmc_priv(mmc); + struct omap_mmc_platform_data *pdata = host->pdata; - if (!mmc_slot(host).get_ro) + if (!pdata->slots[0].get_ro) return -ENOSYS; - return mmc_slot(host).get_ro(host->dev, 0); + return pdata->slots[0].get_ro(host->dev, 0); } -static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) +static void omap_hsmmc_init(struct mmc_omap_host *host) { u32 hctl, capa, value; @@ -1281,340 +959,19 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) set_sd_bus_power(host); } -/* - * Dynamic power saving handling, FSM: - * ENABLED -> DISABLED -> CARDSLEEP / REGSLEEP -> OFF - * ^___________| | | - * |______________________|______________________| - * - * ENABLED: mmc host is fully functional - * DISABLED: fclk is off - * CARDSLEEP: fclk is off, card is asleep, voltage regulator is asleep - * REGSLEEP: fclk is off, voltage regulator is asleep - * OFF: fclk is off, voltage regulator is off - * - * Transition handlers return the timeout for the next state transition - * or negative error. - */ - -enum {ENABLED = 0, DISABLED, CARDSLEEP, REGSLEEP, OFF}; - -/* Handler for [ENABLED -> DISABLED] transition */ -static int omap_hsmmc_enabled_to_disabled(struct omap_hsmmc_host *host) -{ - omap_hsmmc_context_save(host); - clk_disable(host->fclk); - host->dpm_state = DISABLED; - - dev_dbg(mmc_dev(host->mmc), "ENABLED -> DISABLED\n"); - - if (host->power_mode == MMC_POWER_OFF) - return 0; - - return msecs_to_jiffies(OMAP_MMC_SLEEP_TIMEOUT); -} - -/* Handler for [DISABLED -> REGSLEEP / CARDSLEEP] transition */ -static int omap_hsmmc_disabled_to_sleep(struct omap_hsmmc_host *host) -{ - int err, new_state; - - if (!mmc_try_claim_host(host->mmc)) - return 0; - - clk_enable(host->fclk); - omap_hsmmc_context_restore(host); - if (mmc_card_can_sleep(host->mmc)) { - err = mmc_card_sleep(host->mmc); - if (err < 0) { - clk_disable(host->fclk); - mmc_release_host(host->mmc); - return err; - } - new_state = CARDSLEEP; - } else { - new_state = REGSLEEP; - } - if (mmc_slot(host).set_sleep) - mmc_slot(host).set_sleep(host->dev, host->slot_id, 1, 0, - new_state == CARDSLEEP); - /* FIXME: turn off bus power and perhaps interrupts too */ - clk_disable(host->fclk); - host->dpm_state = new_state; - - mmc_release_host(host->mmc); - - dev_dbg(mmc_dev(host->mmc), "DISABLED -> %s\n", - host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); - - if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) || - mmc_slot(host).card_detect || - (mmc_slot(host).get_cover_state && - mmc_slot(host).get_cover_state(host->dev, host->slot_id))) - return msecs_to_jiffies(OMAP_MMC_OFF_TIMEOUT); - - return 0; -} - -/* Handler for [REGSLEEP / CARDSLEEP -> OFF] transition */ -static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) -{ - if (!mmc_try_claim_host(host->mmc)) - return 0; - - if (!((host->mmc->caps & MMC_CAP_NONREMOVABLE) || - mmc_slot(host).card_detect || - (mmc_slot(host).get_cover_state && - mmc_slot(host).get_cover_state(host->dev, host->slot_id)))) { - mmc_release_host(host->mmc); - return 0; - } - - mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); - host->vdd = 0; - host->power_mode = MMC_POWER_OFF; - - dev_dbg(mmc_dev(host->mmc), "%s -> OFF\n", - host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); - - host->dpm_state = OFF; - - mmc_release_host(host->mmc); - - return 0; -} - -/* Handler for [DISABLED -> ENABLED] transition */ -static int omap_hsmmc_disabled_to_enabled(struct omap_hsmmc_host *host) -{ - int err; - - err = clk_enable(host->fclk); - if (err < 0) - return err; - - omap_hsmmc_context_restore(host); - host->dpm_state = ENABLED; - - dev_dbg(mmc_dev(host->mmc), "DISABLED -> ENABLED\n"); - - return 0; -} - -/* Handler for [SLEEP -> ENABLED] transition */ -static int omap_hsmmc_sleep_to_enabled(struct omap_hsmmc_host *host) -{ - if (!mmc_try_claim_host(host->mmc)) - return 0; - - clk_enable(host->fclk); - omap_hsmmc_context_restore(host); - if (mmc_slot(host).set_sleep) - mmc_slot(host).set_sleep(host->dev, host->slot_id, 0, - host->vdd, host->dpm_state == CARDSLEEP); - if (mmc_card_can_sleep(host->mmc)) - mmc_card_awake(host->mmc); - - dev_dbg(mmc_dev(host->mmc), "%s -> ENABLED\n", - host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); - - host->dpm_state = ENABLED; - - mmc_release_host(host->mmc); - - return 0; -} - -/* Handler for [OFF -> ENABLED] transition */ -static int omap_hsmmc_off_to_enabled(struct omap_hsmmc_host *host) -{ - clk_enable(host->fclk); - - omap_hsmmc_context_restore(host); - omap_hsmmc_conf_bus_power(host); - mmc_power_restore_host(host->mmc); - - host->dpm_state = ENABLED; - - dev_dbg(mmc_dev(host->mmc), "OFF -> ENABLED\n"); - - return 0; -} - -/* - * Bring MMC host to ENABLED from any other PM state. - */ -static int omap_hsmmc_enable(struct mmc_host *mmc) -{ - struct omap_hsmmc_host *host = mmc_priv(mmc); - - switch (host->dpm_state) { - case DISABLED: - return omap_hsmmc_disabled_to_enabled(host); - case CARDSLEEP: - case REGSLEEP: - return omap_hsmmc_sleep_to_enabled(host); - case OFF: - return omap_hsmmc_off_to_enabled(host); - default: - dev_dbg(mmc_dev(host->mmc), "UNKNOWN state\n"); - return -EINVAL; - } -} - -/* - * Bring MMC host in PM state (one level deeper). - */ -static int omap_hsmmc_disable(struct mmc_host *mmc, int lazy) -{ - struct omap_hsmmc_host *host = mmc_priv(mmc); - - switch (host->dpm_state) { - case ENABLED: { - int delay; - - delay = omap_hsmmc_enabled_to_disabled(host); - if (lazy || delay < 0) - return delay; - return 0; - } - case DISABLED: - return omap_hsmmc_disabled_to_sleep(host); - case CARDSLEEP: - case REGSLEEP: - return omap_hsmmc_sleep_to_off(host); - default: - dev_dbg(mmc_dev(host->mmc), "UNKNOWN state\n"); - return -EINVAL; - } -} - -static int omap_hsmmc_enable_fclk(struct mmc_host *mmc) -{ - struct omap_hsmmc_host *host = mmc_priv(mmc); - int err; - - err = clk_enable(host->fclk); - if (err) - return err; - dev_dbg(mmc_dev(host->mmc), "mmc_fclk: enabled\n"); - omap_hsmmc_context_restore(host); - return 0; -} - -static int omap_hsmmc_disable_fclk(struct mmc_host *mmc, int lazy) -{ - struct omap_hsmmc_host *host = mmc_priv(mmc); - - omap_hsmmc_context_save(host); - clk_disable(host->fclk); - dev_dbg(mmc_dev(host->mmc), "mmc_fclk: disabled\n"); - return 0; -} - -static const struct mmc_host_ops omap_hsmmc_ops = { - .enable = omap_hsmmc_enable_fclk, - .disable = omap_hsmmc_disable_fclk, - .request = omap_hsmmc_request, - .set_ios = omap_hsmmc_set_ios, +static struct mmc_host_ops mmc_omap_ops = { + .request = omap_mmc_request, + .set_ios = omap_mmc_set_ios, .get_cd = omap_hsmmc_get_cd, .get_ro = omap_hsmmc_get_ro, /* NYET -- enable_sdio_irq */ }; -static const struct mmc_host_ops omap_hsmmc_ps_ops = { - .enable = omap_hsmmc_enable, - .disable = omap_hsmmc_disable, - .request = omap_hsmmc_request, - .set_ios = omap_hsmmc_set_ios, - .get_cd = omap_hsmmc_get_cd, - .get_ro = omap_hsmmc_get_ro, - /* NYET -- enable_sdio_irq */ -}; - -#ifdef CONFIG_DEBUG_FS - -static int omap_hsmmc_regs_show(struct seq_file *s, void *data) -{ - struct mmc_host *mmc = s->private; - struct omap_hsmmc_host *host = mmc_priv(mmc); - int context_loss = 0; - - if (host->pdata->get_context_loss_count) - context_loss = host->pdata->get_context_loss_count(host->dev); - - seq_printf(s, "mmc%d:\n" - " enabled:\t%d\n" - " dpm_state:\t%d\n" - " nesting_cnt:\t%d\n" - " ctx_loss:\t%d:%d\n" - "\nregs:\n", - mmc->index, mmc->enabled ? 1 : 0, - host->dpm_state, mmc->nesting_cnt, - host->context_loss, context_loss); - - if (host->suspended || host->dpm_state == OFF) { - seq_printf(s, "host suspended, can't read registers\n"); - return 0; - } - - if (clk_enable(host->fclk) != 0) { - seq_printf(s, "can't read the regs\n"); - return 0; - } - - seq_printf(s, "SYSCONFIG:\t0x%08x\n", - OMAP_HSMMC_READ(host->base, SYSCONFIG)); - seq_printf(s, "CON:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, CON)); - seq_printf(s, "HCTL:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, HCTL)); - seq_printf(s, "SYSCTL:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, SYSCTL)); - seq_printf(s, "IE:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, IE)); - seq_printf(s, "ISE:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, ISE)); - seq_printf(s, "CAPA:\t\t0x%08x\n", - OMAP_HSMMC_READ(host->base, CAPA)); - - clk_disable(host->fclk); - - return 0; -} - -static int omap_hsmmc_regs_open(struct inode *inode, struct file *file) -{ - return single_open(file, omap_hsmmc_regs_show, inode->i_private); -} - -static const struct file_operations mmc_regs_fops = { - .open = omap_hsmmc_regs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void omap_hsmmc_debugfs(struct mmc_host *mmc) -{ - if (mmc->debugfs_root) - debugfs_create_file("regs", S_IRUSR, mmc->debugfs_root, - mmc, &mmc_regs_fops); -} - -#else - -static void omap_hsmmc_debugfs(struct mmc_host *mmc) -{ -} - -#endif - -static int __init omap_hsmmc_probe(struct platform_device *pdev) +static int __init omap_mmc_probe(struct platform_device *pdev) { struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; struct mmc_host *mmc; - struct omap_hsmmc_host *host = NULL; + struct mmc_omap_host *host = NULL; struct resource *res; int ret = 0, irq; @@ -1638,7 +995,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) if (res == NULL) return -EBUSY; - mmc = mmc_alloc_host(sizeof(struct omap_hsmmc_host), &pdev->dev); + mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto err; @@ -1656,21 +1013,15 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) host->slot_id = 0; host->mapbase = res->start; host->base = ioremap(host->mapbase, SZ_4K); - host->power_mode = -1; platform_set_drvdata(pdev, host); - INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); - - if (mmc_slot(host).power_saving) - mmc->ops = &omap_hsmmc_ps_ops; - else - mmc->ops = &omap_hsmmc_ops; + INIT_WORK(&host->mmc_carddetect_work, mmc_omap_detect); + mmc->ops = &mmc_omap_ops; mmc->f_min = 400000; mmc->f_max = 52000000; sema_init(&host->sem, 1); - spin_lock_init(&host->irq_lock); host->iclk = clk_get(&pdev->dev, "ick"); if (IS_ERR(host->iclk)) { @@ -1686,42 +1037,31 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) goto err1; } - omap_hsmmc_context_save(host); - - mmc->caps |= MMC_CAP_DISABLE; - mmc_set_disable_delay(mmc, OMAP_MMC_DISABLED_TIMEOUT); - /* we start off in DISABLED state */ - host->dpm_state = DISABLED; - - if (mmc_host_enable(host->mmc) != 0) { + if (clk_enable(host->fclk) != 0) { clk_put(host->iclk); clk_put(host->fclk); goto err1; } if (clk_enable(host->iclk) != 0) { - mmc_host_disable(host->mmc); + clk_disable(host->fclk); clk_put(host->iclk); clk_put(host->fclk); goto err1; } - if (cpu_is_omap2430()) { - host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); - /* - * MMC can still work without debounce clock. - */ - if (IS_ERR(host->dbclk)) - dev_warn(mmc_dev(host->mmc), - "Failed to get debounce clock\n"); - else - host->got_dbclk = 1; - - if (host->got_dbclk) - if (clk_enable(host->dbclk) != 0) - dev_dbg(mmc_dev(host->mmc), "Enabling debounce" + host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); + /* + * MMC can still work without debounce clock. + */ + if (IS_ERR(host->dbclk)) + dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n"); + else + if (clk_enable(host->dbclk) != 0) + dev_dbg(mmc_dev(host->mmc), "Enabling debounce" " clk failed\n"); - } + else + host->dbclk_enabled = 1; /* Since we do only SG emulation, we can have as many segs * as we want. */ @@ -1733,18 +1073,14 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; - mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_WAIT_WHILE_BUSY; + mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; - if (mmc_slot(host).wires >= 8) + if (pdata->slots[host->slot_id].wires >= 8) mmc->caps |= MMC_CAP_8_BIT_DATA; - else if (mmc_slot(host).wires >= 4) + else if (pdata->slots[host->slot_id].wires >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (mmc_slot(host).nonremovable) - mmc->caps |= MMC_CAP_NONREMOVABLE; - - omap_hsmmc_conf_bus_power(host); + omap_hsmmc_init(host); /* Select DMA lines */ switch (host->id) { @@ -1760,21 +1096,13 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) host->dma_line_tx = OMAP34XX_DMA_MMC3_TX; host->dma_line_rx = OMAP34XX_DMA_MMC3_RX; break; - case OMAP_MMC4_DEVID: - host->dma_line_tx = OMAP44XX_DMA_MMC4_TX; - host->dma_line_rx = OMAP44XX_DMA_MMC4_RX; - break; - case OMAP_MMC5_DEVID: - host->dma_line_tx = OMAP44XX_DMA_MMC5_TX; - host->dma_line_rx = OMAP44XX_DMA_MMC5_RX; - break; default: dev_err(mmc_dev(host->mmc), "Invalid MMC id\n"); goto err_irq; } /* Request IRQ for MMC operations */ - ret = request_irq(host->irq, omap_hsmmc_irq, IRQF_DISABLED, + ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED, mmc_hostname(mmc), host); if (ret) { dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n"); @@ -1784,8 +1112,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) /* initialize power supplies, gpios, etc */ if (pdata->init != NULL) { if (pdata->init(&pdev->dev) != 0) { - dev_dbg(mmc_dev(host->mmc), - "Unable to configure MMC IRQs\n"); + dev_dbg(mmc_dev(host->mmc), "late init error\n"); goto err_irq_cd_init; } } @@ -1794,7 +1121,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) /* Request IRQ for card detect */ if ((mmc_slot(host).card_detect_irq)) { ret = request_irq(mmc_slot(host).card_detect_irq, - omap_hsmmc_cd_handler, + omap_mmc_cd_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, mmc_hostname(mmc), host); @@ -1808,26 +1135,21 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - mmc_host_lazy_disable(host->mmc); - - omap_hsmmc_protect_card(host); - mmc_add_host(mmc); - if (mmc_slot(host).name != NULL) { + if (host->pdata->slots[host->slot_id].name != NULL) { ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name); if (ret < 0) goto err_slot_name; } - if (mmc_slot(host).card_detect_irq && mmc_slot(host).get_cover_state) { + if (mmc_slot(host).card_detect_irq && + host->pdata->slots[host->slot_id].get_cover_state) { ret = device_create_file(&mmc->class_dev, &dev_attr_cover_switch); if (ret < 0) goto err_cover_switch; } - omap_hsmmc_debugfs(mmc); - return 0; err_cover_switch: @@ -1839,11 +1161,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) err_irq_cd_init: free_irq(host->irq, host); err_irq: - mmc_host_disable(host->mmc); + clk_disable(host->fclk); clk_disable(host->iclk); clk_put(host->fclk); clk_put(host->iclk); - if (host->got_dbclk) { + if (host->dbclk_enabled) { clk_disable(host->dbclk); clk_put(host->dbclk); } @@ -1858,13 +1180,12 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) return ret; } -static int omap_hsmmc_remove(struct platform_device *pdev) +static int omap_mmc_remove(struct platform_device *pdev) { - struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + struct mmc_omap_host *host = platform_get_drvdata(pdev); struct resource *res; if (host) { - mmc_host_enable(host->mmc); mmc_remove_host(host->mmc); if (host->pdata->cleanup) host->pdata->cleanup(&pdev->dev); @@ -1873,11 +1194,11 @@ static int omap_hsmmc_remove(struct platform_device *pdev) free_irq(mmc_slot(host).card_detect_irq, host); flush_scheduled_work(); - mmc_host_disable(host->mmc); + clk_disable(host->fclk); clk_disable(host->iclk); clk_put(host->fclk); clk_put(host->iclk); - if (host->got_dbclk) { + if (host->dbclk_enabled) { clk_disable(host->dbclk); clk_put(host->dbclk); } @@ -1895,51 +1216,36 @@ static int omap_hsmmc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) +static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state) { int ret = 0; - struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + struct mmc_omap_host *host = platform_get_drvdata(pdev); if (host && host->suspended) return 0; if (host) { - host->suspended = 1; - if (host->pdata->suspend) { - ret = host->pdata->suspend(&pdev->dev, - host->slot_id); - if (ret) { - dev_dbg(mmc_dev(host->mmc), - "Unable to handle MMC board" - " level suspend\n"); - host->suspended = 0; - return ret; - } - } - cancel_work_sync(&host->mmc_carddetect_work); - mmc_host_enable(host->mmc); ret = mmc_suspend_host(host->mmc, state); if (ret == 0) { + host->suspended = 1; + OMAP_HSMMC_WRITE(host->base, ISE, 0); OMAP_HSMMC_WRITE(host->base, IE, 0); - - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); - mmc_host_disable(host->mmc); - clk_disable(host->iclk); - if (host->got_dbclk) - clk_disable(host->dbclk); - } else { - host->suspended = 0; - if (host->pdata->resume) { - ret = host->pdata->resume(&pdev->dev, - host->slot_id); + if (host->pdata->suspend) { + ret = host->pdata->suspend(&pdev->dev, + host->slot_id); if (ret) dev_dbg(mmc_dev(host->mmc), - "Unmask interrupt failed\n"); + "Unable to handle MMC board" + " level suspend\n"); } - mmc_host_disable(host->mmc); + + OMAP_HSMMC_WRITE(host->base, HCTL, + OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); + clk_disable(host->fclk); + clk_disable(host->iclk); + clk_disable(host->dbclk); } } @@ -1947,28 +1253,32 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) } /* Routine to resume the MMC device */ -static int omap_hsmmc_resume(struct platform_device *pdev) +static int omap_mmc_resume(struct platform_device *pdev) { int ret = 0; - struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + struct mmc_omap_host *host = platform_get_drvdata(pdev); if (host && !host->suspended) return 0; if (host) { - ret = clk_enable(host->iclk); + + ret = clk_enable(host->fclk); if (ret) goto clk_en_err; - if (mmc_host_enable(host->mmc) != 0) { - clk_disable(host->iclk); + ret = clk_enable(host->iclk); + if (ret) { + clk_disable(host->fclk); + clk_put(host->fclk); goto clk_en_err; } - if (host->got_dbclk) - clk_enable(host->dbclk); + if (clk_enable(host->dbclk) != 0) + dev_dbg(mmc_dev(host->mmc), + "Enabling debounce clk failed\n"); - omap_hsmmc_conf_bus_power(host); + omap_hsmmc_init(host); if (host->pdata->resume) { ret = host->pdata->resume(&pdev->dev, host->slot_id); @@ -1977,14 +1287,10 @@ static int omap_hsmmc_resume(struct platform_device *pdev) "Unmask interrupt failed\n"); } - omap_hsmmc_protect_card(host); - /* Notify the core to resume the host */ ret = mmc_resume_host(host->mmc); if (ret == 0) host->suspended = 0; - - mmc_host_lazy_disable(host->mmc); } return ret; @@ -1996,34 +1302,35 @@ static int omap_hsmmc_resume(struct platform_device *pdev) } #else -#define omap_hsmmc_suspend NULL -#define omap_hsmmc_resume NULL +#define omap_mmc_suspend NULL +#define omap_mmc_resume NULL #endif -static struct platform_driver omap_hsmmc_driver = { - .remove = omap_hsmmc_remove, - .suspend = omap_hsmmc_suspend, - .resume = omap_hsmmc_resume, +static struct platform_driver omap_mmc_driver = { + .probe = omap_mmc_probe, + .remove = omap_mmc_remove, + .suspend = omap_mmc_suspend, + .resume = omap_mmc_resume, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, }; -static int __init omap_hsmmc_init(void) +static int __init omap_mmc_init(void) { /* Register the MMC driver */ - return platform_driver_register(&omap_hsmmc_driver); + return platform_driver_register(&omap_mmc_driver); } -static void __exit omap_hsmmc_cleanup(void) +static void __exit omap_mmc_cleanup(void) { /* Unregister MMC driver */ - platform_driver_unregister(&omap_hsmmc_driver); + platform_driver_unregister(&omap_mmc_driver); } -module_init(omap_hsmmc_init); -module_exit(omap_hsmmc_cleanup); +module_init(omap_mmc_init); +module_exit(omap_mmc_cleanup); MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mmc/host/sdhci-of.c b/trunk/drivers/mmc/host/sdhci-of.c index 01ab916c2802..1e8aa590bb39 100644 --- a/trunk/drivers/mmc/host/sdhci-of.c +++ b/trunk/drivers/mmc/host/sdhci-of.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "sdhci.h" struct sdhci_of_data { @@ -49,8 +48,6 @@ struct sdhci_of_host { #define ESDHC_CLOCK_HCKEN 0x00000002 #define ESDHC_CLOCK_IPGEN 0x00000001 -#define ESDHC_HOST_CONTROL_RES 0x05 - static u32 esdhc_readl(struct sdhci_host *host, int reg) { return in_be32(host->ioaddr + reg); @@ -112,17 +109,13 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) int base = reg & ~0x3; int shift = (reg & 0x3) * 8; - /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ - if (reg == SDHCI_HOST_CONTROL) - val &= ~ESDHC_HOST_CONTROL_RES; - clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); } static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) { + int div; int pre_div = 2; - int div = 1; clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); @@ -130,17 +123,19 @@ static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 0) goto out; - while (host->max_clk / pre_div / 16 > clock && pre_div < 256) - pre_div *= 2; - - while (host->max_clk / pre_div / div > clock && div < 16) - div++; + if (host->max_clk / 16 > clock) { + for (; pre_div < 256; pre_div *= 2) { + if (host->max_clk / pre_div < clock * 16) + break; + } + } - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", - clock, host->max_clk / pre_div / div); + for (div = 1; div <= 16; div++) { + if (host->max_clk / (div * pre_div) <= clock) + break; + } pre_div >>= 1; - div--; setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | @@ -170,12 +165,19 @@ static unsigned int esdhc_get_min_clock(struct sdhci_host *host) return of_host->clock / 256 / 16; } +static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock / 1000; +} + static struct sdhci_of_data sdhci_esdhc = { .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_INVERTED_WRITE_PROTECT | SDHCI_QUIRK_NO_BUSY_IRQ | SDHCI_QUIRK_NONSTANDARD_CLOCK | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_PIO_NEEDS_DELAY | SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | SDHCI_QUIRK_NO_CARD_NO_RESET, @@ -190,6 +192,7 @@ static struct sdhci_of_data sdhci_esdhc = { .enable_dma = esdhc_enable_dma, .get_max_clock = esdhc_get_max_clock, .get_min_clock = esdhc_get_min_clock, + .get_timeout_clock = esdhc_get_timeout_clock, }, }; @@ -216,15 +219,6 @@ static int sdhci_of_resume(struct of_device *ofdev) #endif -static bool __devinit sdhci_of_wp_inverted(struct device_node *np) -{ - if (of_get_property(np, "sdhci,wp-inverted", NULL)) - return true; - - /* Old device trees don't have the wp-inverted property. */ - return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds); -} - static int __devinit sdhci_of_probe(struct of_device *ofdev, const struct of_device_id *match) { @@ -267,9 +261,6 @@ static int __devinit sdhci_of_probe(struct of_device *ofdev, if (of_get_property(np, "sdhci,1-bit-only", NULL)) host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; - if (sdhci_of_wp_inverted(np)) - host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; - clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) of_host->clock = *clk; diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index e0356644d1aa..2f15cc17d887 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -83,8 +83,7 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; - if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || - chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) + if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; return 0; @@ -396,7 +395,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && - (host->flags & SDHCI_USE_SDMA)) { + (host->flags & SDHCI_USE_DMA)) { dev_warn(&pdev->dev, "Will use DMA mode even though HW " "doesn't fully claim to support it.\n"); } diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index c279fbc4c2e5..fc96f8cb9c0b 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -591,9 +591,6 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) target_timeout = data->timeout_ns / 1000 + data->timeout_clks / host->clock; - if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) - host->timeout_clk = host->clock / 1000; - /* * Figure out needed cycles. * We do this in steps in order to fit inside a 32 bit int. @@ -655,7 +652,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) count = sdhci_calc_timeout(host, data); sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) + if (host->flags & SDHCI_USE_DMA) host->flags |= SDHCI_REQ_USE_DMA; /* @@ -994,8 +991,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) clk |= SDHCI_CLOCK_INT_EN; sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - /* Wait max 20 ms */ - timeout = 20; + /* Wait max 10 ms */ + timeout = 10; while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) & SDHCI_CLOCK_INT_STABLE)) { if (timeout == 0) { @@ -1600,7 +1597,7 @@ int sdhci_resume_host(struct sdhci_host *host) { int ret; - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { + if (host->flags & SDHCI_USE_DMA) { if (host->ops->enable_dma) host->ops->enable_dma(host); } @@ -1681,20 +1678,23 @@ int sdhci_add_host(struct sdhci_host *host) caps = sdhci_readl(host, SDHCI_CAPABILITIES); if (host->quirks & SDHCI_QUIRK_FORCE_DMA) - host->flags |= SDHCI_USE_SDMA; - else if (!(caps & SDHCI_CAN_DO_SDMA)) - DBG("Controller doesn't have SDMA capability\n"); + host->flags |= SDHCI_USE_DMA; + else if (!(caps & SDHCI_CAN_DO_DMA)) + DBG("Controller doesn't have DMA capability\n"); else - host->flags |= SDHCI_USE_SDMA; + host->flags |= SDHCI_USE_DMA; if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && - (host->flags & SDHCI_USE_SDMA)) { + (host->flags & SDHCI_USE_DMA)) { DBG("Disabling DMA as it is marked broken\n"); - host->flags &= ~SDHCI_USE_SDMA; + host->flags &= ~SDHCI_USE_DMA; } - if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2)) - host->flags |= SDHCI_USE_ADMA; + if (host->flags & SDHCI_USE_DMA) { + if ((host->version >= SDHCI_SPEC_200) && + (caps & SDHCI_CAN_DO_ADMA2)) + host->flags |= SDHCI_USE_ADMA; + } if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && (host->flags & SDHCI_USE_ADMA)) { @@ -1702,14 +1702,13 @@ int sdhci_add_host(struct sdhci_host *host) host->flags &= ~SDHCI_USE_ADMA; } - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { + if (host->flags & SDHCI_USE_DMA) { if (host->ops->enable_dma) { if (host->ops->enable_dma(host)) { printk(KERN_WARNING "%s: No suitable DMA " "available. Falling back to PIO.\n", mmc_hostname(mmc)); - host->flags &= - ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA); + host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA); } } } @@ -1737,7 +1736,7 @@ int sdhci_add_host(struct sdhci_host *host) * mask, but PIO does not need the hw shim so we set a new * mask here in that case. */ - if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) { + if (!(host->flags & SDHCI_USE_DMA)) { host->dma_mask = DMA_BIT_MASK(64); mmc_dev(host->mmc)->dma_mask = &host->dma_mask; } @@ -1758,15 +1757,13 @@ int sdhci_add_host(struct sdhci_host *host) host->timeout_clk = (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; if (host->timeout_clk == 0) { - if (host->ops->get_timeout_clock) { - host->timeout_clk = host->ops->get_timeout_clock(host); - } else if (!(host->quirks & - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { + if (!host->ops->get_timeout_clock) { printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " "frequency.\n", mmc_hostname(mmc)); return -ENODEV; } + host->timeout_clk = host->ops->get_timeout_clock(host); } if (caps & SDHCI_TIMEOUT_CLK_UNIT) host->timeout_clk *= 1000; @@ -1775,8 +1772,7 @@ int sdhci_add_host(struct sdhci_host *host) * Set host parameters. */ mmc->ops = &sdhci_ops; - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK && - host->ops->set_clock && host->ops->get_min_clock) + if (host->ops->get_min_clock) mmc->f_min = host->ops->get_min_clock(host); else mmc->f_min = host->max_clk / 256; @@ -1814,7 +1810,7 @@ int sdhci_add_host(struct sdhci_host *host) */ if (host->flags & SDHCI_USE_ADMA) mmc->max_hw_segs = 128; - else if (host->flags & SDHCI_USE_SDMA) + else if (host->flags & SDHCI_USE_DMA) mmc->max_hw_segs = 1; else /* PIO */ mmc->max_hw_segs = 128; @@ -1897,10 +1893,10 @@ int sdhci_add_host(struct sdhci_host *host) mmc_add_host(mmc); - printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n", + printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), - (host->flags & SDHCI_USE_ADMA) ? "ADMA" : - (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); + (host->flags & SDHCI_USE_ADMA)?"A":"", + (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); sdhci_enable_card_detection(host); diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index ce5f1d73dc04..c77e9ff30223 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -143,7 +143,7 @@ #define SDHCI_CAN_DO_ADMA2 0x00080000 #define SDHCI_CAN_DO_ADMA1 0x00100000 #define SDHCI_CAN_DO_HISPD 0x00200000 -#define SDHCI_CAN_DO_SDMA 0x00400000 +#define SDHCI_CAN_DO_DMA 0x00400000 #define SDHCI_CAN_VDD_330 0x01000000 #define SDHCI_CAN_VDD_300 0x02000000 #define SDHCI_CAN_VDD_180 0x04000000 @@ -232,8 +232,6 @@ struct sdhci_host { #define SDHCI_QUIRK_FORCE_1_BIT_DATA (1<<22) /* Controller needs 10ms delay between applying power and clock */ #define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) -/* Controller uses SDCLK instead of TMCLK for data timeouts */ -#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ @@ -252,7 +250,7 @@ struct sdhci_host { spinlock_t lock; /* Mutex */ int flags; /* Host attributes */ -#define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */ +#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ #define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index 211c27acd01e..43976aa4dbb1 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -966,4 +966,3 @@ module_exit(dataflash_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Andrew Victor, David Brownell"); MODULE_DESCRIPTION("MTD DataFlash driver"); -MODULE_ALIAS("spi:mtd_dataflash"); diff --git a/trunk/drivers/net/ehea/ehea_qmr.c b/trunk/drivers/net/ehea/ehea_qmr.c index bc7c5b7abb88..3747457f5e69 100644 --- a/trunk/drivers/net/ehea/ehea_qmr.c +++ b/trunk/drivers/net/ehea/ehea_qmr.c @@ -751,7 +751,7 @@ int ehea_create_busmap(void) mutex_lock(&ehea_busmap_mutex); ehea_mr_len = 0; - ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL, + ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL, ehea_create_busmap_callback); mutex_unlock(&ehea_busmap_mutex); return ret; diff --git a/trunk/drivers/net/enc28j60.c b/trunk/drivers/net/enc28j60.c index 66813c91a720..117fc6c12e34 100644 --- a/trunk/drivers/net/enc28j60.c +++ b/trunk/drivers/net/enc28j60.c @@ -1666,4 +1666,3 @@ MODULE_AUTHOR("Claudio Lanconelli "); MODULE_LICENSE("GPL"); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., ffff=all)"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/trunk/drivers/net/ks8851.c b/trunk/drivers/net/ks8851.c index 237835864357..547ac7c7479c 100644 --- a/trunk/drivers/net/ks8851.c +++ b/trunk/drivers/net/ks8851.c @@ -1321,4 +1321,3 @@ MODULE_LICENSE("GPL"); module_param_named(message, msg_enable, int, 0); MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); -MODULE_ALIAS("spi:ks8851"); diff --git a/trunk/drivers/net/niu.c b/trunk/drivers/net/niu.c index f9364d0678f2..76cc2614f480 100644 --- a/trunk/drivers/net/niu.c +++ b/trunk/drivers/net/niu.c @@ -5615,7 +5615,7 @@ static void niu_init_tx_mac(struct niu *np) /* The XMAC_MIN register only accepts values for TX min which * have the low 3 bits cleared. */ - BUG_ON(min & 0x7); + BUILD_BUG_ON(min & 0x7); if (np->flags & NIU_FLAGS_XMAC) niu_init_tx_xmac(np, min, max); diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 5c498d2b043f..32266fb89c20 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -321,7 +320,7 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp) skb_queue_head(&vi->recv, skb); err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); - if (err < 0) { + if (err) { skb_unlink(skb, &vi->recv); trim_pages(vi, skb); kfree_skb(skb); @@ -374,7 +373,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp) skb_queue_head(&vi->recv, skb); err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb); - if (err < 0) { + if (err) { skb_unlink(skb, &vi->recv); kfree_skb(skb); break; @@ -528,7 +527,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); - if (err >= 0 && !vi->free_in_tasklet) + if (!err && !vi->free_in_tasklet) mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); return err; @@ -539,7 +538,7 @@ static void xmit_tasklet(unsigned long data) struct virtnet_info *vi = (void *)data; netif_tx_lock_bh(vi->dev); - if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) >= 0) { + if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) { vi->svq->vq_ops->kick(vi->svq); vi->last_xmit_skb = NULL; } @@ -558,7 +557,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) /* If we has a buffer left over from last time, send it now. */ if (unlikely(vi->last_xmit_skb) && - xmit_skb(vi, vi->last_xmit_skb) < 0) + xmit_skb(vi, vi->last_xmit_skb) != 0) goto stop_queue; vi->last_xmit_skb = NULL; @@ -566,7 +565,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) /* Put new one in send queue and do transmit */ if (likely(skb)) { __skb_queue_head(&vi->send, skb); - if (xmit_skb(vi, skb) < 0) { + if (xmit_skb(vi, skb) != 0) { vi->last_xmit_skb = skb; skb = NULL; goto stop_queue; @@ -669,7 +668,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, sg_set_buf(&sg[i + 1], sg_virt(s), s->length); sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); - BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) < 0); + BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi)); vi->cvq->vq_ops->kick(vi->cvq); diff --git a/trunk/drivers/net/wireless/libertas/if_spi.c b/trunk/drivers/net/wireless/libertas/if_spi.c index cb8be8d7abc1..446e327180f8 100644 --- a/trunk/drivers/net/wireless/libertas/if_spi.c +++ b/trunk/drivers/net/wireless/libertas/if_spi.c @@ -1222,4 +1222,3 @@ MODULE_DESCRIPTION("Libertas SPI WLAN Driver"); MODULE_AUTHOR("Andrey Yurovsky , " "Colin McCabe "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:libertas_spi"); diff --git a/trunk/drivers/net/wireless/p54/p54spi.c b/trunk/drivers/net/wireless/p54/p54spi.c index afd26bf06649..05458d9249ce 100644 --- a/trunk/drivers/net/wireless/p54/p54spi.c +++ b/trunk/drivers/net/wireless/p54/p54spi.c @@ -731,4 +731,3 @@ module_exit(p54spi_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Lamparter "); -MODULE_ALIAS("spi:cx3110x"); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c index 1103256ad989..5809ef5b18f8 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c @@ -1426,4 +1426,3 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw); MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kalle Valo "); -MODULE_ALIAS("spi:wl12xx"); diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index ddf224d456b2..69f85c07d17f 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -447,6 +447,7 @@ struct of_modalias_table { static struct of_modalias_table of_modalias_table[] = { { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, { "mmc-spi-slot", "mmc_spi" }, + { "stm,m25p40", "m25p80" }, }; /** diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 3c20dae43ce2..73771b09fbd3 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -378,15 +378,6 @@ config RTC_DRV_DS3234 This driver can also be built as a module. If so, the module will be called rtc-ds3234. -config RTC_DRV_PCF2123 - tristate "NXP PCF2123" - help - If you say yes here you get support for the NXP PCF2123 - RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-pcf2123. - endif # SPI_MASTER comment "Platform RTC drivers" @@ -509,17 +500,6 @@ config RTC_DRV_M48T59 This driver can also be built as a module, if so, the module will be called "rtc-m48t59". -config RTC_MXC - tristate "Freescale MXC Real Time Clock" - depends on ARCH_MXC - depends on RTC_CLASS - help - If you say yes here you get support for the Freescale MXC - RTC module. - - This driver can also be built as a module, if so, the module - will be called "rtc-mxc". - config RTC_DRV_BQ4802 tristate "TI BQ4802" help @@ -798,33 +778,4 @@ config RTC_DRV_PS3 This driver can also be built as a module. If so, the module will be called rtc-ps3. -config RTC_DRV_COH901331 - tristate "ST-Ericsson COH 901 331 RTC" - depends on ARCH_U300 - help - If you say Y here you will get access to ST-Ericsson - COH 901 331 RTC clock found in some ST-Ericsson Mobile - Platforms. - - This driver can also be built as a module. If so, the module - will be called "rtc-coh901331". - - -config RTC_DRV_STMP - tristate "Freescale STMP3xxx RTC" - depends on ARCH_STMP3XXX - help - If you say yes here you will get support for the onboard - STMP3xxx RTC. - - This driver can also be built as a module. If so, the module - will be called rtc-stmp3xxx. - -config RTC_DRV_PCAP - tristate "PCAP RTC" - depends on EZX_PCAP - help - If you say Y here you will get support for the RTC found on - the PCAP2 ASIC used on some Motorola phones. - endif # RTC_CLASS diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index aa3fbd5517a1..5e152ffe5058 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -23,9 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o -obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o -obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o @@ -42,26 +40,24 @@ obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o -obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o -obj-$(CONFIG_RTC_MXC) += rtc-mxc.o +obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o +obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o +obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o -obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o -obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o -obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o -obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o +obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o @@ -73,10 +69,7 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o -obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o -obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o -obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o @@ -85,3 +78,5 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o +obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o +obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o diff --git a/trunk/drivers/rtc/rtc-at91rm9200.c b/trunk/drivers/rtc/rtc-at91rm9200.c index bc8bbca9a2e2..b5bf93706913 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.c +++ b/trunk/drivers/rtc/rtc-at91rm9200.c @@ -289,7 +289,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) AT91_RTC_CALEV); ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, - IRQF_SHARED, + IRQF_DISABLED | IRQF_SHARED, "at91_rtc", pdev); if (ret) { printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", @@ -340,7 +340,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) static u32 at91_rtc_imr; -static int at91_rtc_suspend(struct device *dev) +static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... @@ -348,7 +348,7 @@ static int at91_rtc_suspend(struct device *dev) at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(&pdev->dev)) enable_irq_wake(AT91_ID_SYS); else at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); @@ -356,34 +356,28 @@ static int at91_rtc_suspend(struct device *dev) return 0; } -static int at91_rtc_resume(struct device *dev) +static int at91_rtc_resume(struct platform_device *pdev) { if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(&pdev->dev)) disable_irq_wake(AT91_ID_SYS); else at91_sys_write(AT91_RTC_IER, at91_rtc_imr); } return 0; } - -static const struct dev_pm_ops at91_rtc_pm = { - .suspend = at91_rtc_suspend, - .resume = at91_rtc_resume, -}; - -#define at91_rtc_pm_ptr &at91_rtc_pm - #else -#define at91_rtc_pm_ptr NULL +#define at91_rtc_suspend NULL +#define at91_rtc_resume NULL #endif static struct platform_driver at91_rtc_driver = { .remove = __exit_p(at91_rtc_remove), + .suspend = at91_rtc_suspend, + .resume = at91_rtc_resume, .driver = { .name = "at91_rtc", .owner = THIS_MODULE, - .pm = at91_rtc_pm_ptr, }, }; diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c index b11485b9f21c..a118eb0f1e67 100644 --- a/trunk/drivers/rtc/rtc-bfin.c +++ b/trunk/drivers/rtc/rtc-bfin.c @@ -383,7 +383,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) } /* Grab the IRQ and init the hardware */ - ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, 0, pdev->name, dev); + ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); if (unlikely(ret)) goto err_reg; /* sometimes the bootloader touched things, but the write complete was not diff --git a/trunk/drivers/rtc/rtc-coh901331.c b/trunk/drivers/rtc/rtc-coh901331.c deleted file mode 100644 index 7fe1fa26c52c..000000000000 --- a/trunk/drivers/rtc/rtc-coh901331.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC. - * Author: Linus Walleij - * Based on rtc-pl031.c by Deepak Saxena - * Copyright 2006 (c) MontaVista Software, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Registers in the COH 901 331 - */ -/* Alarm value 32bit (R/W) */ -#define COH901331_ALARM 0x00U -/* Used to set current time 32bit (R/W) */ -#define COH901331_SET_TIME 0x04U -/* Indication if current time is valid 32bit (R/-) */ -#define COH901331_VALID 0x08U -/* Read the current time 32bit (R/-) */ -#define COH901331_CUR_TIME 0x0cU -/* Event register for the "alarm" interrupt */ -#define COH901331_IRQ_EVENT 0x10U -/* Mask register for the "alarm" interrupt */ -#define COH901331_IRQ_MASK 0x14U -/* Force register for the "alarm" interrupt */ -#define COH901331_IRQ_FORCE 0x18U - -/* - * Reference to RTC block clock - * Notice that the frequent clk_enable()/clk_disable() on this - * clock is mainly to be able to turn on/off other clocks in the - * hierarchy as needed, the RTC clock is always on anyway. - */ -struct coh901331_port { - struct rtc_device *rtc; - struct clk *clk; - u32 phybase; - u32 physize; - void __iomem *virtbase; - int irq; -#ifdef CONFIG_PM - u32 irqmaskstore; -#endif -}; - -static irqreturn_t coh901331_interrupt(int irq, void *data) -{ - struct coh901331_port *rtap = data; - - clk_enable(rtap->clk); - /* Ack IRQ */ - writel(1, rtap->virtbase + COH901331_IRQ_EVENT); - clk_disable(rtap->clk); - /* Set alarm flag */ - rtc_update_irq(rtap->rtc, 1, RTC_AF); - - return IRQ_HANDLED; -} - -static int coh901331_read_time(struct device *dev, struct rtc_time *tm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - /* Check if the time is valid */ - if (readl(rtap->virtbase + COH901331_VALID)) { - rtc_time_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); - clk_disable(rtap->clk); - return rtc_valid_tm(tm); - } - clk_disable(rtap->clk); - return -EINVAL; -} - -static int coh901331_set_mmss(struct device *dev, unsigned long secs) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - writel(secs, rtap->virtbase + COH901331_SET_TIME); - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - rtc_time_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); - alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U; - alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U; - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - unsigned long time; - - rtc_tm_to_time(&alarm->time, &time); - clk_enable(rtap->clk); - writel(time, rtap->virtbase + COH901331_ALARM); - writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - - return 0; -} - -static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct coh901331_port *rtap = dev_get_drvdata(dev); - - clk_enable(rtap->clk); - if (enabled) - writel(1, rtap->virtbase + COH901331_IRQ_MASK); - else - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); -} - -static struct rtc_class_ops coh901331_ops = { - .read_time = coh901331_read_time, - .set_mmss = coh901331_set_mmss, - .read_alarm = coh901331_read_alarm, - .set_alarm = coh901331_set_alarm, - .alarm_irq_enable = coh901331_alarm_irq_enable, -}; - -static int __exit coh901331_remove(struct platform_device *pdev) -{ - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - - if (rtap) { - free_irq(rtap->irq, rtap); - rtc_device_unregister(rtap->rtc); - clk_put(rtap->clk); - iounmap(rtap->virtbase); - release_mem_region(rtap->phybase, rtap->physize); - platform_set_drvdata(pdev, NULL); - kfree(rtap); - } - - return 0; -} - - -static int __init coh901331_probe(struct platform_device *pdev) -{ - int ret; - struct coh901331_port *rtap; - struct resource *res; - - rtap = kzalloc(sizeof(struct coh901331_port), GFP_KERNEL); - if (!rtap) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto out_no_resource; - } - rtap->phybase = res->start; - rtap->physize = resource_size(res); - - if (request_mem_region(rtap->phybase, rtap->physize, - "rtc-coh901331") == NULL) { - ret = -EBUSY; - goto out_no_memregion; - } - - rtap->virtbase = ioremap(rtap->phybase, rtap->physize); - if (!rtap->virtbase) { - ret = -ENOMEM; - goto out_no_remap; - } - - rtap->irq = platform_get_irq(pdev, 0); - if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED, - "RTC COH 901 331 Alarm", rtap)) { - ret = -EIO; - goto out_no_irq; - } - - rtap->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(rtap->clk)) { - ret = PTR_ERR(rtap->clk); - dev_err(&pdev->dev, "could not get clock\n"); - goto out_no_clk; - } - - /* We enable/disable the clock only to assure it works */ - ret = clk_enable(rtap->clk); - if (ret) { - dev_err(&pdev->dev, "could not enable clock\n"); - goto out_no_clk_enable; - } - clk_disable(rtap->clk); - - rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, - THIS_MODULE); - if (IS_ERR(rtap->rtc)) { - ret = PTR_ERR(rtap->rtc); - goto out_no_rtc; - } - - platform_set_drvdata(pdev, rtap); - - return 0; - - out_no_rtc: - out_no_clk_enable: - clk_put(rtap->clk); - out_no_clk: - free_irq(rtap->irq, rtap); - out_no_irq: - iounmap(rtap->virtbase); - out_no_remap: - platform_set_drvdata(pdev, NULL); - out_no_memregion: - release_mem_region(rtap->phybase, SZ_4K); - out_no_resource: - kfree(rtap); - return ret; -} - -#ifdef CONFIG_PM -static int coh901331_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - - /* - * If this RTC alarm will be used for waking the system up, - * don't disable it of course. Else we just disable the alarm - * and await suspension. - */ - if (device_may_wakeup(&pdev->dev)) { - enable_irq_wake(rtap->irq); - } else { - clk_enable(rtap->clk); - rtap->irqmaskstore = readl(rtap->virtbase + COH901331_IRQ_MASK); - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - } - return 0; -} - -static int coh901331_resume(struct platform_device *pdev) -{ - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - - if (device_may_wakeup(&pdev->dev)) - disable_irq_wake(rtap->irq); - else - clk_enable(rtap->clk); - writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); - return 0; -} -#else -#define coh901331_suspend NULL -#define coh901331_resume NULL -#endif - -static void coh901331_shutdown(struct platform_device *pdev) -{ - struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - - clk_enable(rtap->clk); - writel(0, rtap->virtbase + COH901331_IRQ_MASK); - clk_disable(rtap->clk); -} - -static struct platform_driver coh901331_driver = { - .driver = { - .name = "rtc-coh901331", - .owner = THIS_MODULE, - }, - .remove = __exit_p(coh901331_remove), - .suspend = coh901331_suspend, - .resume = coh901331_resume, - .shutdown = coh901331_shutdown, -}; - -static int __init coh901331_init(void) -{ - return platform_driver_probe(&coh901331_driver, coh901331_probe); -} - -static void __exit coh901331_exit(void) -{ - platform_driver_unregister(&coh901331_driver); -} - -module_init(coh901331_init); -module_exit(coh901331_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST-Ericsson AB COH 901 331 RTC Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-ds1305.c b/trunk/drivers/rtc/rtc-ds1305.c index 2736b11a1b1e..8f410e59d9f5 100644 --- a/trunk/drivers/rtc/rtc-ds1305.c +++ b/trunk/drivers/rtc/rtc-ds1305.c @@ -841,4 +841,3 @@ module_exit(ds1305_exit); MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:rtc-ds1305"); diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index eb99ee4fa0f5..47a93c022d91 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -896,7 +896,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, return 0; exit_irq: - rtc_device_unregister(ds1307->rtc); + if (ds1307->rtc) + rtc_device_unregister(ds1307->rtc); exit_free: kfree(ds1307); return err; diff --git a/trunk/drivers/rtc/rtc-ds1390.c b/trunk/drivers/rtc/rtc-ds1390.c index cdb705057091..e01b955db077 100644 --- a/trunk/drivers/rtc/rtc-ds1390.c +++ b/trunk/drivers/rtc/rtc-ds1390.c @@ -189,4 +189,3 @@ module_exit(ds1390_exit); MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); MODULE_AUTHOR("Mark Jackson "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:rtc-ds1390"); diff --git a/trunk/drivers/rtc/rtc-ds3234.c b/trunk/drivers/rtc/rtc-ds3234.c index a774ca35b5f7..c51589ede5b7 100644 --- a/trunk/drivers/rtc/rtc-ds3234.c +++ b/trunk/drivers/rtc/rtc-ds3234.c @@ -188,4 +188,3 @@ module_exit(ds3234_exit); MODULE_DESCRIPTION("DS3234 SPI RTC driver"); MODULE_AUTHOR("Dennis Aberilla "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:ds3234"); diff --git a/trunk/drivers/rtc/rtc-ep93xx.c b/trunk/drivers/rtc/rtc-ep93xx.c index 9da02d108b73..551332e4ed02 100644 --- a/trunk/drivers/rtc/rtc-ep93xx.c +++ b/trunk/drivers/rtc/rtc-ep93xx.c @@ -128,16 +128,12 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - err = -ENXIO; - goto fail_free; - } + if (res == NULL) + return -ENXIO; res = request_mem_region(res->start, resource_size(res), pdev->name); - if (res == NULL) { - err = -EBUSY; - goto fail_free; - } + if (res == NULL) + return -EBUSY; ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res)); if (ep93xx_rtc->mmio_base == NULL) { @@ -173,8 +169,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) pdev->dev.platform_data = NULL; } release_mem_region(res->start, resource_size(res)); -fail_free: - kfree(ep93xx_rtc); return err; } diff --git a/trunk/drivers/rtc/rtc-m41t94.c b/trunk/drivers/rtc/rtc-m41t94.c index c8c97a4169d4..c3a18c58daf6 100644 --- a/trunk/drivers/rtc/rtc-m41t94.c +++ b/trunk/drivers/rtc/rtc-m41t94.c @@ -171,4 +171,3 @@ module_exit(m41t94_exit); MODULE_AUTHOR("Kim B. Heino "); MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:rtc-m41t94"); diff --git a/trunk/drivers/rtc/rtc-max6902.c b/trunk/drivers/rtc/rtc-max6902.c index 657403ebd54a..36a8ea9ed8ba 100644 --- a/trunk/drivers/rtc/rtc-max6902.c +++ b/trunk/drivers/rtc/rtc-max6902.c @@ -175,4 +175,3 @@ module_exit(max6902_exit); MODULE_DESCRIPTION ("max6902 spi RTC driver"); MODULE_AUTHOR ("Raphael Assenat"); MODULE_LICENSE ("GPL"); -MODULE_ALIAS("spi:rtc-max6902"); diff --git a/trunk/drivers/rtc/rtc-mxc.c b/trunk/drivers/rtc/rtc-mxc.c deleted file mode 100644 index 6bd5072d4eb7..000000000000 --- a/trunk/drivers/rtc/rtc-mxc.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include - -#include - -#define RTC_INPUT_CLK_32768HZ (0x00 << 5) -#define RTC_INPUT_CLK_32000HZ (0x01 << 5) -#define RTC_INPUT_CLK_38400HZ (0x02 << 5) - -#define RTC_SW_BIT (1 << 0) -#define RTC_ALM_BIT (1 << 2) -#define RTC_1HZ_BIT (1 << 4) -#define RTC_2HZ_BIT (1 << 7) -#define RTC_SAM0_BIT (1 << 8) -#define RTC_SAM1_BIT (1 << 9) -#define RTC_SAM2_BIT (1 << 10) -#define RTC_SAM3_BIT (1 << 11) -#define RTC_SAM4_BIT (1 << 12) -#define RTC_SAM5_BIT (1 << 13) -#define RTC_SAM6_BIT (1 << 14) -#define RTC_SAM7_BIT (1 << 15) -#define PIT_ALL_ON (RTC_2HZ_BIT | RTC_SAM0_BIT | RTC_SAM1_BIT | \ - RTC_SAM2_BIT | RTC_SAM3_BIT | RTC_SAM4_BIT | \ - RTC_SAM5_BIT | RTC_SAM6_BIT | RTC_SAM7_BIT) - -#define RTC_ENABLE_BIT (1 << 7) - -#define MAX_PIE_NUM 9 -#define MAX_PIE_FREQ 512 -static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = { - { 2, RTC_2HZ_BIT }, - { 4, RTC_SAM0_BIT }, - { 8, RTC_SAM1_BIT }, - { 16, RTC_SAM2_BIT }, - { 32, RTC_SAM3_BIT }, - { 64, RTC_SAM4_BIT }, - { 128, RTC_SAM5_BIT }, - { 256, RTC_SAM6_BIT }, - { MAX_PIE_FREQ, RTC_SAM7_BIT }, -}; - -/* Those are the bits from a classic RTC we want to mimic */ -#define RTC_IRQF 0x80 /* any of the following 3 is active */ -#define RTC_PF 0x40 /* Periodic interrupt */ -#define RTC_AF 0x20 /* Alarm interrupt */ -#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ - -#define MXC_RTC_TIME 0 -#define MXC_RTC_ALARM 1 - -#define RTC_HOURMIN 0x00 /* 32bit rtc hour/min counter reg */ -#define RTC_SECOND 0x04 /* 32bit rtc seconds counter reg */ -#define RTC_ALRM_HM 0x08 /* 32bit rtc alarm hour/min reg */ -#define RTC_ALRM_SEC 0x0C /* 32bit rtc alarm seconds reg */ -#define RTC_RTCCTL 0x10 /* 32bit rtc control reg */ -#define RTC_RTCISR 0x14 /* 32bit rtc interrupt status reg */ -#define RTC_RTCIENR 0x18 /* 32bit rtc interrupt enable reg */ -#define RTC_STPWCH 0x1C /* 32bit rtc stopwatch min reg */ -#define RTC_DAYR 0x20 /* 32bit rtc days counter reg */ -#define RTC_DAYALARM 0x24 /* 32bit rtc day alarm reg */ -#define RTC_TEST1 0x28 /* 32bit rtc test reg 1 */ -#define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */ -#define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */ - -struct rtc_plat_data { - struct rtc_device *rtc; - void __iomem *ioaddr; - int irq; - struct clk *clk; - unsigned int irqen; - int alrm_sec; - int alrm_min; - int alrm_hour; - int alrm_mday; - struct timespec mxc_rtc_delta; - struct rtc_time g_rtc_alarm; -}; - -/* - * This function is used to obtain the RTC time or the alarm value in - * second. - */ -static u32 get_alarm_or_time(struct device *dev, int time_alarm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - u32 day = 0, hr = 0, min = 0, sec = 0, hr_min = 0; - - switch (time_alarm) { - case MXC_RTC_TIME: - day = readw(ioaddr + RTC_DAYR); - hr_min = readw(ioaddr + RTC_HOURMIN); - sec = readw(ioaddr + RTC_SECOND); - break; - case MXC_RTC_ALARM: - day = readw(ioaddr + RTC_DAYALARM); - hr_min = readw(ioaddr + RTC_ALRM_HM) & 0xffff; - sec = readw(ioaddr + RTC_ALRM_SEC); - break; - } - - hr = hr_min >> 8; - min = hr_min & 0xff; - - return (((day * 24 + hr) * 60) + min) * 60 + sec; -} - -/* - * This function sets the RTC alarm value or the time value. - */ -static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time) -{ - u32 day, hr, min, sec, temp; - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - - day = time / 86400; - time -= day * 86400; - - /* time is within a day now */ - hr = time / 3600; - time -= hr * 3600; - - /* time is within an hour now */ - min = time / 60; - sec = time - min * 60; - - temp = (hr << 8) + min; - - switch (time_alarm) { - case MXC_RTC_TIME: - writew(day, ioaddr + RTC_DAYR); - writew(sec, ioaddr + RTC_SECOND); - writew(temp, ioaddr + RTC_HOURMIN); - break; - case MXC_RTC_ALARM: - writew(day, ioaddr + RTC_DAYALARM); - writew(sec, ioaddr + RTC_ALRM_SEC); - writew(temp, ioaddr + RTC_ALRM_HM); - break; - } -} - -/* - * This function updates the RTC alarm registers and then clears all the - * interrupt status bits. - */ -static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) -{ - struct rtc_time alarm_tm, now_tm; - unsigned long now, time; - int ret; - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - - now = get_alarm_or_time(dev, MXC_RTC_TIME); - rtc_time_to_tm(now, &now_tm); - alarm_tm.tm_year = now_tm.tm_year; - alarm_tm.tm_mon = now_tm.tm_mon; - alarm_tm.tm_mday = now_tm.tm_mday; - alarm_tm.tm_hour = alrm->tm_hour; - alarm_tm.tm_min = alrm->tm_min; - alarm_tm.tm_sec = alrm->tm_sec; - rtc_tm_to_time(&now_tm, &now); - rtc_tm_to_time(&alarm_tm, &time); - - if (time < now) { - time += 60 * 60 * 24; - rtc_time_to_tm(time, &alarm_tm); - } - - ret = rtc_tm_to_time(&alarm_tm, &time); - - /* clear all the interrupt status bits */ - writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR); - set_alarm_or_time(dev, MXC_RTC_ALARM, time); - - return ret; -} - -/* This function is the RTC interrupt service routine. */ -static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) -{ - struct platform_device *pdev = dev_id; - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - u32 status; - u32 events = 0; - - spin_lock_irq(&pdata->rtc->irq_lock); - status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); - /* clear interrupt sources */ - writew(status, ioaddr + RTC_RTCISR); - - /* clear alarm interrupt if it has occurred */ - if (status & RTC_ALM_BIT) - status &= ~RTC_ALM_BIT; - - /* update irq data & counter */ - if (status & RTC_ALM_BIT) - events |= (RTC_AF | RTC_IRQF); - - if (status & RTC_1HZ_BIT) - events |= (RTC_UF | RTC_IRQF); - - if (status & PIT_ALL_ON) - events |= (RTC_PF | RTC_IRQF); - - if ((status & RTC_ALM_BIT) && rtc_valid_tm(&pdata->g_rtc_alarm)) - rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm); - - rtc_update_irq(pdata->rtc, 1, events); - spin_unlock_irq(&pdata->rtc->irq_lock); - - return IRQ_HANDLED; -} - -/* - * Clear all interrupts and release the IRQ - */ -static void mxc_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - - spin_lock_irq(&pdata->rtc->irq_lock); - - /* Disable all rtc interrupts */ - writew(0, ioaddr + RTC_RTCIENR); - - /* Clear all interrupt status */ - writew(0xffffffff, ioaddr + RTC_RTCISR); - - spin_unlock_irq(&pdata->rtc->irq_lock); -} - -static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit, - unsigned int enabled) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - u32 reg; - - spin_lock_irq(&pdata->rtc->irq_lock); - reg = readw(ioaddr + RTC_RTCIENR); - - if (enabled) - reg |= bit; - else - reg &= ~bit; - - writew(reg, ioaddr + RTC_RTCIENR); - spin_unlock_irq(&pdata->rtc->irq_lock); -} - -static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled); - return 0; -} - -static int mxc_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - mxc_rtc_irq_enable(dev, RTC_1HZ_BIT, enabled); - return 0; -} - -/* - * This function reads the current RTC time into tm in Gregorian date. - */ -static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - u32 val; - - /* Avoid roll-over from reading the different registers */ - do { - val = get_alarm_or_time(dev, MXC_RTC_TIME); - } while (val != get_alarm_or_time(dev, MXC_RTC_TIME)); - - rtc_time_to_tm(val, tm); - - return 0; -} - -/* - * This function sets the internal RTC time based on tm in Gregorian date. - */ -static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) -{ - /* Avoid roll-over from reading the different registers */ - do { - set_alarm_or_time(dev, MXC_RTC_TIME, time); - } while (time != get_alarm_or_time(dev, MXC_RTC_TIME)); - - return 0; -} - -/* - * This function reads the current alarm value into the passed in 'alrm' - * argument. It updates the alrm's pending field value based on the whether - * an alarm interrupt occurs or not. - */ -static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - - rtc_time_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time); - alrm->pending = ((readw(ioaddr + RTC_RTCISR) & RTC_ALM_BIT)) ? 1 : 0; - - return 0; -} - -/* - * This function sets the RTC alarm based on passed in alrm. - */ -static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - int ret; - - if (rtc_valid_tm(&alrm->time)) { - if (alrm->time.tm_sec > 59 || - alrm->time.tm_hour > 23 || - alrm->time.tm_min > 59) - return -EINVAL; - - ret = rtc_update_alarm(dev, &alrm->time); - } else { - ret = rtc_valid_tm(&alrm->time); - if (ret) - return ret; - - ret = rtc_update_alarm(dev, &alrm->time); - } - - if (ret) - return ret; - - memcpy(&pdata->g_rtc_alarm, &alrm->time, sizeof(struct rtc_time)); - mxc_rtc_irq_enable(dev, RTC_ALM_BIT, alrm->enabled); - - return 0; -} - -/* RTC layer */ -static struct rtc_class_ops mxc_rtc_ops = { - .release = mxc_rtc_release, - .read_time = mxc_rtc_read_time, - .set_mmss = mxc_rtc_set_mmss, - .read_alarm = mxc_rtc_read_alarm, - .set_alarm = mxc_rtc_set_alarm, - .alarm_irq_enable = mxc_rtc_alarm_irq_enable, - .update_irq_enable = mxc_rtc_update_irq_enable, -}; - -static int __init mxc_rtc_probe(struct platform_device *pdev) -{ - struct clk *clk; - struct resource *res; - struct rtc_device *rtc; - struct rtc_plat_data *pdata = NULL; - u32 reg; - int ret, rate; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - pdata->ioaddr = ioremap(res->start, resource_size(res)); - - clk = clk_get(&pdev->dev, "ckil"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - rate = clk_get_rate(clk); - clk_put(clk); - - if (rate == 32768) - reg = RTC_INPUT_CLK_32768HZ; - else if (rate == 32000) - reg = RTC_INPUT_CLK_32000HZ; - else if (rate == 38400) - reg = RTC_INPUT_CLK_38400HZ; - else { - dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", - clk_get_rate(clk)); - ret = -EINVAL; - goto exit_free_pdata; - } - - reg |= RTC_ENABLE_BIT; - writew(reg, (pdata->ioaddr + RTC_RTCCTL)); - if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { - dev_err(&pdev->dev, "hardware module can't be enabled!\n"); - ret = -EIO; - goto exit_free_pdata; - } - - pdata->clk = clk_get(&pdev->dev, "rtc"); - if (IS_ERR(pdata->clk)) { - dev_err(&pdev->dev, "unable to get clock!\n"); - ret = PTR_ERR(pdata->clk); - goto exit_free_pdata; - } - - clk_enable(pdata->clk); - - rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto exit_put_clk; - } - - pdata->rtc = rtc; - platform_set_drvdata(pdev, pdata); - - /* Configure and enable the RTC */ - pdata->irq = platform_get_irq(pdev, 0); - - if (pdata->irq >= 0 && - request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED, - pdev->name, pdev) < 0) { - dev_warn(&pdev->dev, "interrupt not available.\n"); - pdata->irq = -1; - } - - return 0; - -exit_put_clk: - clk_put(pdata->clk); - -exit_free_pdata: - kfree(pdata); - - return ret; -} - -static int __exit mxc_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - rtc_device_unregister(pdata->rtc); - - if (pdata->irq >= 0) - free_irq(pdata->irq, pdev); - - clk_disable(pdata->clk); - clk_put(pdata->clk); - kfree(pdata); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver mxc_rtc_driver = { - .driver = { - .name = "mxc_rtc", - .owner = THIS_MODULE, - }, - .remove = __exit_p(mxc_rtc_remove), -}; - -static int __init mxc_rtc_init(void) -{ - return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe); -} - -static void __exit mxc_rtc_exit(void) -{ - platform_driver_unregister(&mxc_rtc_driver); -} - -module_init(mxc_rtc_init); -module_exit(mxc_rtc_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("RTC driver for Freescale MXC"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/rtc/rtc-pcap.c b/trunk/drivers/rtc/rtc-pcap.c deleted file mode 100644 index a99c28992d21..000000000000 --- a/trunk/drivers/rtc/rtc-pcap.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * pcap rtc code for Motorola EZX phones - * - * Copyright (c) 2008 guiming zhuo - * Copyright (c) 2009 Daniel Ribeiro - * - * Based on Motorola's rtc.c Copyright (c) 2003-2005 Motorola - * - * 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 -#include -#include -#include -#include -#include - -struct pcap_rtc { - struct pcap_chip *pcap; - struct rtc_device *rtc; -}; - -static irqreturn_t pcap_rtc_irq(int irq, void *_pcap_rtc) -{ - struct pcap_rtc *pcap_rtc = _pcap_rtc; - unsigned long rtc_events; - - if (irq == pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ)) - rtc_events = RTC_IRQF | RTC_UF; - else if (irq == pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA)) - rtc_events = RTC_IRQF | RTC_AF; - else - rtc_events = 0; - - rtc_update_irq(pcap_rtc->rtc, 1, rtc_events); - return IRQ_HANDLED; -} - -static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - struct rtc_time *tm = &alrm->time; - unsigned long secs; - u32 tod; /* time of day, seconds since midnight */ - u32 days; /* days since 1/1/1970 */ - - ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_TODA, &tod); - secs = tod & PCAP_RTC_TOD_MASK; - - ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAYA, &days); - secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY; - - rtc_time_to_tm(secs, tm); - - return 0; -} - -static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - struct rtc_time *tm = &alrm->time; - unsigned long secs; - u32 tod, days; - - rtc_tm_to_time(tm, &secs); - - tod = secs % SEC_PER_DAY; - ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_TODA, tod); - - days = secs / SEC_PER_DAY; - ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_DAYA, days); - - return 0; -} - -static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - unsigned long secs; - u32 tod, days; - - ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_TOD, &tod); - secs = tod & PCAP_RTC_TOD_MASK; - - ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAY, &days); - secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY; - - rtc_time_to_tm(secs, tm); - - return rtc_valid_tm(tm); -} - -static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - u32 tod, days; - - tod = secs % SEC_PER_DAY; - ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_TOD, tod); - - days = secs / SEC_PER_DAY; - ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_DAY, days); - - return 0; -} - -static int pcap_rtc_irq_enable(struct device *dev, int pirq, unsigned int en) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - - if (en) - enable_irq(pcap_to_irq(pcap_rtc->pcap, pirq)); - else - disable_irq(pcap_to_irq(pcap_rtc->pcap, pirq)); - - return 0; -} - -static int pcap_rtc_alarm_irq_enable(struct device *dev, unsigned int en) -{ - return pcap_rtc_irq_enable(dev, PCAP_IRQ_TODA, en); -} - -static int pcap_rtc_update_irq_enable(struct device *dev, unsigned int en) -{ - return pcap_rtc_irq_enable(dev, PCAP_IRQ_1HZ, en); -} - -static const struct rtc_class_ops pcap_rtc_ops = { - .read_time = pcap_rtc_read_time, - .read_alarm = pcap_rtc_read_alarm, - .set_alarm = pcap_rtc_set_alarm, - .set_mmss = pcap_rtc_set_mmss, - .alarm_irq_enable = pcap_rtc_alarm_irq_enable, - .update_irq_enable = pcap_rtc_update_irq_enable, -}; - -static int __devinit pcap_rtc_probe(struct platform_device *pdev) -{ - struct pcap_rtc *pcap_rtc; - int timer_irq, alarm_irq; - int err = -ENOMEM; - - pcap_rtc = kmalloc(sizeof(struct pcap_rtc), GFP_KERNEL); - if (!pcap_rtc) - return err; - - pcap_rtc->pcap = dev_get_drvdata(pdev->dev.parent); - - pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, - &pcap_rtc_ops, THIS_MODULE); - if (IS_ERR(pcap_rtc->rtc)) { - err = PTR_ERR(pcap_rtc->rtc); - goto fail_rtc; - } - - platform_set_drvdata(pdev, pcap_rtc); - - timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); - alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); - - err = request_irq(timer_irq, pcap_rtc_irq, 0, "RTC Timer", pcap_rtc); - if (err) - goto fail_timer; - - err = request_irq(alarm_irq, pcap_rtc_irq, 0, "RTC Alarm", pcap_rtc); - if (err) - goto fail_alarm; - - return 0; -fail_alarm: - free_irq(timer_irq, pcap_rtc); -fail_timer: - rtc_device_unregister(pcap_rtc->rtc); -fail_rtc: - kfree(pcap_rtc); - return err; -} - -static int __devexit pcap_rtc_remove(struct platform_device *pdev) -{ - struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); - - free_irq(pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ), pcap_rtc); - free_irq(pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA), pcap_rtc); - rtc_device_unregister(pcap_rtc->rtc); - kfree(pcap_rtc); - - return 0; -} - -static struct platform_driver pcap_rtc_driver = { - .remove = __devexit_p(pcap_rtc_remove), - .driver = { - .name = "pcap-rtc", - .owner = THIS_MODULE, - }, -}; - -static int __init rtc_pcap_init(void) -{ - return platform_driver_probe(&pcap_rtc_driver, pcap_rtc_probe); -} - -static void __exit rtc_pcap_exit(void) -{ - platform_driver_unregister(&pcap_rtc_driver); -} - -module_init(rtc_pcap_init); -module_exit(rtc_pcap_exit); - -MODULE_DESCRIPTION("Motorola pcap rtc driver"); -MODULE_AUTHOR("guiming zhuo "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-pcf2123.c b/trunk/drivers/rtc/rtc-pcf2123.c deleted file mode 100644 index e75df9d50e27..000000000000 --- a/trunk/drivers/rtc/rtc-pcf2123.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * An SPI driver for the Philips PCF2123 RTC - * Copyright 2009 Cyber Switching, Inc. - * - * Author: Chris Verges - * Maintainers: http://www.cyberswitching.com - * - * based on the RS5C348 driver in this same directory. - * - * Thanks to Christian Pellegrin for - * the sysfs contributions to this driver. - * - * 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. - * - * Please note that the CS is active high, so platform data - * should look something like: - * - * static struct spi_board_info ek_spi_devices[] = { - * ... - * { - * .modalias = "rtc-pcf2123", - * .chip_select = 1, - * .controller_data = (void *)AT91_PIN_PA10, - * .max_speed_hz = 1000 * 1000, - * .mode = SPI_CS_HIGH, - * .bus_num = 0, - * }, - * ... - *}; - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "0.6" - -#define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */ -#define PCF2123_REG_CTRL2 (0x01) /* Control Register 2 */ -#define PCF2123_REG_SC (0x02) /* datetime */ -#define PCF2123_REG_MN (0x03) -#define PCF2123_REG_HR (0x04) -#define PCF2123_REG_DM (0x05) -#define PCF2123_REG_DW (0x06) -#define PCF2123_REG_MO (0x07) -#define PCF2123_REG_YR (0x08) - -#define PCF2123_SUBADDR (1 << 4) -#define PCF2123_WRITE ((0 << 7) | PCF2123_SUBADDR) -#define PCF2123_READ ((1 << 7) | PCF2123_SUBADDR) - -static struct spi_driver pcf2123_driver; - -struct pcf2123_sysfs_reg { - struct device_attribute attr; - char name[2]; -}; - -struct pcf2123_plat_data { - struct rtc_device *rtc; - struct pcf2123_sysfs_reg regs[16]; -}; - -/* - * Causes a 30 nanosecond delay to ensure that the PCF2123 chip select - * is released properly after an SPI write. This function should be - * called after EVERY read/write call over SPI. - */ -static inline void pcf2123_delay_trec(void) -{ - ndelay(30); -} - -static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr, - char *buffer) -{ - struct spi_device *spi = to_spi_device(dev); - struct pcf2123_sysfs_reg *r; - u8 txbuf[1], rxbuf[1]; - unsigned long reg; - int ret; - - r = container_of(attr, struct pcf2123_sysfs_reg, attr); - - if (strict_strtoul(r->name, 16, ®)) - return -EINVAL; - - txbuf[0] = PCF2123_READ | reg; - ret = spi_write_then_read(spi, txbuf, 1, rxbuf, 1); - if (ret < 0) - return -EIO; - pcf2123_delay_trec(); - return sprintf(buffer, "0x%x\n", rxbuf[0]); -} - -static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr, - const char *buffer, size_t count) { - struct spi_device *spi = to_spi_device(dev); - struct pcf2123_sysfs_reg *r; - u8 txbuf[2]; - unsigned long reg; - unsigned long val; - - int ret; - - r = container_of(attr, struct pcf2123_sysfs_reg, attr); - - if (strict_strtoul(r->name, 16, ®) - || strict_strtoul(buffer, 10, &val)) - return -EINVAL; - - txbuf[0] = PCF2123_WRITE | reg; - txbuf[1] = val; - ret = spi_write(spi, txbuf, sizeof(txbuf)); - if (ret < 0) - return -EIO; - pcf2123_delay_trec(); - return count; -} - -static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct spi_device *spi = to_spi_device(dev); - u8 txbuf[1], rxbuf[7]; - int ret; - - txbuf[0] = PCF2123_READ | PCF2123_REG_SC; - ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), - rxbuf, sizeof(rxbuf)); - if (ret < 0) - return ret; - pcf2123_delay_trec(); - - tm->tm_sec = bcd2bin(rxbuf[0] & 0x7F); - tm->tm_min = bcd2bin(rxbuf[1] & 0x7F); - tm->tm_hour = bcd2bin(rxbuf[2] & 0x3F); /* rtc hr 0-23 */ - tm->tm_mday = bcd2bin(rxbuf[3] & 0x3F); - tm->tm_wday = rxbuf[4] & 0x07; - tm->tm_mon = bcd2bin(rxbuf[5] & 0x1F) - 1; /* rtc mn 1-12 */ - tm->tm_year = bcd2bin(rxbuf[6]); - if (tm->tm_year < 70) - tm->tm_year += 100; /* assume we are in 1970...2069 */ - - dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - /* the clock can give out invalid datetime, but we cannot return - * -EINVAL otherwise hwclock will refuse to set the time on bootup. - */ - if (rtc_valid_tm(tm) < 0) - dev_err(dev, "retrieved date/time is not valid.\n"); - - return 0; -} - -static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct spi_device *spi = to_spi_device(dev); - u8 txbuf[8]; - int ret; - - dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, - tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - - /* Stop the counter first */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1; - txbuf[1] = 0x20; - ret = spi_write(spi, txbuf, 2); - if (ret < 0) - return ret; - pcf2123_delay_trec(); - - /* Set the new time */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_SC; - txbuf[1] = bin2bcd(tm->tm_sec & 0x7F); - txbuf[2] = bin2bcd(tm->tm_min & 0x7F); - txbuf[3] = bin2bcd(tm->tm_hour & 0x3F); - txbuf[4] = bin2bcd(tm->tm_mday & 0x3F); - txbuf[5] = tm->tm_wday & 0x07; - txbuf[6] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */ - txbuf[7] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100); - - ret = spi_write(spi, txbuf, sizeof(txbuf)); - if (ret < 0) - return ret; - pcf2123_delay_trec(); - - /* Start the counter */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1; - txbuf[1] = 0x00; - ret = spi_write(spi, txbuf, 2); - if (ret < 0) - return ret; - pcf2123_delay_trec(); - - return 0; -} - -static const struct rtc_class_ops pcf2123_rtc_ops = { - .read_time = pcf2123_rtc_read_time, - .set_time = pcf2123_rtc_set_time, -}; - -static int __devinit pcf2123_probe(struct spi_device *spi) -{ - struct rtc_device *rtc; - struct pcf2123_plat_data *pdata; - u8 txbuf[2], rxbuf[2]; - int ret, i; - - pdata = kzalloc(sizeof(struct pcf2123_plat_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - spi->dev.platform_data = pdata; - - /* Send a software reset command */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1; - txbuf[1] = 0x58; - dev_dbg(&spi->dev, "resetting RTC (0x%02X 0x%02X)\n", - txbuf[0], txbuf[1]); - ret = spi_write(spi, txbuf, 2 * sizeof(u8)); - if (ret < 0) - goto kfree_exit; - pcf2123_delay_trec(); - - /* Stop the counter */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1; - txbuf[1] = 0x20; - dev_dbg(&spi->dev, "stopping RTC (0x%02X 0x%02X)\n", - txbuf[0], txbuf[1]); - ret = spi_write(spi, txbuf, 2 * sizeof(u8)); - if (ret < 0) - goto kfree_exit; - pcf2123_delay_trec(); - - /* See if the counter was actually stopped */ - txbuf[0] = PCF2123_READ | PCF2123_REG_CTRL1; - dev_dbg(&spi->dev, "checking for presence of RTC (0x%02X)\n", - txbuf[0]); - ret = spi_write_then_read(spi, txbuf, 1 * sizeof(u8), - rxbuf, 2 * sizeof(u8)); - dev_dbg(&spi->dev, "received data from RTC (0x%02X 0x%02X)\n", - rxbuf[0], rxbuf[1]); - if (ret < 0) - goto kfree_exit; - pcf2123_delay_trec(); - - if (!(rxbuf[0] & 0x20)) { - dev_err(&spi->dev, "chip not found\n"); - goto kfree_exit; - } - - dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); - dev_info(&spi->dev, "spiclk %u KHz.\n", - (spi->max_speed_hz + 500) / 1000); - - /* Start the counter */ - txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1; - txbuf[1] = 0x00; - ret = spi_write(spi, txbuf, sizeof(txbuf)); - if (ret < 0) - goto kfree_exit; - pcf2123_delay_trec(); - - /* Finalize the initialization */ - rtc = rtc_device_register(pcf2123_driver.driver.name, &spi->dev, - &pcf2123_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - dev_err(&spi->dev, "failed to register.\n"); - ret = PTR_ERR(rtc); - goto kfree_exit; - } - - pdata->rtc = rtc; - - for (i = 0; i < 16; i++) { - sprintf(pdata->regs[i].name, "%1x", i); - pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; - pdata->regs[i].attr.attr.name = pdata->regs[i].name; - pdata->regs[i].attr.show = pcf2123_show; - pdata->regs[i].attr.store = pcf2123_store; - ret = device_create_file(&spi->dev, &pdata->regs[i].attr); - if (ret) { - dev_err(&spi->dev, "Unable to create sysfs %s\n", - pdata->regs[i].name); - goto sysfs_exit; - } - } - - return 0; - -sysfs_exit: - for (i--; i >= 0; i--) - device_remove_file(&spi->dev, &pdata->regs[i].attr); - -kfree_exit: - kfree(pdata); - spi->dev.platform_data = NULL; - return ret; -} - -static int pcf2123_remove(struct spi_device *spi) -{ - struct pcf2123_plat_data *pdata = spi->dev.platform_data; - int i; - - if (pdata) { - struct rtc_device *rtc = pdata->rtc; - - if (rtc) - rtc_device_unregister(rtc); - for (i = 0; i < 16; i++) - if (pdata->regs[i].name[0]) - device_remove_file(&spi->dev, - &pdata->regs[i].attr); - kfree(pdata); - } - - return 0; -} - -static struct spi_driver pcf2123_driver = { - .driver = { - .name = "rtc-pcf2123", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = pcf2123_probe, - .remove = __devexit_p(pcf2123_remove), -}; - -static int __init pcf2123_init(void) -{ - return spi_register_driver(&pcf2123_driver); -} - -static void __exit pcf2123_exit(void) -{ - spi_unregister_driver(&pcf2123_driver); -} - -MODULE_AUTHOR("Chris Verges "); -MODULE_DESCRIPTION("NXP PCF2123 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(pcf2123_init); -module_exit(pcf2123_exit); diff --git a/trunk/drivers/rtc/rtc-r9701.c b/trunk/drivers/rtc/rtc-r9701.c index 9beba49c3c5b..42028f233bef 100644 --- a/trunk/drivers/rtc/rtc-r9701.c +++ b/trunk/drivers/rtc/rtc-r9701.c @@ -174,4 +174,3 @@ module_exit(r9701_exit); MODULE_DESCRIPTION("r9701 spi RTC driver"); MODULE_AUTHOR("Magnus Damm "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:rtc-r9701"); diff --git a/trunk/drivers/rtc/rtc-rs5c348.c b/trunk/drivers/rtc/rtc-rs5c348.c index 2099037cb3ea..dd1e2bc7a472 100644 --- a/trunk/drivers/rtc/rtc-rs5c348.c +++ b/trunk/drivers/rtc/rtc-rs5c348.c @@ -251,4 +251,3 @@ MODULE_AUTHOR("Atsushi Nemoto "); MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -MODULE_ALIAS("spi:rtc-rs5c348"); diff --git a/trunk/drivers/rtc/rtc-stmp3xxx.c b/trunk/drivers/rtc/rtc-stmp3xxx.c deleted file mode 100644 index d7ce1a5c857d..000000000000 --- a/trunk/drivers/rtc/rtc-stmp3xxx.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Freescale STMP37XX/STMP378X Real Time Clock driver - * - * Copyright (c) 2007 Sigmatel, Inc. - * Peter Hartley, - * - * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct stmp3xxx_rtc_data { - struct rtc_device *rtc; - unsigned irq_count; - void __iomem *io; - int irq_alarm, irq_1msec; -}; - -static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) -{ - /* - * The datasheet doesn't say which way round the - * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, - * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS - */ - while (__raw_readl(rtc_data->io + HW_RTC_STAT) & - BF(0x80, RTC_STAT_STALE_REGS)) - cpu_relax(); -} - -/* Time read/write */ -static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - stmp3xxx_wait_time(rtc_data); - rtc_time_to_tm(__raw_readl(rtc_data->io + HW_RTC_SECONDS), rtc_tm); - return 0; -} - -static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - __raw_writel(t, rtc_data->io + HW_RTC_SECONDS); - stmp3xxx_wait_time(rtc_data); - return 0; -} - -/* interrupt(s) handler */ -static irqreturn_t stmp3xxx_rtc_interrupt(int irq, void *dev_id) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev_id); - u32 status; - u32 events = 0; - - status = __raw_readl(rtc_data->io + HW_RTC_CTRL) & - (BM_RTC_CTRL_ALARM_IRQ | BM_RTC_CTRL_ONEMSEC_IRQ); - - if (status & BM_RTC_CTRL_ALARM_IRQ) { - stmp3xxx_clearl(BM_RTC_CTRL_ALARM_IRQ, - rtc_data->io + HW_RTC_CTRL); - events |= RTC_AF | RTC_IRQF; - } - - if (status & BM_RTC_CTRL_ONEMSEC_IRQ) { - stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ, - rtc_data->io + HW_RTC_CTRL); - if (++rtc_data->irq_count % 1000 == 0) { - events |= RTC_UF | RTC_IRQF; - rtc_data->irq_count = 0; - } - } - - if (events) - rtc_update_irq(rtc_data->rtc, 1, events); - - return IRQ_HANDLED; -} - -static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - void __iomem *p = rtc_data->io + HW_RTC_PERSISTENT0, - *ctl = rtc_data->io + HW_RTC_CTRL; - - if (enabled) { - stmp3xxx_setl(BM_RTC_PERSISTENT0_ALARM_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE_EN, p); - stmp3xxx_setl(BM_RTC_CTRL_ALARM_IRQ_EN, ctl); - } else { - stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE_EN, p); - stmp3xxx_clearl(BM_RTC_CTRL_ALARM_IRQ_EN, ctl); - } - return 0; -} - -static int stmp3xxx_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - if (enabled) - stmp3xxx_setl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - else - stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - return 0; -} - -static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - rtc_time_to_tm(__raw_readl(rtc_data->io + HW_RTC_ALARM), &alm->time); - return 0; -} - -static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - unsigned long t; - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - rtc_tm_to_time(&alm->time, &t); - __raw_writel(t, rtc_data->io + HW_RTC_ALARM); - return 0; -} - -static struct rtc_class_ops stmp3xxx_rtc_ops = { - .alarm_irq_enable = - stmp3xxx_alarm_irq_enable, - .update_irq_enable = - stmp3xxx_update_irq_enable, - .read_time = stmp3xxx_rtc_gettime, - .set_mmss = stmp3xxx_rtc_set_mmss, - .read_alarm = stmp3xxx_rtc_read_alarm, - .set_alarm = stmp3xxx_rtc_set_alarm, -}; - -static int stmp3xxx_rtc_remove(struct platform_device *pdev) -{ - struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); - - if (!rtc_data) - return 0; - - stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN | BM_RTC_CTRL_ALARM_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - free_irq(rtc_data->irq_alarm, &pdev->dev); - free_irq(rtc_data->irq_1msec, &pdev->dev); - rtc_device_unregister(rtc_data->rtc); - iounmap(rtc_data->io); - kfree(rtc_data); - - return 0; -} - -static int stmp3xxx_rtc_probe(struct platform_device *pdev) -{ - struct stmp3xxx_rtc_data *rtc_data; - struct resource *r; - int err; - - rtc_data = kzalloc(sizeof *rtc_data, GFP_KERNEL); - if (!rtc_data) - return -ENOMEM; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - dev_err(&pdev->dev, "failed to get resource\n"); - err = -ENXIO; - goto out_free; - } - - rtc_data->io = ioremap(r->start, resource_size(r)); - if (!rtc_data->io) { - dev_err(&pdev->dev, "ioremap failed\n"); - err = -EIO; - goto out_free; - } - - rtc_data->irq_alarm = platform_get_irq(pdev, 0); - rtc_data->irq_1msec = platform_get_irq(pdev, 1); - - if (!(__raw_readl(HW_RTC_STAT + rtc_data->io) & - BM_RTC_STAT_RTC_PRESENT)) { - dev_err(&pdev->dev, "no device onboard\n"); - err = -ENODEV; - goto out_remap; - } - - stmp3xxx_reset_block(rtc_data->io, true); - stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE, - rtc_data->io + HW_RTC_PERSISTENT0); - rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev, - &stmp3xxx_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc_data->rtc)) { - err = PTR_ERR(rtc_data->rtc); - goto out_remap; - } - - rtc_data->irq_count = 0; - err = request_irq(rtc_data->irq_alarm, stmp3xxx_rtc_interrupt, - IRQF_DISABLED, "RTC alarm", &pdev->dev); - if (err) { - dev_err(&pdev->dev, "Cannot claim IRQ%d\n", - rtc_data->irq_alarm); - goto out_irq_alarm; - } - err = request_irq(rtc_data->irq_1msec, stmp3xxx_rtc_interrupt, - IRQF_DISABLED, "RTC tick", &pdev->dev); - if (err) { - dev_err(&pdev->dev, "Cannot claim IRQ%d\n", - rtc_data->irq_1msec); - goto out_irq1; - } - - platform_set_drvdata(pdev, rtc_data); - - return 0; - -out_irq1: - free_irq(rtc_data->irq_alarm, &pdev->dev); -out_irq_alarm: - stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN | BM_RTC_CTRL_ALARM_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - rtc_device_unregister(rtc_data->rtc); -out_remap: - iounmap(rtc_data->io); -out_free: - kfree(rtc_data); - return err; -} - -#ifdef CONFIG_PM -static int stmp3xxx_rtc_suspend(struct platform_device *dev, pm_message_t state) -{ - return 0; -} - -static int stmp3xxx_rtc_resume(struct platform_device *dev) -{ - struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev); - - stmp3xxx_reset_block(rtc_data->io, true); - stmp3xxx_clearl(BM_RTC_PERSISTENT0_ALARM_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE_EN | - BM_RTC_PERSISTENT0_ALARM_WAKE, - rtc_data->io + HW_RTC_PERSISTENT0); - return 0; -} -#else -#define stmp3xxx_rtc_suspend NULL -#define stmp3xxx_rtc_resume NULL -#endif - -static struct platform_driver stmp3xxx_rtcdrv = { - .probe = stmp3xxx_rtc_probe, - .remove = stmp3xxx_rtc_remove, - .suspend = stmp3xxx_rtc_suspend, - .resume = stmp3xxx_rtc_resume, - .driver = { - .name = "stmp3xxx-rtc", - .owner = THIS_MODULE, - }, -}; - -static int __init stmp3xxx_rtc_init(void) -{ - return platform_driver_register(&stmp3xxx_rtcdrv); -} - -static void __exit stmp3xxx_rtc_exit(void) -{ - platform_driver_unregister(&stmp3xxx_rtcdrv); -} - -module_init(stmp3xxx_rtc_init); -module_exit(stmp3xxx_rtc_exit); - -MODULE_DESCRIPTION("STMP3xxx RTC Driver"); -MODULE_AUTHOR("dmitry pervushin "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-sysfs.c b/trunk/drivers/rtc/rtc-sysfs.c index 7dd23a6fc825..2531ce4c9db0 100644 --- a/trunk/drivers/rtc/rtc-sysfs.c +++ b/trunk/drivers/rtc/rtc-sysfs.c @@ -102,19 +102,6 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr, return n; } -static ssize_t -rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, - char *buf) -{ -#ifdef CONFIG_RTC_HCTOSYS_DEVICE - if (strcmp(dev_name(&to_rtc_device(dev)->dev), - CONFIG_RTC_HCTOSYS_DEVICE) == 0) - return sprintf(buf, "1\n"); - else -#endif - return sprintf(buf, "0\n"); -} - static struct device_attribute rtc_attrs[] = { __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), @@ -122,7 +109,6 @@ static struct device_attribute rtc_attrs[] = { __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq, rtc_sysfs_set_max_user_freq), - __ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL), { }, }; diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 848b59466850..4968c4ced385 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -2233,7 +2233,7 @@ static struct file_operations dev_fops = { .open = sg_proc_open_dev, .release = seq_release, }; -static const struct seq_operations dev_seq_ops = { +static struct seq_operations dev_seq_ops = { .start = dev_seq_start, .next = dev_seq_next, .stop = dev_seq_stop, @@ -2246,7 +2246,7 @@ static struct file_operations devstrs_fops = { .open = sg_proc_open_devstrs, .release = seq_release, }; -static const struct seq_operations devstrs_seq_ops = { +static struct seq_operations devstrs_seq_ops = { .start = dev_seq_start, .next = dev_seq_next, .stop = dev_seq_stop, @@ -2259,7 +2259,7 @@ static struct file_operations debug_fops = { .open = sg_proc_open_debug, .release = seq_release, }; -static const struct seq_operations debug_seq_ops = { +static struct seq_operations debug_seq_ops = { .start = dev_seq_start, .next = dev_seq_next, .stop = dev_seq_stop, diff --git a/trunk/drivers/serial/max3100.c b/trunk/drivers/serial/max3100.c index 3c30c56aa2e1..75ab00631c41 100644 --- a/trunk/drivers/serial/max3100.c +++ b/trunk/drivers/serial/max3100.c @@ -925,4 +925,3 @@ module_exit(max3100_exit); MODULE_DESCRIPTION("MAX3100 driver"); MODULE_AUTHOR("Christian Pellegrin "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:max3100"); diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 4b6f7cba3b3d..2c733c27db2f 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -117,11 +117,10 @@ config SPI_GPIO speed with a custom version of this driver; see the source code. config SPI_IMX - tristate "Freescale i.MX SPI controllers" - depends on ARCH_MXC - select SPI_BITBANG + tristate "Freescale iMX SPI controller" + depends on ARCH_MX1 && EXPERIMENTAL help - This enables using the Freescale i.MX SPI controllers in master + This enables using the Freescale iMX SPI controller in master mode. config SPI_LM70_LLP @@ -174,21 +173,11 @@ config SPI_PL022 tristate "ARM AMBA PL022 SSP controller (EXPERIMENTAL)" depends on ARM_AMBA && EXPERIMENTAL default y if MACH_U300 - default y if ARCH_REALVIEW - default y if INTEGRATOR_IMPD1 - default y if ARCH_VERSATILE help This selects the ARM(R) AMBA(R) PrimeCell PL022 SSP controller. If you have an embedded system with an AMBA(R) bus and a PL022 controller, say Y or M here. -config SPI_PPC4xx - tristate "PPC4xx SPI Controller" - depends on PPC32 && 4xx && SPI_MASTER - select SPI_BITBANG - help - This selects a driver for the PPC4xx SPI Controller. - config SPI_PXA2XX tristate "PXA2xx SSP SPI master" depends on ARCH_PXA && EXPERIMENTAL @@ -222,12 +211,6 @@ config SPI_SH_SCI help SPI driver for SuperH SCI blocks. -config SPI_STMP3XXX - tristate "Freescale STMP37xx/378x SPI/SSP controller" - depends on ARCH_STMP3XXX && SPI_MASTER - help - SPI driver for Freescale STMP37xx/378x SoC SSP interface - config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index 6d7a3f82c54b..3de408d294ba 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o obj-$(CONFIG_SPI_AU1550) += au1550_spi.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o obj-$(CONFIG_SPI_GPIO) += spi_gpio.o -obj-$(CONFIG_SPI_IMX) += mxc_spi.o +obj-$(CONFIG_SPI_IMX) += spi_imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o @@ -26,13 +26,11 @@ obj-$(CONFIG_SPI_ORION) += orion_spi.o obj-$(CONFIG_SPI_PL022) += amba-pl022.o obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o -obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o -obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o # ... add above this line ... # SPI protocol drivers (device/link on bus) diff --git a/trunk/drivers/spi/mxc_spi.c b/trunk/drivers/spi/mxc_spi.c deleted file mode 100644 index b1447236ae81..000000000000 --- a/trunk/drivers/spi/mxc_spi.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 Juergen Beisert - * - * 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 - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DRIVER_NAME "spi_imx" - -#define MXC_CSPIRXDATA 0x00 -#define MXC_CSPITXDATA 0x04 -#define MXC_CSPICTRL 0x08 -#define MXC_CSPIINT 0x0c -#define MXC_RESET 0x1c - -/* generic defines to abstract from the different register layouts */ -#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ -#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ - -struct mxc_spi_config { - unsigned int speed_hz; - unsigned int bpw; - unsigned int mode; - int cs; -}; - -struct mxc_spi_data { - struct spi_bitbang bitbang; - - struct completion xfer_done; - void *base; - int irq; - struct clk *clk; - unsigned long spi_clk; - int *chipselect; - - unsigned int count; - void (*tx)(struct mxc_spi_data *); - void (*rx)(struct mxc_spi_data *); - void *rx_buf; - const void *tx_buf; - unsigned int txfifo; /* number of words pushed in tx FIFO */ - - /* SoC specific functions */ - void (*intctrl)(struct mxc_spi_data *, int); - int (*config)(struct mxc_spi_data *, struct mxc_spi_config *); - void (*trigger)(struct mxc_spi_data *); - int (*rx_available)(struct mxc_spi_data *); -}; - -#define MXC_SPI_BUF_RX(type) \ -static void mxc_spi_buf_rx_##type(struct mxc_spi_data *mxc_spi) \ -{ \ - unsigned int val = readl(mxc_spi->base + MXC_CSPIRXDATA); \ - \ - if (mxc_spi->rx_buf) { \ - *(type *)mxc_spi->rx_buf = val; \ - mxc_spi->rx_buf += sizeof(type); \ - } \ -} - -#define MXC_SPI_BUF_TX(type) \ -static void mxc_spi_buf_tx_##type(struct mxc_spi_data *mxc_spi) \ -{ \ - type val = 0; \ - \ - if (mxc_spi->tx_buf) { \ - val = *(type *)mxc_spi->tx_buf; \ - mxc_spi->tx_buf += sizeof(type); \ - } \ - \ - mxc_spi->count -= sizeof(type); \ - \ - writel(val, mxc_spi->base + MXC_CSPITXDATA); \ -} - -MXC_SPI_BUF_RX(u8) -MXC_SPI_BUF_TX(u8) -MXC_SPI_BUF_RX(u16) -MXC_SPI_BUF_TX(u16) -MXC_SPI_BUF_RX(u32) -MXC_SPI_BUF_TX(u32) - -/* First entry is reserved, second entry is valid only if SDHC_SPIEN is set - * (which is currently not the case in this driver) - */ -static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, - 256, 384, 512, 768, 1024}; - -/* MX21, MX27 */ -static unsigned int mxc_spi_clkdiv_1(unsigned int fin, - unsigned int fspi) -{ - int i, max; - - if (cpu_is_mx21()) - max = 18; - else - max = 16; - - for (i = 2; i < max; i++) - if (fspi * mxc_clkdivs[i] >= fin) - return i; - - return max; -} - -/* MX1, MX31, MX35 */ -static unsigned int mxc_spi_clkdiv_2(unsigned int fin, - unsigned int fspi) -{ - int i, div = 4; - - for (i = 0; i < 7; i++) { - if (fspi * div >= fin) - return i; - div <<= 1; - } - - return 7; -} - -#define MX31_INTREG_TEEN (1 << 0) -#define MX31_INTREG_RREN (1 << 3) - -#define MX31_CSPICTRL_ENABLE (1 << 0) -#define MX31_CSPICTRL_MASTER (1 << 1) -#define MX31_CSPICTRL_XCH (1 << 2) -#define MX31_CSPICTRL_POL (1 << 4) -#define MX31_CSPICTRL_PHA (1 << 5) -#define MX31_CSPICTRL_SSCTL (1 << 6) -#define MX31_CSPICTRL_SSPOL (1 << 7) -#define MX31_CSPICTRL_BC_SHIFT 8 -#define MX35_CSPICTRL_BL_SHIFT 20 -#define MX31_CSPICTRL_CS_SHIFT 24 -#define MX35_CSPICTRL_CS_SHIFT 12 -#define MX31_CSPICTRL_DR_SHIFT 16 - -#define MX31_CSPISTATUS 0x14 -#define MX31_STATUS_RR (1 << 3) - -/* These functions also work for the i.MX35, but be aware that - * the i.MX35 has a slightly different register layout for bits - * we do not use here. - */ -static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable) -{ - unsigned int val = 0; - - if (enable & MXC_INT_TE) - val |= MX31_INTREG_TEEN; - if (enable & MXC_INT_RR) - val |= MX31_INTREG_RREN; - - writel(val, mxc_spi->base + MXC_CSPIINT); -} - -static void mx31_trigger(struct mxc_spi_data *mxc_spi) -{ - unsigned int reg; - - reg = readl(mxc_spi->base + MXC_CSPICTRL); - reg |= MX31_CSPICTRL_XCH; - writel(reg, mxc_spi->base + MXC_CSPICTRL); -} - -static int mx31_config(struct mxc_spi_data *mxc_spi, - struct mxc_spi_config *config) -{ - unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; - - reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) << - MX31_CSPICTRL_DR_SHIFT; - - if (cpu_is_mx31()) - reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; - else if (cpu_is_mx35()) { - reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; - reg |= MX31_CSPICTRL_SSCTL; - } - - if (config->mode & SPI_CPHA) - reg |= MX31_CSPICTRL_PHA; - if (config->mode & SPI_CPOL) - reg |= MX31_CSPICTRL_POL; - if (config->mode & SPI_CS_HIGH) - reg |= MX31_CSPICTRL_SSPOL; - if (config->cs < 0) { - if (cpu_is_mx31()) - reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; - else if (cpu_is_mx35()) - reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; - } - - writel(reg, mxc_spi->base + MXC_CSPICTRL); - - return 0; -} - -static int mx31_rx_available(struct mxc_spi_data *mxc_spi) -{ - return readl(mxc_spi->base + MX31_CSPISTATUS) & MX31_STATUS_RR; -} - -#define MX27_INTREG_RR (1 << 4) -#define MX27_INTREG_TEEN (1 << 9) -#define MX27_INTREG_RREN (1 << 13) - -#define MX27_CSPICTRL_POL (1 << 5) -#define MX27_CSPICTRL_PHA (1 << 6) -#define MX27_CSPICTRL_SSPOL (1 << 8) -#define MX27_CSPICTRL_XCH (1 << 9) -#define MX27_CSPICTRL_ENABLE (1 << 10) -#define MX27_CSPICTRL_MASTER (1 << 11) -#define MX27_CSPICTRL_DR_SHIFT 14 -#define MX27_CSPICTRL_CS_SHIFT 19 - -static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable) -{ - unsigned int val = 0; - - if (enable & MXC_INT_TE) - val |= MX27_INTREG_TEEN; - if (enable & MXC_INT_RR) - val |= MX27_INTREG_RREN; - - writel(val, mxc_spi->base + MXC_CSPIINT); -} - -static void mx27_trigger(struct mxc_spi_data *mxc_spi) -{ - unsigned int reg; - - reg = readl(mxc_spi->base + MXC_CSPICTRL); - reg |= MX27_CSPICTRL_XCH; - writel(reg, mxc_spi->base + MXC_CSPICTRL); -} - -static int mx27_config(struct mxc_spi_data *mxc_spi, - struct mxc_spi_config *config) -{ - unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER; - - reg |= mxc_spi_clkdiv_1(mxc_spi->spi_clk, config->speed_hz) << - MX27_CSPICTRL_DR_SHIFT; - reg |= config->bpw - 1; - - if (config->mode & SPI_CPHA) - reg |= MX27_CSPICTRL_PHA; - if (config->mode & SPI_CPOL) - reg |= MX27_CSPICTRL_POL; - if (config->mode & SPI_CS_HIGH) - reg |= MX27_CSPICTRL_SSPOL; - if (config->cs < 0) - reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT; - - writel(reg, mxc_spi->base + MXC_CSPICTRL); - - return 0; -} - -static int mx27_rx_available(struct mxc_spi_data *mxc_spi) -{ - return readl(mxc_spi->base + MXC_CSPIINT) & MX27_INTREG_RR; -} - -#define MX1_INTREG_RR (1 << 3) -#define MX1_INTREG_TEEN (1 << 8) -#define MX1_INTREG_RREN (1 << 11) - -#define MX1_CSPICTRL_POL (1 << 4) -#define MX1_CSPICTRL_PHA (1 << 5) -#define MX1_CSPICTRL_XCH (1 << 8) -#define MX1_CSPICTRL_ENABLE (1 << 9) -#define MX1_CSPICTRL_MASTER (1 << 10) -#define MX1_CSPICTRL_DR_SHIFT 13 - -static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable) -{ - unsigned int val = 0; - - if (enable & MXC_INT_TE) - val |= MX1_INTREG_TEEN; - if (enable & MXC_INT_RR) - val |= MX1_INTREG_RREN; - - writel(val, mxc_spi->base + MXC_CSPIINT); -} - -static void mx1_trigger(struct mxc_spi_data *mxc_spi) -{ - unsigned int reg; - - reg = readl(mxc_spi->base + MXC_CSPICTRL); - reg |= MX1_CSPICTRL_XCH; - writel(reg, mxc_spi->base + MXC_CSPICTRL); -} - -static int mx1_config(struct mxc_spi_data *mxc_spi, - struct mxc_spi_config *config) -{ - unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; - - reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) << - MX1_CSPICTRL_DR_SHIFT; - reg |= config->bpw - 1; - - if (config->mode & SPI_CPHA) - reg |= MX1_CSPICTRL_PHA; - if (config->mode & SPI_CPOL) - reg |= MX1_CSPICTRL_POL; - - writel(reg, mxc_spi->base + MXC_CSPICTRL); - - return 0; -} - -static int mx1_rx_available(struct mxc_spi_data *mxc_spi) -{ - return readl(mxc_spi->base + MXC_CSPIINT) & MX1_INTREG_RR; -} - -static void mxc_spi_chipselect(struct spi_device *spi, int is_active) -{ - struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); - unsigned int cs = 0; - int gpio = mxc_spi->chipselect[spi->chip_select]; - struct mxc_spi_config config; - - if (spi->mode & SPI_CS_HIGH) - cs = 1; - - if (is_active == BITBANG_CS_INACTIVE) { - if (gpio >= 0) - gpio_set_value(gpio, !cs); - return; - } - - config.bpw = spi->bits_per_word; - config.speed_hz = spi->max_speed_hz; - config.mode = spi->mode; - config.cs = mxc_spi->chipselect[spi->chip_select]; - - mxc_spi->config(mxc_spi, &config); - - /* Initialize the functions for transfer */ - if (config.bpw <= 8) { - mxc_spi->rx = mxc_spi_buf_rx_u8; - mxc_spi->tx = mxc_spi_buf_tx_u8; - } else if (config.bpw <= 16) { - mxc_spi->rx = mxc_spi_buf_rx_u16; - mxc_spi->tx = mxc_spi_buf_tx_u16; - } else if (config.bpw <= 32) { - mxc_spi->rx = mxc_spi_buf_rx_u32; - mxc_spi->tx = mxc_spi_buf_tx_u32; - } else - BUG(); - - if (gpio >= 0) - gpio_set_value(gpio, cs); - - return; -} - -static void mxc_spi_push(struct mxc_spi_data *mxc_spi) -{ - while (mxc_spi->txfifo < 8) { - if (!mxc_spi->count) - break; - mxc_spi->tx(mxc_spi); - mxc_spi->txfifo++; - } - - mxc_spi->trigger(mxc_spi); -} - -static irqreturn_t mxc_spi_isr(int irq, void *dev_id) -{ - struct mxc_spi_data *mxc_spi = dev_id; - - while (mxc_spi->rx_available(mxc_spi)) { - mxc_spi->rx(mxc_spi); - mxc_spi->txfifo--; - } - - if (mxc_spi->count) { - mxc_spi_push(mxc_spi); - return IRQ_HANDLED; - } - - if (mxc_spi->txfifo) { - /* No data left to push, but still waiting for rx data, - * enable receive data available interrupt. - */ - mxc_spi->intctrl(mxc_spi, MXC_INT_RR); - return IRQ_HANDLED; - } - - mxc_spi->intctrl(mxc_spi, 0); - complete(&mxc_spi->xfer_done); - - return IRQ_HANDLED; -} - -static int mxc_spi_setupxfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); - struct mxc_spi_config config; - - config.bpw = t ? t->bits_per_word : spi->bits_per_word; - config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; - config.mode = spi->mode; - - mxc_spi->config(mxc_spi, &config); - - return 0; -} - -static int mxc_spi_transfer(struct spi_device *spi, - struct spi_transfer *transfer) -{ - struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); - - mxc_spi->tx_buf = transfer->tx_buf; - mxc_spi->rx_buf = transfer->rx_buf; - mxc_spi->count = transfer->len; - mxc_spi->txfifo = 0; - - init_completion(&mxc_spi->xfer_done); - - mxc_spi_push(mxc_spi); - - mxc_spi->intctrl(mxc_spi, MXC_INT_TE); - - wait_for_completion(&mxc_spi->xfer_done); - - return transfer->len; -} - -static int mxc_spi_setup(struct spi_device *spi) -{ - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__, - spi->mode, spi->bits_per_word, spi->max_speed_hz); - - mxc_spi_chipselect(spi, BITBANG_CS_INACTIVE); - - return 0; -} - -static void mxc_spi_cleanup(struct spi_device *spi) -{ -} - -static int __init mxc_spi_probe(struct platform_device *pdev) -{ - struct spi_imx_master *mxc_platform_info; - struct spi_master *master; - struct mxc_spi_data *mxc_spi; - struct resource *res; - int i, ret; - - mxc_platform_info = (struct spi_imx_master *)pdev->dev.platform_data; - if (!mxc_platform_info) { - dev_err(&pdev->dev, "can't get the platform data\n"); - return -EINVAL; - } - - master = spi_alloc_master(&pdev->dev, sizeof(struct mxc_spi_data)); - if (!master) - return -ENOMEM; - - platform_set_drvdata(pdev, master); - - master->bus_num = pdev->id; - master->num_chipselect = mxc_platform_info->num_chipselect; - - mxc_spi = spi_master_get_devdata(master); - mxc_spi->bitbang.master = spi_master_get(master); - mxc_spi->chipselect = mxc_platform_info->chipselect; - - for (i = 0; i < master->num_chipselect; i++) { - if (mxc_spi->chipselect[i] < 0) - continue; - ret = gpio_request(mxc_spi->chipselect[i], DRIVER_NAME); - if (ret) { - i--; - while (i > 0) - if (mxc_spi->chipselect[i] >= 0) - gpio_free(mxc_spi->chipselect[i--]); - dev_err(&pdev->dev, "can't get cs gpios"); - goto out_master_put; - } - gpio_direction_output(mxc_spi->chipselect[i], 1); - } - - mxc_spi->bitbang.chipselect = mxc_spi_chipselect; - mxc_spi->bitbang.setup_transfer = mxc_spi_setupxfer; - mxc_spi->bitbang.txrx_bufs = mxc_spi_transfer; - mxc_spi->bitbang.master->setup = mxc_spi_setup; - mxc_spi->bitbang.master->cleanup = mxc_spi_cleanup; - - init_completion(&mxc_spi->xfer_done); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "can't get platform resource\n"); - ret = -ENOMEM; - goto out_gpio_free; - } - - if (!request_mem_region(res->start, resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "request_mem_region failed\n"); - ret = -EBUSY; - goto out_gpio_free; - } - - mxc_spi->base = ioremap(res->start, resource_size(res)); - if (!mxc_spi->base) { - ret = -EINVAL; - goto out_release_mem; - } - - mxc_spi->irq = platform_get_irq(pdev, 0); - if (!mxc_spi->irq) { - ret = -EINVAL; - goto out_iounmap; - } - - ret = request_irq(mxc_spi->irq, mxc_spi_isr, 0, DRIVER_NAME, mxc_spi); - if (ret) { - dev_err(&pdev->dev, "can't get irq%d: %d\n", mxc_spi->irq, ret); - goto out_iounmap; - } - - if (cpu_is_mx31() || cpu_is_mx35()) { - mxc_spi->intctrl = mx31_intctrl; - mxc_spi->config = mx31_config; - mxc_spi->trigger = mx31_trigger; - mxc_spi->rx_available = mx31_rx_available; - } else if (cpu_is_mx27() || cpu_is_mx21()) { - mxc_spi->intctrl = mx27_intctrl; - mxc_spi->config = mx27_config; - mxc_spi->trigger = mx27_trigger; - mxc_spi->rx_available = mx27_rx_available; - } else if (cpu_is_mx1()) { - mxc_spi->intctrl = mx1_intctrl; - mxc_spi->config = mx1_config; - mxc_spi->trigger = mx1_trigger; - mxc_spi->rx_available = mx1_rx_available; - } else - BUG(); - - mxc_spi->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(mxc_spi->clk)) { - dev_err(&pdev->dev, "unable to get clock\n"); - ret = PTR_ERR(mxc_spi->clk); - goto out_free_irq; - } - - clk_enable(mxc_spi->clk); - mxc_spi->spi_clk = clk_get_rate(mxc_spi->clk); - - if (!cpu_is_mx31() || !cpu_is_mx35()) - writel(1, mxc_spi->base + MXC_RESET); - - mxc_spi->intctrl(mxc_spi, 0); - - ret = spi_bitbang_start(&mxc_spi->bitbang); - if (ret) { - dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); - goto out_clk_put; - } - - dev_info(&pdev->dev, "probed\n"); - - return ret; - -out_clk_put: - clk_disable(mxc_spi->clk); - clk_put(mxc_spi->clk); -out_free_irq: - free_irq(mxc_spi->irq, mxc_spi); -out_iounmap: - iounmap(mxc_spi->base); -out_release_mem: - release_mem_region(res->start, resource_size(res)); -out_gpio_free: - for (i = 0; i < master->num_chipselect; i++) - if (mxc_spi->chipselect[i] >= 0) - gpio_free(mxc_spi->chipselect[i]); -out_master_put: - spi_master_put(master); - kfree(master); - platform_set_drvdata(pdev, NULL); - return ret; -} - -static int __exit mxc_spi_remove(struct platform_device *pdev) -{ - struct spi_master *master = platform_get_drvdata(pdev); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct mxc_spi_data *mxc_spi = spi_master_get_devdata(master); - int i; - - spi_bitbang_stop(&mxc_spi->bitbang); - - writel(0, mxc_spi->base + MXC_CSPICTRL); - clk_disable(mxc_spi->clk); - clk_put(mxc_spi->clk); - free_irq(mxc_spi->irq, mxc_spi); - iounmap(mxc_spi->base); - - for (i = 0; i < master->num_chipselect; i++) - if (mxc_spi->chipselect[i] >= 0) - gpio_free(mxc_spi->chipselect[i]); - - spi_master_put(master); - - release_mem_region(res->start, resource_size(res)); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver mxc_spi_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - .probe = mxc_spi_probe, - .remove = __exit_p(mxc_spi_remove), -}; - -static int __init mxc_spi_init(void) -{ - return platform_driver_register(&mxc_spi_driver); -} - -static void __exit mxc_spi_exit(void) -{ - platform_driver_unregister(&mxc_spi_driver); -} - -module_init(mxc_spi_init); -module_exit(mxc_spi_exit); - -MODULE_DESCRIPTION("SPI Master Controller driver"); -MODULE_AUTHOR("Sascha Hauer, Pengutronix"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/omap2_mcspi.c b/trunk/drivers/spi/omap2_mcspi.c index ba1a872b221e..9b80ad36dbba 100644 --- a/trunk/drivers/spi/omap2_mcspi.c +++ b/trunk/drivers/spi/omap2_mcspi.c @@ -41,9 +41,6 @@ #define OMAP2_MCSPI_MAX_FREQ 48000000 -/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */ -#define OMAP2_MCSPI_MAX_CTRL 4 - #define OMAP2_MCSPI_REVISION 0x00 #define OMAP2_MCSPI_SYSCONFIG 0x10 #define OMAP2_MCSPI_SYSSTATUS 0x14 @@ -62,40 +59,40 @@ /* per-register bitmasks: */ -#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE BIT(4) -#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) -#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) -#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET BIT(1) +#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) +#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP (1 << 2) +#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0) +#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP2_MCSPI_SYSSTATUS_RESETDONE BIT(0) +#define OMAP2_MCSPI_SYSSTATUS_RESETDONE (1 << 0) -#define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) -#define OMAP2_MCSPI_MODULCTRL_MS BIT(2) -#define OMAP2_MCSPI_MODULCTRL_STEST BIT(3) +#define OMAP2_MCSPI_MODULCTRL_SINGLE (1 << 0) +#define OMAP2_MCSPI_MODULCTRL_MS (1 << 2) +#define OMAP2_MCSPI_MODULCTRL_STEST (1 << 3) -#define OMAP2_MCSPI_CHCONF_PHA BIT(0) -#define OMAP2_MCSPI_CHCONF_POL BIT(1) +#define OMAP2_MCSPI_CHCONF_PHA (1 << 0) +#define OMAP2_MCSPI_CHCONF_POL (1 << 1) #define OMAP2_MCSPI_CHCONF_CLKD_MASK (0x0f << 2) -#define OMAP2_MCSPI_CHCONF_EPOL BIT(6) +#define OMAP2_MCSPI_CHCONF_EPOL (1 << 6) #define OMAP2_MCSPI_CHCONF_WL_MASK (0x1f << 7) -#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY BIT(12) -#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY BIT(13) +#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY (0x01 << 12) +#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY (0x02 << 12) #define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12) -#define OMAP2_MCSPI_CHCONF_DMAW BIT(14) -#define OMAP2_MCSPI_CHCONF_DMAR BIT(15) -#define OMAP2_MCSPI_CHCONF_DPE0 BIT(16) -#define OMAP2_MCSPI_CHCONF_DPE1 BIT(17) -#define OMAP2_MCSPI_CHCONF_IS BIT(18) -#define OMAP2_MCSPI_CHCONF_TURBO BIT(19) -#define OMAP2_MCSPI_CHCONF_FORCE BIT(20) +#define OMAP2_MCSPI_CHCONF_DMAW (1 << 14) +#define OMAP2_MCSPI_CHCONF_DMAR (1 << 15) +#define OMAP2_MCSPI_CHCONF_DPE0 (1 << 16) +#define OMAP2_MCSPI_CHCONF_DPE1 (1 << 17) +#define OMAP2_MCSPI_CHCONF_IS (1 << 18) +#define OMAP2_MCSPI_CHCONF_TURBO (1 << 19) +#define OMAP2_MCSPI_CHCONF_FORCE (1 << 20) -#define OMAP2_MCSPI_CHSTAT_RXS BIT(0) -#define OMAP2_MCSPI_CHSTAT_TXS BIT(1) -#define OMAP2_MCSPI_CHSTAT_EOT BIT(2) +#define OMAP2_MCSPI_CHSTAT_RXS (1 << 0) +#define OMAP2_MCSPI_CHSTAT_TXS (1 << 1) +#define OMAP2_MCSPI_CHSTAT_EOT (1 << 2) -#define OMAP2_MCSPI_CHCTRL_EN BIT(0) +#define OMAP2_MCSPI_CHCTRL_EN (1 << 0) -#define OMAP2_MCSPI_WAKEUPENABLE_WKEN BIT(0) +#define OMAP2_MCSPI_WAKEUPENABLE_WKEN (1 << 0) /* We have 2 DMA channels per CS, one for RX and one for TX */ struct omap2_mcspi_dma { @@ -134,23 +131,8 @@ struct omap2_mcspi_cs { void __iomem *base; unsigned long phys; int word_len; - struct list_head node; - /* Context save and restore shadow register */ - u32 chconf0; -}; - -/* used for context save and restore, structure members to be updated whenever - * corresponding registers are modified. - */ -struct omap2_mcspi_regs { - u32 sysconfig; - u32 modulctrl; - u32 wakeupenable; - struct list_head cs; }; -static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL]; - static struct workqueue_struct *omap2_mcspi_wq; #define MOD_REG_BIT(val, mask, set) do { \ @@ -190,27 +172,12 @@ static inline u32 mcspi_read_cs_reg(const struct spi_device *spi, int idx) return __raw_readl(cs->base + idx); } -static inline u32 mcspi_cached_chconf0(const struct spi_device *spi) -{ - struct omap2_mcspi_cs *cs = spi->controller_state; - - return cs->chconf0; -} - -static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val) -{ - struct omap2_mcspi_cs *cs = spi->controller_state; - - cs->chconf0 = val; - mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val); -} - static void omap2_mcspi_set_dma_req(const struct spi_device *spi, int is_read, int enable) { u32 l, rw; - l = mcspi_cached_chconf0(spi); + l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); if (is_read) /* 1 is read, 0 write */ rw = OMAP2_MCSPI_CHCONF_DMAR; @@ -218,7 +185,7 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi, rw = OMAP2_MCSPI_CHCONF_DMAW; MOD_REG_BIT(l, rw, enable); - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); } static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) @@ -233,9 +200,9 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active) { u32 l; - l = mcspi_cached_chconf0(spi); + l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); MOD_REG_BIT(l, OMAP2_MCSPI_CHCONF_FORCE, cs_active); - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); } static void omap2_mcspi_set_master_mode(struct spi_master *master) @@ -250,46 +217,6 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master) MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0); MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); - - omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l; -} - -static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) -{ - struct spi_master *spi_cntrl; - struct omap2_mcspi_cs *cs; - spi_cntrl = mcspi->master; - - /* McSPI: context restore */ - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, - omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); - - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG, - omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig); - - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, - omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); - - list_for_each_entry(cs, &omap2_mcspi_ctx[spi_cntrl->bus_num - 1].cs, - node) - __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); -} -static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) -{ - clk_disable(mcspi->ick); - clk_disable(mcspi->fck); -} - -static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) -{ - if (clk_enable(mcspi->ick)) - return -ENODEV; - if (clk_enable(mcspi->fck)) - return -ENODEV; - - omap2_mcspi_restore_ctx(mcspi); - - return 0; } static unsigned @@ -430,7 +357,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) c = count; word_len = cs->word_len; - l = mcspi_cached_chconf0(spi); + l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); l &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; /* We store the pre-calculated register addresses on stack to speed @@ -470,7 +397,8 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) * more word i/o: switch to rx+tx */ if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, + OMAP2_MCSPI_CHCONF0, l); *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %02x\n", @@ -508,7 +436,8 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) * more word i/o: switch to rx+tx */ if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, + OMAP2_MCSPI_CHCONF0, l); *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %04x\n", @@ -546,7 +475,8 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) * more word i/o: switch to rx+tx */ if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, + OMAP2_MCSPI_CHCONF0, l); *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %04x\n", @@ -575,12 +505,10 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, { struct omap2_mcspi_cs *cs = spi->controller_state; struct omap2_mcspi *mcspi; - struct spi_master *spi_cntrl; u32 l = 0, div = 0; u8 word_len = spi->bits_per_word; mcspi = spi_master_get_devdata(spi->master); - spi_cntrl = mcspi->master; if (t != NULL && t->bits_per_word) word_len = t->bits_per_word; @@ -594,7 +522,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, } else div = 15; - l = mcspi_cached_chconf0(spi); + l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS * REVISIT: this controller could support SPI_3WIRE mode. @@ -626,7 +554,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, else l &= ~OMAP2_MCSPI_CHCONF_PHA; - mcspi_write_chconf0(spi, l); + mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", OMAP2_MCSPI_MAX_FREQ / (1 << div), @@ -719,11 +647,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; cs->phys = mcspi->phys + spi->chip_select * 0x14; - cs->chconf0 = 0; spi->controller_state = cs; - /* Link this to context save list */ - list_add_tail(&cs->node, - &omap2_mcspi_ctx[mcspi->master->bus_num - 1].cs); } if (mcspi_dma->dma_rx_channel == -1 @@ -733,11 +657,11 @@ static int omap2_mcspi_setup(struct spi_device *spi) return ret; } - if (omap2_mcspi_enable_clocks(mcspi)) - return -ENODEV; - + clk_enable(mcspi->ick); + clk_enable(mcspi->fck); ret = omap2_mcspi_setup_transfer(spi, NULL); - omap2_mcspi_disable_clocks(mcspi); + clk_disable(mcspi->fck); + clk_disable(mcspi->ick); return ret; } @@ -746,15 +670,10 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) { struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; - struct omap2_mcspi_cs *cs; mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; - /* Unlink controller state from context save list */ - cs = spi->controller_state; - list_del(&cs->node); - kfree(spi->controller_state); if (mcspi_dma->dma_rx_channel != -1) { @@ -774,8 +693,8 @@ static void omap2_mcspi_work(struct work_struct *work) mcspi = container_of(work, struct omap2_mcspi, work); spin_lock_irq(&mcspi->lock); - if (omap2_mcspi_enable_clocks(mcspi)) - goto out; + clk_enable(mcspi->ick); + clk_enable(mcspi->fck); /* We only enable one channel at a time -- the one whose message is * at the head of the queue -- although this controller would gladly @@ -822,13 +741,13 @@ static void omap2_mcspi_work(struct work_struct *work) cs_active = 1; } - chconf = mcspi_cached_chconf0(spi); + chconf = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; if (t->tx_buf == NULL) chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; else if (t->rx_buf == NULL) chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; - mcspi_write_chconf0(spi, chconf); + mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, chconf); if (t->len) { unsigned count; @@ -877,9 +796,9 @@ static void omap2_mcspi_work(struct work_struct *work) spin_lock_irq(&mcspi->lock); } - omap2_mcspi_disable_clocks(mcspi); + clk_disable(mcspi->fck); + clk_disable(mcspi->ick); -out: spin_unlock_irq(&mcspi->lock); } @@ -966,8 +885,8 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) struct spi_master *master = mcspi->master; u32 tmp; - if (omap2_mcspi_enable_clocks(mcspi)) - return -1; + clk_enable(mcspi->ick); + clk_enable(mcspi->fck); mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, OMAP2_MCSPI_SYSCONFIG_SOFTRESET); @@ -975,18 +894,18 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS); } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); - tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | - OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | - OMAP2_MCSPI_SYSCONFIG_SMARTIDLE; - mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp); - omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp; + mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, + OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | + OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | + OMAP2_MCSPI_SYSCONFIG_SMARTIDLE); - tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; - mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); - omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp; + mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, + OMAP2_MCSPI_WAKEUPENABLE_WKEN); omap2_mcspi_set_master_mode(master); - omap2_mcspi_disable_clocks(mcspi); + + clk_disable(mcspi->fck); + clk_disable(mcspi->ick); return 0; } @@ -1014,8 +933,7 @@ static u8 __initdata spi2_txdma_id[] = { OMAP24XX_DMA_SPI2_TX1, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) \ - || defined(CONFIG_ARCH_OMAP4) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) static u8 __initdata spi3_rxdma_id[] = { OMAP24XX_DMA_SPI3_RX0, OMAP24XX_DMA_SPI3_RX1, @@ -1027,7 +945,7 @@ static u8 __initdata spi3_txdma_id[] = { }; #endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP3 static u8 __initdata spi4_rxdma_id[] = { OMAP34XX_DMA_SPI4_RX0, }; @@ -1057,15 +975,14 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) txdma_id = spi2_txdma_id; num_chipselect = 2; break; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ - || defined(CONFIG_ARCH_OMAP4) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) case 3: rxdma_id = spi3_rxdma_id; txdma_id = spi3_txdma_id; num_chipselect = 2; break; #endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP3 case 4: rxdma_id = spi4_rxdma_id; txdma_id = spi4_txdma_id; @@ -1121,7 +1038,6 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) spin_lock_init(&mcspi->lock); INIT_LIST_HEAD(&mcspi->msg_queue); - INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); mcspi->ick = clk_get(&pdev->dev, "ick"); if (IS_ERR(mcspi->ick)) { diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index 31dd56f0dae9..d949dbf1141f 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -1729,7 +1729,7 @@ static int __init pxa2xx_spi_init(void) { return platform_driver_probe(&driver, pxa2xx_spi_probe); } -subsys_initcall(pxa2xx_spi_init); +module_init(pxa2xx_spi_init); static void __exit pxa2xx_spi_exit(void) { diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index b76f2468a84a..70845ccd85c3 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -60,32 +59,9 @@ static struct device_attribute spi_dev_attrs[] = { * and the sysfs version makes coldplug work too. */ -static const struct spi_device_id *spi_match_id(const struct spi_device_id *id, - const struct spi_device *sdev) -{ - while (id->name[0]) { - if (!strcmp(sdev->modalias, id->name)) - return id; - id++; - } - return NULL; -} - -const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev) -{ - const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver); - - return spi_match_id(sdrv->id_table, sdev); -} -EXPORT_SYMBOL_GPL(spi_get_device_id); - static int spi_match_device(struct device *dev, struct device_driver *drv) { const struct spi_device *spi = to_spi_device(dev); - const struct spi_driver *sdrv = to_spi_driver(drv); - - if (sdrv->id_table) - return !!spi_match_id(sdrv->id_table, spi); return strcmp(spi->modalias, drv->name) == 0; } @@ -94,7 +70,7 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) { const struct spi_device *spi = to_spi_device(dev); - add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); + add_uevent_var(env, "MODALIAS=%s", spi->modalias); return 0; } @@ -663,65 +639,6 @@ int spi_setup(struct spi_device *spi) } EXPORT_SYMBOL_GPL(spi_setup); -/** - * spi_async - asynchronous SPI transfer - * @spi: device with which data will be exchanged - * @message: describes the data transfers, including completion callback - * Context: any (irqs may be blocked, etc) - * - * This call may be used in_irq and other contexts which can't sleep, - * as well as from task contexts which can sleep. - * - * The completion callback is invoked in a context which can't sleep. - * Before that invocation, the value of message->status is undefined. - * When the callback is issued, message->status holds either zero (to - * indicate complete success) or a negative error code. After that - * callback returns, the driver which issued the transfer request may - * deallocate the associated memory; it's no longer in use by any SPI - * core or controller driver code. - * - * Note that although all messages to a spi_device are handled in - * FIFO order, messages may go to different devices in other orders. - * Some device might be higher priority, or have various "hard" access - * time requirements, for example. - * - * On detection of any fault during the transfer, processing of - * the entire message is aborted, and the device is deselected. - * Until returning from the associated message completion callback, - * no other spi_message queued to that device will be processed. - * (This rule applies equally to all the synchronous transfer calls, - * which are wrappers around this core asynchronous primitive.) - */ -int spi_async(struct spi_device *spi, struct spi_message *message) -{ - struct spi_master *master = spi->master; - - /* Half-duplex links include original MicroWire, and ones with - * only one data pin like SPI_3WIRE (switches direction) or where - * either MOSI or MISO is missing. They can also be caused by - * software limitations. - */ - if ((master->flags & SPI_MASTER_HALF_DUPLEX) - || (spi->mode & SPI_3WIRE)) { - struct spi_transfer *xfer; - unsigned flags = master->flags; - - list_for_each_entry(xfer, &message->transfers, transfer_list) { - if (xfer->rx_buf && xfer->tx_buf) - return -EINVAL; - if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf) - return -EINVAL; - if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf) - return -EINVAL; - } - } - - message->spi = spi; - message->status = -EINPROGRESS; - return master->transfer(spi, message); -} -EXPORT_SYMBOL_GPL(spi_async); - /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/spi/spi_imx.c b/trunk/drivers/spi/spi_imx.c new file mode 100644 index 000000000000..c195e45f7f35 --- /dev/null +++ b/trunk/drivers/spi/spi_imx.c @@ -0,0 +1,1770 @@ +/* + * drivers/spi/spi_imx.c + * + * Copyright (C) 2006 SWAPP + * Andrea Paterniani + * + * Initial version inspired by: + * linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/*-------------------------------------------------------------------------*/ +/* SPI Registers offsets from peripheral base address */ +#define SPI_RXDATA (0x00) +#define SPI_TXDATA (0x04) +#define SPI_CONTROL (0x08) +#define SPI_INT_STATUS (0x0C) +#define SPI_TEST (0x10) +#define SPI_PERIOD (0x14) +#define SPI_DMA (0x18) +#define SPI_RESET (0x1C) + +/* SPI Control Register Bit Fields & Masks */ +#define SPI_CONTROL_BITCOUNT_MASK (0xF) /* Bit Count Mask */ +#define SPI_CONTROL_BITCOUNT(n) (((n) - 1) & SPI_CONTROL_BITCOUNT_MASK) +#define SPI_CONTROL_POL (0x1 << 4) /* Clock Polarity Mask */ +#define SPI_CONTROL_POL_ACT_HIGH (0x0 << 4) /* Active high pol. (0=idle) */ +#define SPI_CONTROL_POL_ACT_LOW (0x1 << 4) /* Active low pol. (1=idle) */ +#define SPI_CONTROL_PHA (0x1 << 5) /* Clock Phase Mask */ +#define SPI_CONTROL_PHA_0 (0x0 << 5) /* Clock Phase 0 */ +#define SPI_CONTROL_PHA_1 (0x1 << 5) /* Clock Phase 1 */ +#define SPI_CONTROL_SSCTL (0x1 << 6) /* /SS Waveform Select Mask */ +#define SPI_CONTROL_SSCTL_0 (0x0 << 6) /* Master: /SS stays low between SPI burst + Slave: RXFIFO advanced by BIT_COUNT */ +#define SPI_CONTROL_SSCTL_1 (0x1 << 6) /* Master: /SS insert pulse between SPI burst + Slave: RXFIFO advanced by /SS rising edge */ +#define SPI_CONTROL_SSPOL (0x1 << 7) /* /SS Polarity Select Mask */ +#define SPI_CONTROL_SSPOL_ACT_LOW (0x0 << 7) /* /SS Active low */ +#define SPI_CONTROL_SSPOL_ACT_HIGH (0x1 << 7) /* /SS Active high */ +#define SPI_CONTROL_XCH (0x1 << 8) /* Exchange */ +#define SPI_CONTROL_SPIEN (0x1 << 9) /* SPI Module Enable */ +#define SPI_CONTROL_MODE (0x1 << 10) /* SPI Mode Select Mask */ +#define SPI_CONTROL_MODE_SLAVE (0x0 << 10) /* SPI Mode Slave */ +#define SPI_CONTROL_MODE_MASTER (0x1 << 10) /* SPI Mode Master */ +#define SPI_CONTROL_DRCTL (0x3 << 11) /* /SPI_RDY Control Mask */ +#define SPI_CONTROL_DRCTL_0 (0x0 << 11) /* Ignore /SPI_RDY */ +#define SPI_CONTROL_DRCTL_1 (0x1 << 11) /* /SPI_RDY falling edge triggers input */ +#define SPI_CONTROL_DRCTL_2 (0x2 << 11) /* /SPI_RDY active low level triggers input */ +#define SPI_CONTROL_DATARATE (0x7 << 13) /* Data Rate Mask */ +#define SPI_PERCLK2_DIV_MIN (0) /* PERCLK2:4 */ +#define SPI_PERCLK2_DIV_MAX (7) /* PERCLK2:512 */ +#define SPI_CONTROL_DATARATE_MIN (SPI_PERCLK2_DIV_MAX << 13) +#define SPI_CONTROL_DATARATE_MAX (SPI_PERCLK2_DIV_MIN << 13) +#define SPI_CONTROL_DATARATE_BAD (SPI_CONTROL_DATARATE_MIN + 1) + +/* SPI Interrupt/Status Register Bit Fields & Masks */ +#define SPI_STATUS_TE (0x1 << 0) /* TXFIFO Empty Status */ +#define SPI_STATUS_TH (0x1 << 1) /* TXFIFO Half Status */ +#define SPI_STATUS_TF (0x1 << 2) /* TXFIFO Full Status */ +#define SPI_STATUS_RR (0x1 << 3) /* RXFIFO Data Ready Status */ +#define SPI_STATUS_RH (0x1 << 4) /* RXFIFO Half Status */ +#define SPI_STATUS_RF (0x1 << 5) /* RXFIFO Full Status */ +#define SPI_STATUS_RO (0x1 << 6) /* RXFIFO Overflow */ +#define SPI_STATUS_BO (0x1 << 7) /* Bit Count Overflow */ +#define SPI_STATUS (0xFF) /* SPI Status Mask */ +#define SPI_INTEN_TE (0x1 << 8) /* TXFIFO Empty Interrupt Enable */ +#define SPI_INTEN_TH (0x1 << 9) /* TXFIFO Half Interrupt Enable */ +#define SPI_INTEN_TF (0x1 << 10) /* TXFIFO Full Interrupt Enable */ +#define SPI_INTEN_RE (0x1 << 11) /* RXFIFO Data Ready Interrupt Enable */ +#define SPI_INTEN_RH (0x1 << 12) /* RXFIFO Half Interrupt Enable */ +#define SPI_INTEN_RF (0x1 << 13) /* RXFIFO Full Interrupt Enable */ +#define SPI_INTEN_RO (0x1 << 14) /* RXFIFO Overflow Interrupt Enable */ +#define SPI_INTEN_BO (0x1 << 15) /* Bit Count Overflow Interrupt Enable */ +#define SPI_INTEN (0xFF << 8) /* SPI Interrupt Enable Mask */ + +/* SPI Test Register Bit Fields & Masks */ +#define SPI_TEST_TXCNT (0xF << 0) /* TXFIFO Counter */ +#define SPI_TEST_RXCNT_LSB (4) /* RXFIFO Counter LSB */ +#define SPI_TEST_RXCNT (0xF << 4) /* RXFIFO Counter */ +#define SPI_TEST_SSTATUS (0xF << 8) /* State Machine Status */ +#define SPI_TEST_LBC (0x1 << 14) /* Loop Back Control */ + +/* SPI Period Register Bit Fields & Masks */ +#define SPI_PERIOD_WAIT (0x7FFF << 0) /* Wait Between Transactions */ +#define SPI_PERIOD_MAX_WAIT (0x7FFF) /* Max Wait Between + Transactions */ +#define SPI_PERIOD_CSRC (0x1 << 15) /* Period Clock Source Mask */ +#define SPI_PERIOD_CSRC_BCLK (0x0 << 15) /* Period Clock Source is + Bit Clock */ +#define SPI_PERIOD_CSRC_32768 (0x1 << 15) /* Period Clock Source is + 32.768 KHz Clock */ + +/* SPI DMA Register Bit Fields & Masks */ +#define SPI_DMA_RHDMA (0x1 << 4) /* RXFIFO Half Status */ +#define SPI_DMA_RFDMA (0x1 << 5) /* RXFIFO Full Status */ +#define SPI_DMA_TEDMA (0x1 << 6) /* TXFIFO Empty Status */ +#define SPI_DMA_THDMA (0x1 << 7) /* TXFIFO Half Status */ +#define SPI_DMA_RHDEN (0x1 << 12) /* RXFIFO Half DMA Request Enable */ +#define SPI_DMA_RFDEN (0x1 << 13) /* RXFIFO Full DMA Request Enable */ +#define SPI_DMA_TEDEN (0x1 << 14) /* TXFIFO Empty DMA Request Enable */ +#define SPI_DMA_THDEN (0x1 << 15) /* TXFIFO Half DMA Request Enable */ + +/* SPI Soft Reset Register Bit Fields & Masks */ +#define SPI_RESET_START (0x1) /* Start */ + +/* Default SPI configuration values */ +#define SPI_DEFAULT_CONTROL \ +( \ + SPI_CONTROL_BITCOUNT(16) | \ + SPI_CONTROL_POL_ACT_HIGH | \ + SPI_CONTROL_PHA_0 | \ + SPI_CONTROL_SPIEN | \ + SPI_CONTROL_SSCTL_1 | \ + SPI_CONTROL_MODE_MASTER | \ + SPI_CONTROL_DRCTL_0 | \ + SPI_CONTROL_DATARATE_MIN \ +) +#define SPI_DEFAULT_ENABLE_LOOPBACK (0) +#define SPI_DEFAULT_ENABLE_DMA (0) +#define SPI_DEFAULT_PERIOD_WAIT (8) +/*-------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/* TX/RX SPI FIFO size */ +#define SPI_FIFO_DEPTH (8) +#define SPI_FIFO_BYTE_WIDTH (2) +#define SPI_FIFO_OVERFLOW_MARGIN (2) + +/* DMA burst length for half full/empty request trigger */ +#define SPI_DMA_BLR (SPI_FIFO_DEPTH * SPI_FIFO_BYTE_WIDTH / 2) + +/* Dummy char output to achieve reads. + Choosing something different from all zeroes may help pattern recogition + for oscilloscope analysis, but may break some drivers. */ +#define SPI_DUMMY_u8 0 +#define SPI_DUMMY_u16 ((SPI_DUMMY_u8 << 8) | SPI_DUMMY_u8) +#define SPI_DUMMY_u32 ((SPI_DUMMY_u16 << 16) | SPI_DUMMY_u16) + +/** + * Macro to change a u32 field: + * @r : register to edit + * @m : bit mask + * @v : new value for the field correctly bit-alligned +*/ +#define u32_EDIT(r, m, v) r = (r & ~(m)) | (v) + +/* Message state */ +#define START_STATE ((void*)0) +#define RUNNING_STATE ((void*)1) +#define DONE_STATE ((void*)2) +#define ERROR_STATE ((void*)-1) + +/* Queue state */ +#define QUEUE_RUNNING (0) +#define QUEUE_STOPPED (1) + +#define IS_DMA_ALIGNED(x) (((u32)(x) & 0x03) == 0) +#define DMA_ALIGNMENT 4 +/*-------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/* Driver data structs */ + +/* Context */ +struct driver_data { + /* Driver model hookup */ + struct platform_device *pdev; + + /* SPI framework hookup */ + struct spi_master *master; + + /* IMX hookup */ + struct spi_imx_master *master_info; + + /* Memory resources and SPI regs virtual address */ + struct resource *ioarea; + void __iomem *regs; + + /* SPI RX_DATA physical address */ + dma_addr_t rd_data_phys; + + /* Driver message queue */ + struct workqueue_struct *workqueue; + struct work_struct work; + spinlock_t lock; + struct list_head queue; + int busy; + int run; + + /* Message Transfer pump */ + struct tasklet_struct pump_transfers; + + /* Current message, transfer and state */ + struct spi_message *cur_msg; + struct spi_transfer *cur_transfer; + struct chip_data *cur_chip; + + /* Rd / Wr buffers pointers */ + size_t len; + void *tx; + void *tx_end; + void *rx; + void *rx_end; + + u8 rd_only; + u8 n_bytes; + int cs_change; + + /* Function pointers */ + irqreturn_t (*transfer_handler)(struct driver_data *drv_data); + void (*cs_control)(u32 command); + + /* DMA setup */ + int rx_channel; + int tx_channel; + dma_addr_t rx_dma; + dma_addr_t tx_dma; + int rx_dma_needs_unmap; + int tx_dma_needs_unmap; + size_t tx_map_len; + u32 dummy_dma_buf ____cacheline_aligned; + + struct clk *clk; +}; + +/* Runtime state */ +struct chip_data { + u32 control; + u32 period; + u32 test; + + u8 enable_dma:1; + u8 bits_per_word; + u8 n_bytes; + u32 max_speed_hz; + + void (*cs_control)(u32 command); +}; +/*-------------------------------------------------------------------------*/ + + +static void pump_messages(struct work_struct *work); + +static void flush(struct driver_data *drv_data) +{ + void __iomem *regs = drv_data->regs; + u32 control; + + dev_dbg(&drv_data->pdev->dev, "flush\n"); + + /* Wait for end of transaction */ + do { + control = readl(regs + SPI_CONTROL); + } while (control & SPI_CONTROL_XCH); + + /* Release chip select if requested, transfer delays are + handled in pump_transfers */ + if (drv_data->cs_change) + drv_data->cs_control(SPI_CS_DEASSERT); + + /* Disable SPI to flush FIFOs */ + writel(control & ~SPI_CONTROL_SPIEN, regs + SPI_CONTROL); + writel(control, regs + SPI_CONTROL); +} + +static void restore_state(struct driver_data *drv_data) +{ + void __iomem *regs = drv_data->regs; + struct chip_data *chip = drv_data->cur_chip; + + /* Load chip registers */ + dev_dbg(&drv_data->pdev->dev, + "restore_state\n" + " test = 0x%08X\n" + " control = 0x%08X\n", + chip->test, + chip->control); + writel(chip->test, regs + SPI_TEST); + writel(chip->period, regs + SPI_PERIOD); + writel(0, regs + SPI_INT_STATUS); + writel(chip->control, regs + SPI_CONTROL); +} + +static void null_cs_control(u32 command) +{ +} + +static inline u32 data_to_write(struct driver_data *drv_data) +{ + return ((u32)(drv_data->tx_end - drv_data->tx)) / drv_data->n_bytes; +} + +static inline u32 data_to_read(struct driver_data *drv_data) +{ + return ((u32)(drv_data->rx_end - drv_data->rx)) / drv_data->n_bytes; +} + +static int write(struct driver_data *drv_data) +{ + void __iomem *regs = drv_data->regs; + void *tx = drv_data->tx; + void *tx_end = drv_data->tx_end; + u8 n_bytes = drv_data->n_bytes; + u32 remaining_writes; + u32 fifo_avail_space; + u32 n; + u16 d; + + /* Compute how many fifo writes to do */ + remaining_writes = (u32)(tx_end - tx) / n_bytes; + fifo_avail_space = SPI_FIFO_DEPTH - + (readl(regs + SPI_TEST) & SPI_TEST_TXCNT); + if (drv_data->rx && (fifo_avail_space > SPI_FIFO_OVERFLOW_MARGIN)) + /* Fix misunderstood receive overflow */ + fifo_avail_space -= SPI_FIFO_OVERFLOW_MARGIN; + n = min(remaining_writes, fifo_avail_space); + + dev_dbg(&drv_data->pdev->dev, + "write type %s\n" + " remaining writes = %d\n" + " fifo avail space = %d\n" + " fifo writes = %d\n", + (n_bytes == 1) ? "u8" : "u16", + remaining_writes, + fifo_avail_space, + n); + + if (n > 0) { + /* Fill SPI TXFIFO */ + if (drv_data->rd_only) { + tx += n * n_bytes; + while (n--) + writel(SPI_DUMMY_u16, regs + SPI_TXDATA); + } else { + if (n_bytes == 1) { + while (n--) { + d = *(u8*)tx; + writel(d, regs + SPI_TXDATA); + tx += 1; + } + } else { + while (n--) { + d = *(u16*)tx; + writel(d, regs + SPI_TXDATA); + tx += 2; + } + } + } + + /* Trigger transfer */ + writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH, + regs + SPI_CONTROL); + + /* Update tx pointer */ + drv_data->tx = tx; + } + + return (tx >= tx_end); +} + +static int read(struct driver_data *drv_data) +{ + void __iomem *regs = drv_data->regs; + void *rx = drv_data->rx; + void *rx_end = drv_data->rx_end; + u8 n_bytes = drv_data->n_bytes; + u32 remaining_reads; + u32 fifo_rxcnt; + u32 n; + u16 d; + + /* Compute how many fifo reads to do */ + remaining_reads = (u32)(rx_end - rx) / n_bytes; + fifo_rxcnt = (readl(regs + SPI_TEST) & SPI_TEST_RXCNT) >> + SPI_TEST_RXCNT_LSB; + n = min(remaining_reads, fifo_rxcnt); + + dev_dbg(&drv_data->pdev->dev, + "read type %s\n" + " remaining reads = %d\n" + " fifo rx count = %d\n" + " fifo reads = %d\n", + (n_bytes == 1) ? "u8" : "u16", + remaining_reads, + fifo_rxcnt, + n); + + if (n > 0) { + /* Read SPI RXFIFO */ + if (n_bytes == 1) { + while (n--) { + d = readl(regs + SPI_RXDATA); + *((u8*)rx) = d; + rx += 1; + } + } else { + while (n--) { + d = readl(regs + SPI_RXDATA); + *((u16*)rx) = d; + rx += 2; + } + } + + /* Update rx pointer */ + drv_data->rx = rx; + } + + return (rx >= rx_end); +} + +static void *next_transfer(struct driver_data *drv_data) +{ + struct spi_message *msg = drv_data->cur_msg; + struct spi_transfer *trans = drv_data->cur_transfer; + + /* Move to next transfer */ + if (trans->transfer_list.next != &msg->transfers) { + drv_data->cur_transfer = + list_entry(trans->transfer_list.next, + struct spi_transfer, + transfer_list); + return RUNNING_STATE; + } + + return DONE_STATE; +} + +static int map_dma_buffers(struct driver_data *drv_data) +{ + struct spi_message *msg; + struct device *dev; + void *buf; + + drv_data->rx_dma_needs_unmap = 0; + drv_data->tx_dma_needs_unmap = 0; + + if (!drv_data->master_info->enable_dma || + !drv_data->cur_chip->enable_dma) + return -1; + + msg = drv_data->cur_msg; + dev = &msg->spi->dev; + if (msg->is_dma_mapped) { + if (drv_data->tx_dma) + /* The caller provided at least dma and cpu virtual + address for write; pump_transfers() will consider the + transfer as write only if cpu rx virtual address is + NULL */ + return 0; + + if (drv_data->rx_dma) { + /* The caller provided dma and cpu virtual address to + performe read only transfer --> + use drv_data->dummy_dma_buf for dummy writes to + achive reads */ + buf = &drv_data->dummy_dma_buf; + drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf); + drv_data->tx_dma = dma_map_single(dev, + buf, + drv_data->tx_map_len, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, drv_data->tx_dma)) + return -1; + + drv_data->tx_dma_needs_unmap = 1; + + /* Flags transfer as rd_only for pump_transfers() DMA + regs programming (should be redundant) */ + drv_data->tx = NULL; + + return 0; + } + } + + if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx)) + return -1; + + if (drv_data->tx == NULL) { + /* Read only message --> use drv_data->dummy_dma_buf for dummy + writes to achive reads */ + buf = &drv_data->dummy_dma_buf; + drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf); + } else { + buf = drv_data->tx; + drv_data->tx_map_len = drv_data->len; + } + drv_data->tx_dma = dma_map_single(dev, + buf, + drv_data->tx_map_len, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, drv_data->tx_dma)) + return -1; + drv_data->tx_dma_needs_unmap = 1; + + /* NULL rx means write-only transfer and no map needed + * since rx DMA will not be used */ + if (drv_data->rx) { + buf = drv_data->rx; + drv_data->rx_dma = dma_map_single(dev, + buf, + drv_data->len, + DMA_FROM_DEVICE); + if (dma_mapping_error(dev, drv_data->rx_dma)) { + if (drv_data->tx_dma) { + dma_unmap_single(dev, + drv_data->tx_dma, + drv_data->tx_map_len, + DMA_TO_DEVICE); + drv_data->tx_dma_needs_unmap = 0; + } + return -1; + } + drv_data->rx_dma_needs_unmap = 1; + } + + return 0; +} + +static void unmap_dma_buffers(struct driver_data *drv_data) +{ + struct spi_message *msg = drv_data->cur_msg; + struct device *dev = &msg->spi->dev; + + if (drv_data->rx_dma_needs_unmap) { + dma_unmap_single(dev, + drv_data->rx_dma, + drv_data->len, + DMA_FROM_DEVICE); + drv_data->rx_dma_needs_unmap = 0; + } + if (drv_data->tx_dma_needs_unmap) { + dma_unmap_single(dev, + drv_data->tx_dma, + drv_data->tx_map_len, + DMA_TO_DEVICE); + drv_data->tx_dma_needs_unmap = 0; + } +} + +/* Caller already set message->status (dma is already blocked) */ +static void giveback(struct spi_message *message, struct driver_data *drv_data) +{ + void __iomem *regs = drv_data->regs; + + /* Bring SPI to sleep; restore_state() and pump_transfer() + will do new setup */ + writel(0, regs + SPI_INT_STATUS); + writel(0, regs + SPI_DMA); + + /* Unconditioned deselct */ + drv_data->cs_control(SPI_CS_DEASSERT); + + message->state = NULL; + if (message->complete) + message->complete(message->context); + + drv_data->cur_msg = NULL; + drv_data->cur_transfer = NULL; + drv_data->cur_chip = NULL; + queue_work(drv_data->workqueue, &drv_data->work); +} + +static void dma_err_handler(int channel, void *data, int errcode) +{ + struct driver_data *drv_data = data; + struct spi_message *msg = drv_data->cur_msg; + + dev_dbg(&drv_data->pdev->dev, "dma_err_handler\n"); + + /* Disable both rx and tx dma channels */ + imx_dma_disable(drv_data->rx_channel); + imx_dma_disable(drv_data->tx_channel); + unmap_dma_buffers(drv_data); + + flush(drv_data); + + msg->state = ERROR_STATE; + tasklet_schedule(&drv_data->pump_transfers); +} + +static void dma_tx_handler(int channel, void *data) +{ + struct driver_data *drv_data = data; + + dev_dbg(&drv_data->pdev->dev, "dma_tx_handler\n"); + + imx_dma_disable(channel); + + /* Now waits for TX FIFO empty */ + writel(SPI_INTEN_TE, drv_data->regs + SPI_INT_STATUS); +} + +static irqreturn_t dma_transfer(struct driver_data *drv_data) +{ + u32 status; + struct spi_message *msg = drv_data->cur_msg; + void __iomem *regs = drv_data->regs; + + status = readl(regs + SPI_INT_STATUS); + + if ((status & (SPI_INTEN_RO | SPI_STATUS_RO)) + == (SPI_INTEN_RO | SPI_STATUS_RO)) { + writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS); + + imx_dma_disable(drv_data->tx_channel); + imx_dma_disable(drv_data->rx_channel); + unmap_dma_buffers(drv_data); + + flush(drv_data); + + dev_warn(&drv_data->pdev->dev, + "dma_transfer - fifo overun\n"); + + msg->state = ERROR_STATE; + tasklet_schedule(&drv_data->pump_transfers); + + return IRQ_HANDLED; + } + + if (status & SPI_STATUS_TE) { + writel(status & ~SPI_INTEN_TE, regs + SPI_INT_STATUS); + + if (drv_data->rx) { + /* Wait end of transfer before read trailing data */ + while (readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) + cpu_relax(); + + imx_dma_disable(drv_data->rx_channel); + unmap_dma_buffers(drv_data); + + /* Release chip select if requested, transfer delays are + handled in pump_transfers() */ + if (drv_data->cs_change) + drv_data->cs_control(SPI_CS_DEASSERT); + + /* Calculate number of trailing data and read them */ + dev_dbg(&drv_data->pdev->dev, + "dma_transfer - test = 0x%08X\n", + readl(regs + SPI_TEST)); + drv_data->rx = drv_data->rx_end - + ((readl(regs + SPI_TEST) & + SPI_TEST_RXCNT) >> + SPI_TEST_RXCNT_LSB)*drv_data->n_bytes; + read(drv_data); + } else { + /* Write only transfer */ + unmap_dma_buffers(drv_data); + + flush(drv_data); + } + + /* End of transfer, update total byte transfered */ + msg->actual_length += drv_data->len; + + /* Move to next transfer */ + msg->state = next_transfer(drv_data); + + /* Schedule transfer tasklet */ + tasklet_schedule(&drv_data->pump_transfers); + + return IRQ_HANDLED; + } + + /* Opps problem detected */ + return IRQ_NONE; +} + +static irqreturn_t interrupt_wronly_transfer(struct driver_data *drv_data) +{ + struct spi_message *msg = drv_data->cur_msg; + void __iomem *regs = drv_data->regs; + u32 status; + irqreturn_t handled = IRQ_NONE; + + status = readl(regs + SPI_INT_STATUS); + + if (status & SPI_INTEN_TE) { + /* TXFIFO Empty Interrupt on the last transfered word */ + writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS); + dev_dbg(&drv_data->pdev->dev, + "interrupt_wronly_transfer - end of tx\n"); + + flush(drv_data); + + /* Update total byte transfered */ + msg->actual_length += drv_data->len; + + /* Move to next transfer */ + msg->state = next_transfer(drv_data); + + /* Schedule transfer tasklet */ + tasklet_schedule(&drv_data->pump_transfers); + + return IRQ_HANDLED; + } else { + while (status & SPI_STATUS_TH) { + dev_dbg(&drv_data->pdev->dev, + "interrupt_wronly_transfer - status = 0x%08X\n", + status); + + /* Pump data */ + if (write(drv_data)) { + /* End of TXFIFO writes, + now wait until TXFIFO is empty */ + writel(SPI_INTEN_TE, regs + SPI_INT_STATUS); + return IRQ_HANDLED; + } + + status = readl(regs + SPI_INT_STATUS); + + /* We did something */ + handled = IRQ_HANDLED; + } + } + + return handled; +} + +static irqreturn_t interrupt_transfer(struct driver_data *drv_data) +{ + struct spi_message *msg = drv_data->cur_msg; + void __iomem *regs = drv_data->regs; + u32 status, control; + irqreturn_t handled = IRQ_NONE; + unsigned long limit; + + status = readl(regs + SPI_INT_STATUS); + + if (status & SPI_INTEN_TE) { + /* TXFIFO Empty Interrupt on the last transfered word */ + writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS); + dev_dbg(&drv_data->pdev->dev, + "interrupt_transfer - end of tx\n"); + + if (msg->state == ERROR_STATE) { + /* RXFIFO overrun was detected and message aborted */ + flush(drv_data); + } else { + /* Wait for end of transaction */ + do { + control = readl(regs + SPI_CONTROL); + } while (control & SPI_CONTROL_XCH); + + /* Release chip select if requested, transfer delays are + handled in pump_transfers */ + if (drv_data->cs_change) + drv_data->cs_control(SPI_CS_DEASSERT); + + /* Read trailing bytes */ + limit = loops_per_jiffy << 1; + while ((read(drv_data) == 0) && --limit) + cpu_relax(); + + if (limit == 0) + dev_err(&drv_data->pdev->dev, + "interrupt_transfer - " + "trailing byte read failed\n"); + else + dev_dbg(&drv_data->pdev->dev, + "interrupt_transfer - end of rx\n"); + + /* Update total byte transfered */ + msg->actual_length += drv_data->len; + + /* Move to next transfer */ + msg->state = next_transfer(drv_data); + } + + /* Schedule transfer tasklet */ + tasklet_schedule(&drv_data->pump_transfers); + + return IRQ_HANDLED; + } else { + while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) { + dev_dbg(&drv_data->pdev->dev, + "interrupt_transfer - status = 0x%08X\n", + status); + + if (status & SPI_STATUS_RO) { + /* RXFIFO overrun, abort message end wait + until TXFIFO is empty */ + writel(SPI_INTEN_TE, regs + SPI_INT_STATUS); + + dev_warn(&drv_data->pdev->dev, + "interrupt_transfer - fifo overun\n" + " data not yet written = %d\n" + " data not yet read = %d\n", + data_to_write(drv_data), + data_to_read(drv_data)); + + msg->state = ERROR_STATE; + + return IRQ_HANDLED; + } + + /* Pump data */ + read(drv_data); + if (write(drv_data)) { + /* End of TXFIFO writes, + now wait until TXFIFO is empty */ + writel(SPI_INTEN_TE, regs + SPI_INT_STATUS); + return IRQ_HANDLED; + } + + status = readl(regs + SPI_INT_STATUS); + + /* We did something */ + handled = IRQ_HANDLED; + } + } + + return handled; +} + +static irqreturn_t spi_int(int irq, void *dev_id) +{ + struct driver_data *drv_data = (struct driver_data *)dev_id; + + if (!drv_data->cur_msg) { + dev_err(&drv_data->pdev->dev, + "spi_int - bad message state\n"); + /* Never fail */ + return IRQ_HANDLED; + } + + return drv_data->transfer_handler(drv_data); +} + +static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate) +{ + return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13)); +} + +static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz) +{ + u32 div; + u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2; + + for (div = SPI_PERCLK2_DIV_MIN; + div <= SPI_PERCLK2_DIV_MAX; + div++, quantized_hz >>= 1) { + if (quantized_hz <= speed_hz) + /* Max available speed LEQ required speed */ + return div << 13; + } + return SPI_CONTROL_DATARATE_BAD; +} + +static void pump_transfers(unsigned long data) +{ + struct driver_data *drv_data = (struct driver_data *)data; + struct spi_message *message; + struct spi_transfer *transfer, *previous; + struct chip_data *chip; + void __iomem *regs; + u32 tmp, control; + + dev_dbg(&drv_data->pdev->dev, "pump_transfer\n"); + + message = drv_data->cur_msg; + + /* Handle for abort */ + if (message->state == ERROR_STATE) { + message->status = -EIO; + giveback(message, drv_data); + return; + } + + /* Handle end of message */ + if (message->state == DONE_STATE) { + message->status = 0; + giveback(message, drv_data); + return; + } + + chip = drv_data->cur_chip; + + /* Delay if requested at end of transfer*/ + transfer = drv_data->cur_transfer; + if (message->state == RUNNING_STATE) { + previous = list_entry(transfer->transfer_list.prev, + struct spi_transfer, + transfer_list); + if (previous->delay_usecs) + udelay(previous->delay_usecs); + } else { + /* START_STATE */ + message->state = RUNNING_STATE; + drv_data->cs_control = chip->cs_control; + } + + transfer = drv_data->cur_transfer; + drv_data->tx = (void *)transfer->tx_buf; + drv_data->tx_end = drv_data->tx + transfer->len; + drv_data->rx = transfer->rx_buf; + drv_data->rx_end = drv_data->rx + transfer->len; + drv_data->rx_dma = transfer->rx_dma; + drv_data->tx_dma = transfer->tx_dma; + drv_data->len = transfer->len; + drv_data->cs_change = transfer->cs_change; + drv_data->rd_only = (drv_data->tx == NULL); + + regs = drv_data->regs; + control = readl(regs + SPI_CONTROL); + + /* Bits per word setup */ + tmp = transfer->bits_per_word; + if (tmp == 0) { + /* Use device setup */ + tmp = chip->bits_per_word; + drv_data->n_bytes = chip->n_bytes; + } else + /* Use per-transfer setup */ + drv_data->n_bytes = (tmp <= 8) ? 1 : 2; + u32_EDIT(control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1); + + /* Speed setup (surely valid because already checked) */ + tmp = transfer->speed_hz; + if (tmp == 0) + tmp = chip->max_speed_hz; + tmp = spi_data_rate(drv_data, tmp); + u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); + + writel(control, regs + SPI_CONTROL); + + /* Assert device chip-select */ + drv_data->cs_control(SPI_CS_ASSERT); + + /* DMA cannot read/write SPI FIFOs other than 16 bits at a time; hence + if bits_per_word is less or equal 8 PIO transfers are performed. + Moreover DMA is convinient for transfer length bigger than FIFOs + byte size. */ + if ((drv_data->n_bytes == 2) && + (drv_data->len > SPI_FIFO_DEPTH*SPI_FIFO_BYTE_WIDTH) && + (map_dma_buffers(drv_data) == 0)) { + dev_dbg(&drv_data->pdev->dev, + "pump dma transfer\n" + " tx = %p\n" + " tx_dma = %08X\n" + " rx = %p\n" + " rx_dma = %08X\n" + " len = %d\n", + drv_data->tx, + (unsigned int)drv_data->tx_dma, + drv_data->rx, + (unsigned int)drv_data->rx_dma, + drv_data->len); + + /* Ensure we have the correct interrupt handler */ + drv_data->transfer_handler = dma_transfer; + + /* Trigger transfer */ + writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH, + regs + SPI_CONTROL); + + /* Setup tx DMA */ + if (drv_data->tx) + /* Linear source address */ + CCR(drv_data->tx_channel) = + CCR_DMOD_FIFO | + CCR_SMOD_LINEAR | + CCR_SSIZ_32 | CCR_DSIZ_16 | + CCR_REN; + else + /* Read only transfer -> fixed source address for + dummy write to achive read */ + CCR(drv_data->tx_channel) = + CCR_DMOD_FIFO | + CCR_SMOD_FIFO | + CCR_SSIZ_32 | CCR_DSIZ_16 | + CCR_REN; + + imx_dma_setup_single( + drv_data->tx_channel, + drv_data->tx_dma, + drv_data->len, + drv_data->rd_data_phys + 4, + DMA_MODE_WRITE); + + if (drv_data->rx) { + /* Setup rx DMA for linear destination address */ + CCR(drv_data->rx_channel) = + CCR_DMOD_LINEAR | + CCR_SMOD_FIFO | + CCR_DSIZ_32 | CCR_SSIZ_16 | + CCR_REN; + imx_dma_setup_single( + drv_data->rx_channel, + drv_data->rx_dma, + drv_data->len, + drv_data->rd_data_phys, + DMA_MODE_READ); + imx_dma_enable(drv_data->rx_channel); + + /* Enable SPI interrupt */ + writel(SPI_INTEN_RO, regs + SPI_INT_STATUS); + + /* Set SPI to request DMA service on both + Rx and Tx half fifo watermark */ + writel(SPI_DMA_RHDEN | SPI_DMA_THDEN, regs + SPI_DMA); + } else + /* Write only access -> set SPI to request DMA + service on Tx half fifo watermark */ + writel(SPI_DMA_THDEN, regs + SPI_DMA); + + imx_dma_enable(drv_data->tx_channel); + } else { + dev_dbg(&drv_data->pdev->dev, + "pump pio transfer\n" + " tx = %p\n" + " rx = %p\n" + " len = %d\n", + drv_data->tx, + drv_data->rx, + drv_data->len); + + /* Ensure we have the correct interrupt handler */ + if (drv_data->rx) + drv_data->transfer_handler = interrupt_transfer; + else + drv_data->transfer_handler = interrupt_wronly_transfer; + + /* Enable SPI interrupt */ + if (drv_data->rx) + writel(SPI_INTEN_TH | SPI_INTEN_RO, + regs + SPI_INT_STATUS); + else + writel(SPI_INTEN_TH, regs + SPI_INT_STATUS); + } +} + +static void pump_messages(struct work_struct *work) +{ + struct driver_data *drv_data = + container_of(work, struct driver_data, work); + unsigned long flags; + + /* Lock queue and check for queue work */ + spin_lock_irqsave(&drv_data->lock, flags); + if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) { + drv_data->busy = 0; + spin_unlock_irqrestore(&drv_data->lock, flags); + return; + } + + /* Make sure we are not already running a message */ + if (drv_data->cur_msg) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return; + } + + /* Extract head of queue */ + drv_data->cur_msg = list_entry(drv_data->queue.next, + struct spi_message, queue); + list_del_init(&drv_data->cur_msg->queue); + drv_data->busy = 1; + spin_unlock_irqrestore(&drv_data->lock, flags); + + /* Initial message state */ + drv_data->cur_msg->state = START_STATE; + drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, + struct spi_transfer, + transfer_list); + + /* Setup the SPI using the per chip configuration */ + drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); + restore_state(drv_data); + + /* Mark as busy and launch transfers */ + tasklet_schedule(&drv_data->pump_transfers); +} + +static int transfer(struct spi_device *spi, struct spi_message *msg) +{ + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + u32 min_speed_hz, max_speed_hz, tmp; + struct spi_transfer *trans; + unsigned long flags; + + msg->actual_length = 0; + + /* Per transfer setup check */ + min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN); + max_speed_hz = spi->max_speed_hz; + list_for_each_entry(trans, &msg->transfers, transfer_list) { + tmp = trans->bits_per_word; + if (tmp > 16) { + dev_err(&drv_data->pdev->dev, + "message rejected : " + "invalid transfer bits_per_word (%d bits)\n", + tmp); + goto msg_rejected; + } + tmp = trans->speed_hz; + if (tmp) { + if (tmp < min_speed_hz) { + dev_err(&drv_data->pdev->dev, + "message rejected : " + "device min speed (%d Hz) exceeds " + "required transfer speed (%d Hz)\n", + min_speed_hz, + tmp); + goto msg_rejected; + } else if (tmp > max_speed_hz) { + dev_err(&drv_data->pdev->dev, + "message rejected : " + "transfer speed (%d Hz) exceeds " + "device max speed (%d Hz)\n", + tmp, + max_speed_hz); + goto msg_rejected; + } + } + } + + /* Message accepted */ + msg->status = -EINPROGRESS; + msg->state = START_STATE; + + spin_lock_irqsave(&drv_data->lock, flags); + if (drv_data->run == QUEUE_STOPPED) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return -ESHUTDOWN; + } + + list_add_tail(&msg->queue, &drv_data->queue); + if (drv_data->run == QUEUE_RUNNING && !drv_data->busy) + queue_work(drv_data->workqueue, &drv_data->work); + + spin_unlock_irqrestore(&drv_data->lock, flags); + return 0; + +msg_rejected: + /* Message rejected and not queued */ + msg->status = -EINVAL; + msg->state = ERROR_STATE; + if (msg->complete) + msg->complete(msg->context); + return -EINVAL; +} + +/* On first setup bad values must free chip_data memory since will cause + spi_new_device to fail. Bad value setup from protocol driver are simply not + applied and notified to the calling driver. */ +static int setup(struct spi_device *spi) +{ + struct driver_data *drv_data = spi_master_get_devdata(spi->master); + struct spi_imx_chip *chip_info; + struct chip_data *chip; + int first_setup = 0; + u32 tmp; + int status = 0; + + /* Get controller data */ + chip_info = spi->controller_data; + + /* Get controller_state */ + chip = spi_get_ctldata(spi); + if (chip == NULL) { + first_setup = 1; + + chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + if (!chip) { + dev_err(&spi->dev, + "setup - cannot allocate controller state\n"); + return -ENOMEM; + } + chip->control = SPI_DEFAULT_CONTROL; + + if (chip_info == NULL) { + /* spi_board_info.controller_data not is supplied */ + chip_info = kzalloc(sizeof(struct spi_imx_chip), + GFP_KERNEL); + if (!chip_info) { + dev_err(&spi->dev, + "setup - " + "cannot allocate controller data\n"); + status = -ENOMEM; + goto err_first_setup; + } + /* Set controller data default value */ + chip_info->enable_loopback = + SPI_DEFAULT_ENABLE_LOOPBACK; + chip_info->enable_dma = SPI_DEFAULT_ENABLE_DMA; + chip_info->ins_ss_pulse = 1; + chip_info->bclk_wait = SPI_DEFAULT_PERIOD_WAIT; + chip_info->cs_control = null_cs_control; + } + } + + /* Now set controller state based on controller data */ + + if (first_setup) { + /* SPI loopback */ + if (chip_info->enable_loopback) + chip->test = SPI_TEST_LBC; + else + chip->test = 0; + + /* SPI dma driven */ + chip->enable_dma = chip_info->enable_dma; + + /* SPI /SS pulse between spi burst */ + if (chip_info->ins_ss_pulse) + u32_EDIT(chip->control, + SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_1); + else + u32_EDIT(chip->control, + SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_0); + + /* SPI bclk waits between each bits_per_word spi burst */ + if (chip_info->bclk_wait > SPI_PERIOD_MAX_WAIT) { + dev_err(&spi->dev, + "setup - " + "bclk_wait exceeds max allowed (%d)\n", + SPI_PERIOD_MAX_WAIT); + goto err_first_setup; + } + chip->period = SPI_PERIOD_CSRC_BCLK | + (chip_info->bclk_wait & SPI_PERIOD_WAIT); + } + + /* SPI mode */ + tmp = spi->mode; + if (tmp & SPI_CS_HIGH) { + u32_EDIT(chip->control, + SPI_CONTROL_SSPOL, SPI_CONTROL_SSPOL_ACT_HIGH); + } + switch (tmp & SPI_MODE_3) { + case SPI_MODE_0: + tmp = 0; + break; + case SPI_MODE_1: + tmp = SPI_CONTROL_PHA_1; + break; + case SPI_MODE_2: + tmp = SPI_CONTROL_POL_ACT_LOW; + break; + default: + /* SPI_MODE_3 */ + tmp = SPI_CONTROL_PHA_1 | SPI_CONTROL_POL_ACT_LOW; + break; + } + u32_EDIT(chip->control, SPI_CONTROL_POL | SPI_CONTROL_PHA, tmp); + + /* SPI word width */ + tmp = spi->bits_per_word; + if (tmp > 16) { + status = -EINVAL; + dev_err(&spi->dev, + "setup - " + "invalid bits_per_word (%d)\n", + tmp); + if (first_setup) + goto err_first_setup; + else { + /* Undo setup using chip as backup copy */ + tmp = chip->bits_per_word; + spi->bits_per_word = tmp; + } + } + chip->bits_per_word = tmp; + u32_EDIT(chip->control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1); + chip->n_bytes = (tmp <= 8) ? 1 : 2; + + /* SPI datarate */ + tmp = spi_data_rate(drv_data, spi->max_speed_hz); + if (tmp == SPI_CONTROL_DATARATE_BAD) { + status = -EINVAL; + dev_err(&spi->dev, + "setup - " + "HW min speed (%d Hz) exceeds required " + "max speed (%d Hz)\n", + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), + spi->max_speed_hz); + if (first_setup) + goto err_first_setup; + else + /* Undo setup using chip as backup copy */ + spi->max_speed_hz = chip->max_speed_hz; + } else { + u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); + /* Actual rounded max_speed_hz */ + tmp = spi_speed_hz(drv_data, tmp); + spi->max_speed_hz = tmp; + chip->max_speed_hz = tmp; + } + + /* SPI chip-select management */ + if (chip_info->cs_control) + chip->cs_control = chip_info->cs_control; + else + chip->cs_control = null_cs_control; + + /* Save controller_state */ + spi_set_ctldata(spi, chip); + + /* Summary */ + dev_dbg(&spi->dev, + "setup succeded\n" + " loopback enable = %s\n" + " dma enable = %s\n" + " insert /ss pulse = %s\n" + " period wait = %d\n" + " mode = %d\n" + " bits per word = %d\n" + " min speed = %d Hz\n" + " rounded max speed = %d Hz\n", + chip->test & SPI_TEST_LBC ? "Yes" : "No", + chip->enable_dma ? "Yes" : "No", + chip->control & SPI_CONTROL_SSCTL ? "Yes" : "No", + chip->period & SPI_PERIOD_WAIT, + spi->mode, + spi->bits_per_word, + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), + spi->max_speed_hz); + return status; + +err_first_setup: + kfree(chip); + return status; +} + +static void cleanup(struct spi_device *spi) +{ + kfree(spi_get_ctldata(spi)); +} + +static int __init init_queue(struct driver_data *drv_data) +{ + INIT_LIST_HEAD(&drv_data->queue); + spin_lock_init(&drv_data->lock); + + drv_data->run = QUEUE_STOPPED; + drv_data->busy = 0; + + tasklet_init(&drv_data->pump_transfers, + pump_transfers, (unsigned long)drv_data); + + INIT_WORK(&drv_data->work, pump_messages); + drv_data->workqueue = create_singlethread_workqueue( + dev_name(drv_data->master->dev.parent)); + if (drv_data->workqueue == NULL) + return -EBUSY; + + return 0; +} + +static int start_queue(struct driver_data *drv_data) +{ + unsigned long flags; + + spin_lock_irqsave(&drv_data->lock, flags); + + if (drv_data->run == QUEUE_RUNNING || drv_data->busy) { + spin_unlock_irqrestore(&drv_data->lock, flags); + return -EBUSY; + } + + drv_data->run = QUEUE_RUNNING; + drv_data->cur_msg = NULL; + drv_data->cur_transfer = NULL; + drv_data->cur_chip = NULL; + spin_unlock_irqrestore(&drv_data->lock, flags); + + queue_work(drv_data->workqueue, &drv_data->work); + + return 0; +} + +static int stop_queue(struct driver_data *drv_data) +{ + unsigned long flags; + unsigned limit = 500; + int status = 0; + + spin_lock_irqsave(&drv_data->lock, flags); + + /* This is a bit lame, but is optimized for the common execution path. + * A wait_queue on the drv_data->busy could be used, but then the common + * execution path (pump_messages) would be required to call wake_up or + * friends on every SPI message. Do this instead */ + drv_data->run = QUEUE_STOPPED; + while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { + spin_unlock_irqrestore(&drv_data->lock, flags); + msleep(10); + spin_lock_irqsave(&drv_data->lock, flags); + } + + if (!list_empty(&drv_data->queue) || drv_data->busy) + status = -EBUSY; + + spin_unlock_irqrestore(&drv_data->lock, flags); + + return status; +} + +static int destroy_queue(struct driver_data *drv_data) +{ + int status; + + status = stop_queue(drv_data); + if (status != 0) + return status; + + if (drv_data->workqueue) + destroy_workqueue(drv_data->workqueue); + + return 0; +} + +static int __init spi_imx_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct spi_imx_master *platform_info; + struct spi_master *master; + struct driver_data *drv_data; + struct resource *res; + int irq, status = 0; + + platform_info = dev->platform_data; + if (platform_info == NULL) { + dev_err(&pdev->dev, "probe - no platform data supplied\n"); + status = -ENODEV; + goto err_no_pdata; + } + + /* Allocate master with space for drv_data */ + master = spi_alloc_master(dev, sizeof(struct driver_data)); + if (!master) { + dev_err(&pdev->dev, "probe - cannot alloc spi_master\n"); + status = -ENOMEM; + goto err_no_mem; + } + drv_data = spi_master_get_devdata(master); + drv_data->master = master; + drv_data->master_info = platform_info; + drv_data->pdev = pdev; + + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + + master->bus_num = pdev->id; + master->num_chipselect = platform_info->num_chipselect; + master->dma_alignment = DMA_ALIGNMENT; + master->cleanup = cleanup; + master->setup = setup; + master->transfer = transfer; + + drv_data->dummy_dma_buf = SPI_DUMMY_u32; + + drv_data->clk = clk_get(&pdev->dev, "perclk2"); + if (IS_ERR(drv_data->clk)) { + dev_err(&pdev->dev, "probe - cannot get clock\n"); + status = PTR_ERR(drv_data->clk); + goto err_no_clk; + } + clk_enable(drv_data->clk); + + /* Find and map resources */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "probe - MEM resources not defined\n"); + status = -ENODEV; + goto err_no_iores; + } + drv_data->ioarea = request_mem_region(res->start, + res->end - res->start + 1, + pdev->name); + if (drv_data->ioarea == NULL) { + dev_err(&pdev->dev, "probe - cannot reserve region\n"); + status = -ENXIO; + goto err_no_iores; + } + drv_data->regs = ioremap(res->start, res->end - res->start + 1); + if (drv_data->regs == NULL) { + dev_err(&pdev->dev, "probe - cannot map IO\n"); + status = -ENXIO; + goto err_no_iomap; + } + drv_data->rd_data_phys = (dma_addr_t)res->start; + + /* Attach to IRQ */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "probe - IRQ resource not defined\n"); + status = -ENODEV; + goto err_no_irqres; + } + status = request_irq(irq, spi_int, IRQF_DISABLED, + dev_name(dev), drv_data); + if (status < 0) { + dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status); + goto err_no_irqres; + } + + /* Setup DMA if requested */ + drv_data->tx_channel = -1; + drv_data->rx_channel = -1; + if (platform_info->enable_dma) { + /* Get rx DMA channel */ + drv_data->rx_channel = imx_dma_request_by_prio("spi_imx_rx", + DMA_PRIO_HIGH); + if (drv_data->rx_channel < 0) { + dev_err(dev, + "probe - problem (%d) requesting rx channel\n", + drv_data->rx_channel); + goto err_no_rxdma; + } else + imx_dma_setup_handlers(drv_data->rx_channel, NULL, + dma_err_handler, drv_data); + + /* Get tx DMA channel */ + drv_data->tx_channel = imx_dma_request_by_prio("spi_imx_tx", + DMA_PRIO_MEDIUM); + if (drv_data->tx_channel < 0) { + dev_err(dev, + "probe - problem (%d) requesting tx channel\n", + drv_data->tx_channel); + imx_dma_free(drv_data->rx_channel); + goto err_no_txdma; + } else + imx_dma_setup_handlers(drv_data->tx_channel, + dma_tx_handler, dma_err_handler, + drv_data); + + /* Set request source and burst length for allocated channels */ + switch (drv_data->pdev->id) { + case 1: + /* Using SPI1 */ + RSSR(drv_data->rx_channel) = DMA_REQ_SPI1_R; + RSSR(drv_data->tx_channel) = DMA_REQ_SPI1_T; + break; + case 2: + /* Using SPI2 */ + RSSR(drv_data->rx_channel) = DMA_REQ_SPI2_R; + RSSR(drv_data->tx_channel) = DMA_REQ_SPI2_T; + break; + default: + dev_err(dev, "probe - bad SPI Id\n"); + imx_dma_free(drv_data->rx_channel); + imx_dma_free(drv_data->tx_channel); + status = -ENODEV; + goto err_no_devid; + } + BLR(drv_data->rx_channel) = SPI_DMA_BLR; + BLR(drv_data->tx_channel) = SPI_DMA_BLR; + } + + /* Load default SPI configuration */ + writel(SPI_RESET_START, drv_data->regs + SPI_RESET); + writel(0, drv_data->regs + SPI_RESET); + writel(SPI_DEFAULT_CONTROL, drv_data->regs + SPI_CONTROL); + + /* Initial and start queue */ + status = init_queue(drv_data); + if (status != 0) { + dev_err(&pdev->dev, "probe - problem initializing queue\n"); + goto err_init_queue; + } + status = start_queue(drv_data); + if (status != 0) { + dev_err(&pdev->dev, "probe - problem starting queue\n"); + goto err_start_queue; + } + + /* Register with the SPI framework */ + platform_set_drvdata(pdev, drv_data); + status = spi_register_master(master); + if (status != 0) { + dev_err(&pdev->dev, "probe - problem registering spi master\n"); + goto err_spi_register; + } + + dev_dbg(dev, "probe succeded\n"); + return 0; + +err_init_queue: +err_start_queue: +err_spi_register: + destroy_queue(drv_data); + +err_no_rxdma: +err_no_txdma: +err_no_devid: + free_irq(irq, drv_data); + +err_no_irqres: + iounmap(drv_data->regs); + +err_no_iomap: + release_resource(drv_data->ioarea); + kfree(drv_data->ioarea); + +err_no_iores: + clk_disable(drv_data->clk); + clk_put(drv_data->clk); + +err_no_clk: + spi_master_put(master); + +err_no_pdata: +err_no_mem: + return status; +} + +static int __exit spi_imx_remove(struct platform_device *pdev) +{ + struct driver_data *drv_data = platform_get_drvdata(pdev); + int irq; + int status = 0; + + if (!drv_data) + return 0; + + tasklet_kill(&drv_data->pump_transfers); + + /* Remove the queue */ + status = destroy_queue(drv_data); + if (status != 0) { + dev_err(&pdev->dev, "queue remove failed (%d)\n", status); + return status; + } + + /* Reset SPI */ + writel(SPI_RESET_START, drv_data->regs + SPI_RESET); + writel(0, drv_data->regs + SPI_RESET); + + /* Release DMA */ + if (drv_data->master_info->enable_dma) { + RSSR(drv_data->rx_channel) = 0; + RSSR(drv_data->tx_channel) = 0; + imx_dma_free(drv_data->tx_channel); + imx_dma_free(drv_data->rx_channel); + } + + /* Release IRQ */ + irq = platform_get_irq(pdev, 0); + if (irq >= 0) + free_irq(irq, drv_data); + + clk_disable(drv_data->clk); + clk_put(drv_data->clk); + + /* Release map resources */ + iounmap(drv_data->regs); + release_resource(drv_data->ioarea); + kfree(drv_data->ioarea); + + /* Disconnect from the SPI framework */ + spi_unregister_master(drv_data->master); + spi_master_put(drv_data->master); + + /* Prevent double remove */ + platform_set_drvdata(pdev, NULL); + + dev_dbg(&pdev->dev, "remove succeded\n"); + + return 0; +} + +static void spi_imx_shutdown(struct platform_device *pdev) +{ + struct driver_data *drv_data = platform_get_drvdata(pdev); + + /* Reset SPI */ + writel(SPI_RESET_START, drv_data->regs + SPI_RESET); + writel(0, drv_data->regs + SPI_RESET); + + dev_dbg(&pdev->dev, "shutdown succeded\n"); +} + +#ifdef CONFIG_PM + +static int spi_imx_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct driver_data *drv_data = platform_get_drvdata(pdev); + int status = 0; + + status = stop_queue(drv_data); + if (status != 0) { + dev_warn(&pdev->dev, "suspend cannot stop queue\n"); + return status; + } + + dev_dbg(&pdev->dev, "suspended\n"); + + return 0; +} + +static int spi_imx_resume(struct platform_device *pdev) +{ + struct driver_data *drv_data = platform_get_drvdata(pdev); + int status = 0; + + /* Start the queue running */ + status = start_queue(drv_data); + if (status != 0) + dev_err(&pdev->dev, "problem starting queue (%d)\n", status); + else + dev_dbg(&pdev->dev, "resumed\n"); + + return status; +} +#else +#define spi_imx_suspend NULL +#define spi_imx_resume NULL +#endif /* CONFIG_PM */ + +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:spi_imx"); + +static struct platform_driver driver = { + .driver = { + .name = "spi_imx", + .owner = THIS_MODULE, + }, + .remove = __exit_p(spi_imx_remove), + .shutdown = spi_imx_shutdown, + .suspend = spi_imx_suspend, + .resume = spi_imx_resume, +}; + +static int __init spi_imx_init(void) +{ + return platform_driver_probe(&driver, spi_imx_probe); +} +module_init(spi_imx_init); + +static void __exit spi_imx_exit(void) +{ + platform_driver_unregister(&driver); +} +module_exit(spi_imx_exit); + +MODULE_AUTHOR("Andrea Paterniani, "); +MODULE_DESCRIPTION("iMX SPI Controller Driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi_ppc4xx.c b/trunk/drivers/spi/spi_ppc4xx.c deleted file mode 100644 index 140a18d6cf3e..000000000000 --- a/trunk/drivers/spi/spi_ppc4xx.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * SPI_PPC4XX SPI controller driver. - * - * Copyright (C) 2007 Gary Jennejohn - * Copyright 2008 Stefan Roese , DENX Software Engineering - * Copyright 2009 Harris Corporation, Steven A. Falco - * - * Based in part on drivers/spi/spi_s3c24xx.c - * - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * 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. - */ - -/* - * The PPC4xx SPI controller has no FIFO so each sent/received byte will - * generate an interrupt to the CPU. This can cause high CPU utilization. - * This driver allows platforms to reduce the interrupt load on the CPU - * during SPI transfers by setting max_speed_hz via the device tree. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -/* bits in mode register - bit 0 is MSb */ - -/* - * SPI_PPC4XX_MODE_SCP = 0 means "data latched on trailing edge of clock" - * SPI_PPC4XX_MODE_SCP = 1 means "data latched on leading edge of clock" - * Note: This is the inverse of CPHA. - */ -#define SPI_PPC4XX_MODE_SCP (0x80 >> 3) - -/* SPI_PPC4XX_MODE_SPE = 1 means "port enabled" */ -#define SPI_PPC4XX_MODE_SPE (0x80 >> 4) - -/* - * SPI_PPC4XX_MODE_RD = 0 means "MSB first" - this is the normal mode - * SPI_PPC4XX_MODE_RD = 1 means "LSB first" - this is bit-reversed mode - * Note: This is identical to SPI_LSB_FIRST. - */ -#define SPI_PPC4XX_MODE_RD (0x80 >> 5) - -/* - * SPI_PPC4XX_MODE_CI = 0 means "clock idles low" - * SPI_PPC4XX_MODE_CI = 1 means "clock idles high" - * Note: This is identical to CPOL. - */ -#define SPI_PPC4XX_MODE_CI (0x80 >> 6) - -/* - * SPI_PPC4XX_MODE_IL = 0 means "loopback disable" - * SPI_PPC4XX_MODE_IL = 1 means "loopback enable" - */ -#define SPI_PPC4XX_MODE_IL (0x80 >> 7) - -/* bits in control register */ -/* starts a transfer when set */ -#define SPI_PPC4XX_CR_STR (0x80 >> 7) - -/* bits in status register */ -/* port is busy with a transfer */ -#define SPI_PPC4XX_SR_BSY (0x80 >> 6) -/* RxD ready */ -#define SPI_PPC4XX_SR_RBR (0x80 >> 7) - -/* clock settings (SCP and CI) for various SPI modes */ -#define SPI_CLK_MODE0 (SPI_PPC4XX_MODE_SCP | 0) -#define SPI_CLK_MODE1 (0 | 0) -#define SPI_CLK_MODE2 (SPI_PPC4XX_MODE_SCP | SPI_PPC4XX_MODE_CI) -#define SPI_CLK_MODE3 (0 | SPI_PPC4XX_MODE_CI) - -#define DRIVER_NAME "spi_ppc4xx_of" - -struct spi_ppc4xx_regs { - u8 mode; - u8 rxd; - u8 txd; - u8 cr; - u8 sr; - u8 dummy; - /* - * Clock divisor modulus register - * This uses the follwing formula: - * SCPClkOut = OPBCLK/(4(CDM + 1)) - * or - * CDM = (OPBCLK/4*SCPClkOut) - 1 - * bit 0 is the MSb! - */ - u8 cdm; -}; - -/* SPI Controller driver's private data. */ -struct ppc4xx_spi { - /* bitbang has to be first */ - struct spi_bitbang bitbang; - struct completion done; - - u64 mapbase; - u64 mapsize; - int irqnum; - /* need this to set the SPI clock */ - unsigned int opb_freq; - - /* for transfers */ - int len; - int count; - /* data buffers */ - const unsigned char *tx; - unsigned char *rx; - - int *gpios; - - struct spi_ppc4xx_regs __iomem *regs; /* pointer to the registers */ - struct spi_master *master; - struct device *dev; -}; - -/* need this so we can set the clock in the chipselect routine */ -struct spi_ppc4xx_cs { - u8 mode; -}; - -static int spi_ppc4xx_txrx(struct spi_device *spi, struct spi_transfer *t) -{ - struct ppc4xx_spi *hw; - u8 data; - - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", - t->tx_buf, t->rx_buf, t->len); - - hw = spi_master_get_devdata(spi->master); - - hw->tx = t->tx_buf; - hw->rx = t->rx_buf; - hw->len = t->len; - hw->count = 0; - - /* send the first byte */ - data = hw->tx ? hw->tx[0] : 0; - out_8(&hw->regs->txd, data); - out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR); - wait_for_completion(&hw->done); - - return hw->count; -} - -static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master); - struct spi_ppc4xx_cs *cs = spi->controller_state; - int scr; - u8 cdm = 0; - u32 speed; - u8 bits_per_word; - - /* Start with the generic configuration for this device. */ - bits_per_word = spi->bits_per_word; - speed = spi->max_speed_hz; - - /* - * Modify the configuration if the transfer overrides it. Do not allow - * the transfer to overwrite the generic configuration with zeros. - */ - if (t) { - if (t->bits_per_word) - bits_per_word = t->bits_per_word; - - if (t->speed_hz) - speed = min(t->speed_hz, spi->max_speed_hz); - } - - if (bits_per_word != 8) { - dev_err(&spi->dev, "invalid bits-per-word (%d)\n", - bits_per_word); - return -EINVAL; - } - - if (!speed || (speed > spi->max_speed_hz)) { - dev_err(&spi->dev, "invalid speed_hz (%d)\n", speed); - return -EINVAL; - } - - /* Write new configration */ - out_8(&hw->regs->mode, cs->mode); - - /* Set the clock */ - /* opb_freq was already divided by 4 */ - scr = (hw->opb_freq / speed) - 1; - if (scr > 0) - cdm = min(scr, 0xff); - - dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", cdm, speed); - - if (in_8(&hw->regs->cdm) != cdm) - out_8(&hw->regs->cdm, cdm); - - spin_lock(&hw->bitbang.lock); - if (!hw->bitbang.busy) { - hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); - /* Need to ndelay here? */ - } - spin_unlock(&hw->bitbang.lock); - - return 0; -} - -static int spi_ppc4xx_setup(struct spi_device *spi) -{ - struct spi_ppc4xx_cs *cs = spi->controller_state; - - if (spi->bits_per_word != 8) { - dev_err(&spi->dev, "invalid bits-per-word (%d)\n", - spi->bits_per_word); - return -EINVAL; - } - - if (!spi->max_speed_hz) { - dev_err(&spi->dev, "invalid max_speed_hz (must be non-zero)\n"); - return -EINVAL; - } - - if (cs == NULL) { - cs = kzalloc(sizeof *cs, GFP_KERNEL); - if (!cs) - return -ENOMEM; - spi->controller_state = cs; - } - - /* - * We set all bits of the SPI0_MODE register, so, - * no need to read-modify-write - */ - cs->mode = SPI_PPC4XX_MODE_SPE; - - switch (spi->mode & (SPI_CPHA | SPI_CPOL)) { - case SPI_MODE_0: - cs->mode |= SPI_CLK_MODE0; - break; - case SPI_MODE_1: - cs->mode |= SPI_CLK_MODE1; - break; - case SPI_MODE_2: - cs->mode |= SPI_CLK_MODE2; - break; - case SPI_MODE_3: - cs->mode |= SPI_CLK_MODE3; - break; - } - - if (spi->mode & SPI_LSB_FIRST) - cs->mode |= SPI_PPC4XX_MODE_RD; - - return 0; -} - -static void spi_ppc4xx_chipsel(struct spi_device *spi, int value) -{ - struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master); - unsigned int cs = spi->chip_select; - unsigned int cspol; - - /* - * If there are no chip selects at all, or if this is the special - * case of a non-existent (dummy) chip select, do nothing. - */ - - if (!hw->master->num_chipselect || hw->gpios[cs] == -EEXIST) - return; - - cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; - if (value == BITBANG_CS_INACTIVE) - cspol = !cspol; - - gpio_set_value(hw->gpios[cs], cspol); -} - -static irqreturn_t spi_ppc4xx_int(int irq, void *dev_id) -{ - struct ppc4xx_spi *hw; - u8 status; - u8 data; - unsigned int count; - - hw = (struct ppc4xx_spi *)dev_id; - - status = in_8(&hw->regs->sr); - if (!status) - return IRQ_NONE; - - /* - * BSY de-asserts one cycle after the transfer is complete. The - * interrupt is asserted after the transfer is complete. The exact - * relationship is not documented, hence this code. - */ - - if (unlikely(status & SPI_PPC4XX_SR_BSY)) { - u8 lstatus; - int cnt = 0; - - dev_dbg(hw->dev, "got interrupt but spi still busy?\n"); - do { - ndelay(10); - lstatus = in_8(&hw->regs->sr); - } while (++cnt < 100 && lstatus & SPI_PPC4XX_SR_BSY); - - if (cnt >= 100) { - dev_err(hw->dev, "busywait: too many loops!\n"); - complete(&hw->done); - return IRQ_HANDLED; - } else { - /* status is always 1 (RBR) here */ - status = in_8(&hw->regs->sr); - dev_dbg(hw->dev, "loops %d status %x\n", cnt, status); - } - } - - count = hw->count; - hw->count++; - - /* RBR triggered this interrupt. Therefore, data must be ready. */ - data = in_8(&hw->regs->rxd); - if (hw->rx) - hw->rx[count] = data; - - count++; - - if (count < hw->len) { - data = hw->tx ? hw->tx[count] : 0; - out_8(&hw->regs->txd, data); - out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR); - } else { - complete(&hw->done); - } - - return IRQ_HANDLED; -} - -static void spi_ppc4xx_cleanup(struct spi_device *spi) -{ - kfree(spi->controller_state); -} - -static void spi_ppc4xx_enable(struct ppc4xx_spi *hw) -{ - /* - * On all 4xx PPC's the SPI bus is shared/multiplexed with - * the 2nd I2C bus. We need to enable the the SPI bus before - * using it. - */ - - /* need to clear bit 14 to enable SPC */ - dcri_clrset(SDR0, SDR0_PFC1, 0x80000000 >> 14, 0); -} - -static void free_gpios(struct ppc4xx_spi *hw) -{ - if (hw->master->num_chipselect) { - int i; - for (i = 0; i < hw->master->num_chipselect; i++) - if (gpio_is_valid(hw->gpios[i])) - gpio_free(hw->gpios[i]); - - kfree(hw->gpios); - hw->gpios = NULL; - } -} - -/* - * of_device layer stuff... - */ -static int __init spi_ppc4xx_of_probe(struct of_device *op, - const struct of_device_id *match) -{ - struct ppc4xx_spi *hw; - struct spi_master *master; - struct spi_bitbang *bbp; - struct resource resource; - struct device_node *np = op->node; - struct device *dev = &op->dev; - struct device_node *opbnp; - int ret; - int num_gpios; - const unsigned int *clk; - - master = spi_alloc_master(dev, sizeof *hw); - if (master == NULL) - return -ENOMEM; - dev_set_drvdata(dev, master); - hw = spi_master_get_devdata(master); - hw->master = spi_master_get(master); - hw->dev = dev; - - init_completion(&hw->done); - - /* - * A count of zero implies a single SPI device without any chip-select. - * Note that of_gpio_count counts all gpios assigned to this spi master. - * This includes both "null" gpio's and real ones. - */ - num_gpios = of_gpio_count(np); - if (num_gpios) { - int i; - - hw->gpios = kzalloc(sizeof(int) * num_gpios, GFP_KERNEL); - if (!hw->gpios) { - ret = -ENOMEM; - goto free_master; - } - - for (i = 0; i < num_gpios; i++) { - int gpio; - enum of_gpio_flags flags; - - gpio = of_get_gpio_flags(np, i, &flags); - hw->gpios[i] = gpio; - - if (gpio_is_valid(gpio)) { - /* Real CS - set the initial state. */ - ret = gpio_request(gpio, np->name); - if (ret < 0) { - dev_err(dev, "can't request gpio " - "#%d: %d\n", i, ret); - goto free_gpios; - } - - gpio_direction_output(gpio, - !!(flags & OF_GPIO_ACTIVE_LOW)); - } else if (gpio == -EEXIST) { - ; /* No CS, but that's OK. */ - } else { - dev_err(dev, "invalid gpio #%d: %d\n", i, gpio); - ret = -EINVAL; - goto free_gpios; - } - } - } - - /* Setup the state for the bitbang driver */ - bbp = &hw->bitbang; - bbp->master = hw->master; - bbp->setup_transfer = spi_ppc4xx_setupxfer; - bbp->chipselect = spi_ppc4xx_chipsel; - bbp->txrx_bufs = spi_ppc4xx_txrx; - bbp->use_dma = 0; - bbp->master->setup = spi_ppc4xx_setup; - bbp->master->cleanup = spi_ppc4xx_cleanup; - - /* Allocate bus num dynamically. */ - bbp->master->bus_num = -1; - - /* the spi->mode bits understood by this driver: */ - bbp->master->mode_bits = - SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST; - - /* this many pins in all GPIO controllers */ - bbp->master->num_chipselect = num_gpios; - - /* Get the clock for the OPB */ - opbnp = of_find_compatible_node(NULL, NULL, "ibm,opb"); - if (opbnp == NULL) { - dev_err(dev, "OPB: cannot find node\n"); - ret = -ENODEV; - goto free_gpios; - } - /* Get the clock (Hz) for the OPB */ - clk = of_get_property(opbnp, "clock-frequency", NULL); - if (clk == NULL) { - dev_err(dev, "OPB: no clock-frequency property set\n"); - of_node_put(opbnp); - ret = -ENODEV; - goto free_gpios; - } - hw->opb_freq = *clk; - hw->opb_freq >>= 2; - of_node_put(opbnp); - - ret = of_address_to_resource(np, 0, &resource); - if (ret) { - dev_err(dev, "error while parsing device node resource\n"); - goto free_gpios; - } - hw->mapbase = resource.start; - hw->mapsize = resource.end - resource.start + 1; - - /* Sanity check */ - if (hw->mapsize < sizeof(struct spi_ppc4xx_regs)) { - dev_err(dev, "too small to map registers\n"); - ret = -EINVAL; - goto free_gpios; - } - - /* Request IRQ */ - hw->irqnum = irq_of_parse_and_map(np, 0); - ret = request_irq(hw->irqnum, spi_ppc4xx_int, - IRQF_DISABLED, "spi_ppc4xx_of", (void *)hw); - if (ret) { - dev_err(dev, "unable to allocate interrupt\n"); - goto free_gpios; - } - - if (!request_mem_region(hw->mapbase, hw->mapsize, DRIVER_NAME)) { - dev_err(dev, "resource unavailable\n"); - ret = -EBUSY; - goto request_mem_error; - } - - hw->regs = ioremap(hw->mapbase, sizeof(struct spi_ppc4xx_regs)); - - if (!hw->regs) { - dev_err(dev, "unable to memory map registers\n"); - ret = -ENXIO; - goto map_io_error; - } - - spi_ppc4xx_enable(hw); - - /* Finally register our spi controller */ - dev->dma_mask = 0; - ret = spi_bitbang_start(bbp); - if (ret) { - dev_err(dev, "failed to register SPI master\n"); - goto unmap_regs; - } - - dev_info(dev, "driver initialized\n"); - of_register_spi_devices(master, np); - - return 0; - -unmap_regs: - iounmap(hw->regs); -map_io_error: - release_mem_region(hw->mapbase, hw->mapsize); -request_mem_error: - free_irq(hw->irqnum, hw); -free_gpios: - free_gpios(hw); -free_master: - dev_set_drvdata(dev, NULL); - spi_master_put(master); - - dev_err(dev, "initialization failed\n"); - return ret; -} - -static int __exit spi_ppc4xx_of_remove(struct of_device *op) -{ - struct spi_master *master = dev_get_drvdata(&op->dev); - struct ppc4xx_spi *hw = spi_master_get_devdata(master); - - spi_bitbang_stop(&hw->bitbang); - dev_set_drvdata(&op->dev, NULL); - release_mem_region(hw->mapbase, hw->mapsize); - free_irq(hw->irqnum, hw); - iounmap(hw->regs); - free_gpios(hw); - return 0; -} - -static struct of_device_id spi_ppc4xx_of_match[] = { - { .compatible = "ibm,ppc4xx-spi", }, - {}, -}; - -MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); - -static struct of_platform_driver spi_ppc4xx_of_driver = { - .match_table = spi_ppc4xx_of_match, - .probe = spi_ppc4xx_of_probe, - .remove = __exit_p(spi_ppc4xx_of_remove), - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init spi_ppc4xx_init(void) -{ - return of_register_platform_driver(&spi_ppc4xx_of_driver); -} -module_init(spi_ppc4xx_init); - -static void __exit spi_ppc4xx_exit(void) -{ - of_unregister_platform_driver(&spi_ppc4xx_of_driver); -} -module_exit(spi_ppc4xx_exit); - -MODULE_AUTHOR("Gary Jennejohn & Stefan Roese"); -MODULE_DESCRIPTION("Simple PPC4xx SPI Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index 33d94f76b9ef..6ba8aece90b5 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -20,28 +20,17 @@ #include #include #include -#include #include #include +#include +#include +#include + #include #include -/** - * s3c24xx_spi_devstate - per device data - * @hz: Last frequency calculated for @sppre field. - * @mode: Last mode setting for the @spcon field. - * @spcon: Value to write to the SPCON register. - * @sppre: Value to write to the SPPRE register. - */ -struct s3c24xx_spi_devstate { - unsigned int hz; - unsigned int mode; - u8 spcon; - u8 sppre; -}; - struct s3c24xx_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; @@ -82,31 +71,43 @@ static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) { - struct s3c24xx_spi_devstate *cs = spi->controller_state; struct s3c24xx_spi *hw = to_hw(spi); unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; - - /* change the chipselect state and the state of the spi engine clock */ + unsigned int spcon; switch (value) { case BITBANG_CS_INACTIVE: hw->set_cs(hw->pdata, spi->chip_select, cspol^1); - writeb(cs->spcon, hw->regs + S3C2410_SPCON); break; case BITBANG_CS_ACTIVE: - writeb(cs->spcon | S3C2410_SPCON_ENSCK, - hw->regs + S3C2410_SPCON); + spcon = readb(hw->regs + S3C2410_SPCON); + + if (spi->mode & SPI_CPHA) + spcon |= S3C2410_SPCON_CPHA_FMTB; + else + spcon &= ~S3C2410_SPCON_CPHA_FMTB; + + if (spi->mode & SPI_CPOL) + spcon |= S3C2410_SPCON_CPOL_HIGH; + else + spcon &= ~S3C2410_SPCON_CPOL_HIGH; + + spcon |= S3C2410_SPCON_ENSCK; + + /* write new configration */ + + writeb(spcon, hw->regs + S3C2410_SPCON); hw->set_cs(hw->pdata, spi->chip_select, cspol); + break; } } -static int s3c24xx_spi_update_state(struct spi_device *spi, - struct spi_transfer *t) +static int s3c24xx_spi_setupxfer(struct spi_device *spi, + struct spi_transfer *t) { struct s3c24xx_spi *hw = to_hw(spi); - struct s3c24xx_spi_devstate *cs = spi->controller_state; unsigned int bpw; unsigned int hz; unsigned int div; @@ -126,89 +127,41 @@ static int s3c24xx_spi_update_state(struct spi_device *spi, return -EINVAL; } - if (spi->mode != cs->mode) { - u8 spcon = SPCON_DEFAULT; - - if (spi->mode & SPI_CPHA) - spcon |= S3C2410_SPCON_CPHA_FMTB; - - if (spi->mode & SPI_CPOL) - spcon |= S3C2410_SPCON_CPOL_HIGH; + clk = clk_get_rate(hw->clk); + div = DIV_ROUND_UP(clk, hz * 2) - 1; - cs->mode = spi->mode; - cs->spcon = spcon; - } + if (div > 255) + div = 255; - if (cs->hz != hz) { - clk = clk_get_rate(hw->clk); - div = DIV_ROUND_UP(clk, hz * 2) - 1; + dev_dbg(&spi->dev, "setting pre-scaler to %d (wanted %d, got %ld)\n", + div, hz, clk / (2 * (div + 1))); - if (div > 255) - div = 255; - dev_dbg(&spi->dev, "pre-scaler=%d (wanted %d, got %ld)\n", - div, hz, clk / (2 * (div + 1))); + writeb(div, hw->regs + S3C2410_SPPRE); - cs->hz = hz; - cs->sppre = div; + spin_lock(&hw->bitbang.lock); + if (!hw->bitbang.busy) { + hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); + /* need to ndelay for 0.5 clocktick ? */ } + spin_unlock(&hw->bitbang.lock); return 0; } -static int s3c24xx_spi_setupxfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct s3c24xx_spi_devstate *cs = spi->controller_state; - struct s3c24xx_spi *hw = to_hw(spi); - int ret; - - ret = s3c24xx_spi_update_state(spi, t); - if (!ret) - writeb(cs->sppre, hw->regs + S3C2410_SPPRE); - - return ret; -} - static int s3c24xx_spi_setup(struct spi_device *spi) { - struct s3c24xx_spi_devstate *cs = spi->controller_state; - struct s3c24xx_spi *hw = to_hw(spi); int ret; - /* allocate settings on the first call */ - if (!cs) { - cs = kzalloc(sizeof(struct s3c24xx_spi_devstate), GFP_KERNEL); - if (!cs) { - dev_err(&spi->dev, "no memory for controller state\n"); - return -ENOMEM; - } - - cs->spcon = SPCON_DEFAULT; - cs->hz = -1; - spi->controller_state = cs; - } - - /* initialise the state from the device */ - ret = s3c24xx_spi_update_state(spi, NULL); - if (ret) + ret = s3c24xx_spi_setupxfer(spi, NULL); + if (ret < 0) { + dev_err(&spi->dev, "setupxfer returned %d\n", ret); return ret; - - spin_lock(&hw->bitbang.lock); - if (!hw->bitbang.busy) { - hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); - /* need to ndelay for 0.5 clocktick ? */ } - spin_unlock(&hw->bitbang.lock); return 0; } -static void s3c24xx_spi_cleanup(struct spi_device *spi) -{ - kfree(spi->controller_state); -} - static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) { return hw->tx ? hw->tx[count] : 0; @@ -336,9 +289,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; hw->bitbang.chipselect = s3c24xx_spi_chipsel; hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; - - hw->master->setup = s3c24xx_spi_setup; - hw->master->cleanup = s3c24xx_spi_cleanup; + hw->bitbang.master->setup = s3c24xx_spi_setup; dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); @@ -351,7 +302,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) goto err_no_iores; } - hw->ioarea = request_mem_region(res->start, resource_size(res), + hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, pdev->name); if (hw->ioarea == NULL) { @@ -360,7 +311,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) goto err_no_iores; } - hw->regs = ioremap(res->start, resource_size(res)); + hw->regs = ioremap(res->start, (res->end - res->start)+1); if (hw->regs == NULL) { dev_err(&pdev->dev, "Cannot map IO\n"); err = -ENXIO; @@ -470,9 +421,9 @@ static int __exit s3c24xx_spi_remove(struct platform_device *dev) #ifdef CONFIG_PM -static int s3c24xx_spi_suspend(struct device *dev) +static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg) { - struct s3c24xx_spi *hw = platform_get_drvdata(to_platform_device(dev)); + struct s3c24xx_spi *hw = platform_get_drvdata(pdev); if (hw->pdata && hw->pdata->gpio_setup) hw->pdata->gpio_setup(hw->pdata, 0); @@ -481,31 +432,27 @@ static int s3c24xx_spi_suspend(struct device *dev) return 0; } -static int s3c24xx_spi_resume(struct device *dev) +static int s3c24xx_spi_resume(struct platform_device *pdev) { - struct s3c24xx_spi *hw = platform_get_drvdata(to_platform_device(dev)); + struct s3c24xx_spi *hw = platform_get_drvdata(pdev); s3c24xx_spi_initialsetup(hw); return 0; } -static struct dev_pm_ops s3c24xx_spi_pmops = { - .suspend = s3c24xx_spi_suspend, - .resume = s3c24xx_spi_resume, -}; - -#define S3C24XX_SPI_PMOPS &s3c24xx_spi_pmops #else -#define S3C24XX_SPI_PMOPS NULL -#endif /* CONFIG_PM */ +#define s3c24xx_spi_suspend NULL +#define s3c24xx_spi_resume NULL +#endif MODULE_ALIAS("platform:s3c2410-spi"); static struct platform_driver s3c24xx_spi_driver = { .remove = __exit_p(s3c24xx_spi_remove), + .suspend = s3c24xx_spi_suspend, + .resume = s3c24xx_spi_resume, .driver = { .name = "s3c2410-spi", .owner = THIS_MODULE, - .pm = S3C24XX_SPI_PMOPS, }, }; diff --git a/trunk/drivers/spi/spi_stmp.c b/trunk/drivers/spi/spi_stmp.c deleted file mode 100644 index d871dc23909c..000000000000 --- a/trunk/drivers/spi/spi_stmp.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Freescale STMP378X SPI master driver - * - * Author: dmitry pervushin - * - * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -/* 0 means DMA mode(recommended, default), !0 - PIO mode */ -static int pio; -static int clock; - -/* default timeout for busy waits is 2 seconds */ -#define STMP_SPI_TIMEOUT (2 * HZ) - -struct stmp_spi { - int id; - - void * __iomem regs; /* vaddr of the control registers */ - - int irq, err_irq; - u32 dma; - struct stmp3xxx_dma_descriptor d; - - u32 speed_khz; - u32 saved_timings; - u32 divider; - - struct clk *clk; - struct device *master_dev; - - struct work_struct work; - struct workqueue_struct *workqueue; - - /* lock protects queue access */ - spinlock_t lock; - struct list_head queue; - - struct completion done; -}; - -#define busy_wait(cond) \ - ({ \ - unsigned long end_jiffies = jiffies + STMP_SPI_TIMEOUT; \ - bool succeeded = false; \ - do { \ - if (cond) { \ - succeeded = true; \ - break; \ - } \ - cpu_relax(); \ - } while (time_before(end_jiffies, jiffies)); \ - succeeded; \ - }) - -/** - * stmp_spi_init_hw - * Initialize the SSP port - */ -static int stmp_spi_init_hw(struct stmp_spi *ss) -{ - int err = 0; - void *pins = ss->master_dev->platform_data; - - err = stmp3xxx_request_pin_group(pins, dev_name(ss->master_dev)); - if (err) - goto out; - - ss->clk = clk_get(NULL, "ssp"); - if (IS_ERR(ss->clk)) { - err = PTR_ERR(ss->clk); - goto out_free_pins; - } - clk_enable(ss->clk); - - stmp3xxx_reset_block(ss->regs, false); - stmp3xxx_dma_reset_channel(ss->dma); - - return 0; - -out_free_pins: - stmp3xxx_release_pin_group(pins, dev_name(ss->master_dev)); -out: - return err; -} - -static void stmp_spi_release_hw(struct stmp_spi *ss) -{ - void *pins = ss->master_dev->platform_data; - - if (ss->clk && !IS_ERR(ss->clk)) { - clk_disable(ss->clk); - clk_put(ss->clk); - } - stmp3xxx_release_pin_group(pins, dev_name(ss->master_dev)); -} - -static int stmp_spi_setup_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - u8 bits_per_word; - u32 hz; - struct stmp_spi *ss = spi_master_get_devdata(spi->master); - u16 rate; - - bits_per_word = spi->bits_per_word; - if (t && t->bits_per_word) - bits_per_word = t->bits_per_word; - - /* - * Calculate speed: - * - by default, use maximum speed from ssp clk - * - if device overrides it, use it - * - if transfer specifies other speed, use transfer's one - */ - hz = 1000 * ss->speed_khz / ss->divider; - if (spi->max_speed_hz) - hz = min(hz, spi->max_speed_hz); - if (t && t->speed_hz) - hz = min(hz, t->speed_hz); - - if (hz == 0) { - dev_err(&spi->dev, "Cannot continue with zero clock\n"); - return -EINVAL; - } - - if (bits_per_word != 8) { - dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", - __func__, bits_per_word); - return -EINVAL; - } - - dev_dbg(&spi->dev, "Requested clk rate = %uHz, max = %uHz/%d = %uHz\n", - hz, ss->speed_khz, ss->divider, - ss->speed_khz * 1000 / ss->divider); - - if (ss->speed_khz * 1000 / ss->divider < hz) { - dev_err(&spi->dev, "%s, unsupported clock rate %uHz\n", - __func__, hz); - return -EINVAL; - } - - rate = 1000 * ss->speed_khz/ss->divider/hz; - - writel(BF(ss->divider, SSP_TIMING_CLOCK_DIVIDE) | - BF(rate - 1, SSP_TIMING_CLOCK_RATE), - HW_SSP_TIMING + ss->regs); - - writel(BF(1 /* mode SPI */, SSP_CTRL1_SSP_MODE) | - BF(4 /* 8 bits */, SSP_CTRL1_WORD_LENGTH) | - ((spi->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | - ((spi->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0) | - (pio ? 0 : BM_SSP_CTRL1_DMA_ENABLE), - ss->regs + HW_SSP_CTRL1); - - return 0; -} - -static int stmp_spi_setup(struct spi_device *spi) -{ - /* spi_setup() does basic checks, - * stmp_spi_setup_transfer() does more later - */ - if (spi->bits_per_word != 8) { - dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", - __func__, spi->bits_per_word); - return -EINVAL; - } - return 0; -} - -static inline u32 stmp_spi_cs(unsigned cs) -{ - return ((cs & 1) ? BM_SSP_CTRL0_WAIT_FOR_CMD : 0) | - ((cs & 2) ? BM_SSP_CTRL0_WAIT_FOR_IRQ : 0); -} - -static int stmp_spi_txrx_dma(struct stmp_spi *ss, int cs, - unsigned char *buf, dma_addr_t dma_buf, int len, - int first, int last, bool write) -{ - u32 c0 = 0; - dma_addr_t spi_buf_dma = dma_buf; - int status = 0; - enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - - c0 |= (first ? BM_SSP_CTRL0_LOCK_CS : 0); - c0 |= (last ? BM_SSP_CTRL0_IGNORE_CRC : 0); - c0 |= (write ? 0 : BM_SSP_CTRL0_READ); - c0 |= BM_SSP_CTRL0_DATA_XFER; - - c0 |= stmp_spi_cs(cs); - - c0 |= BF(len, SSP_CTRL0_XFER_COUNT); - - if (!dma_buf) - spi_buf_dma = dma_map_single(ss->master_dev, buf, len, dir); - - ss->d.command->cmd = - BF(len, APBH_CHn_CMD_XFER_COUNT) | - BF(1, APBH_CHn_CMD_CMDWORDS) | - BM_APBH_CHn_CMD_WAIT4ENDCMD | - BM_APBH_CHn_CMD_IRQONCMPLT | - BF(write ? BV_APBH_CHn_CMD_COMMAND__DMA_READ : - BV_APBH_CHn_CMD_COMMAND__DMA_WRITE, - APBH_CHn_CMD_COMMAND); - ss->d.command->pio_words[0] = c0; - ss->d.command->buf_ptr = spi_buf_dma; - - stmp3xxx_dma_reset_channel(ss->dma); - stmp3xxx_dma_clear_interrupt(ss->dma); - stmp3xxx_dma_enable_interrupt(ss->dma); - init_completion(&ss->done); - stmp3xxx_dma_go(ss->dma, &ss->d, 1); - wait_for_completion(&ss->done); - - if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)) - status = ETIMEDOUT; - - if (!dma_buf) - dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir); - - return status; -} - -static inline void stmp_spi_enable(struct stmp_spi *ss) -{ - stmp3xxx_setl(BM_SSP_CTRL0_LOCK_CS, ss->regs + HW_SSP_CTRL0); - stmp3xxx_clearl(BM_SSP_CTRL0_IGNORE_CRC, ss->regs + HW_SSP_CTRL0); -} - -static inline void stmp_spi_disable(struct stmp_spi *ss) -{ - stmp3xxx_clearl(BM_SSP_CTRL0_LOCK_CS, ss->regs + HW_SSP_CTRL0); - stmp3xxx_setl(BM_SSP_CTRL0_IGNORE_CRC, ss->regs + HW_SSP_CTRL0); -} - -static int stmp_spi_txrx_pio(struct stmp_spi *ss, int cs, - unsigned char *buf, int len, - bool first, bool last, bool write) -{ - if (first) - stmp_spi_enable(ss); - - stmp3xxx_setl(stmp_spi_cs(cs), ss->regs + HW_SSP_CTRL0); - - while (len--) { - if (last && len <= 0) - stmp_spi_disable(ss); - - stmp3xxx_clearl(BM_SSP_CTRL0_XFER_COUNT, - ss->regs + HW_SSP_CTRL0); - stmp3xxx_setl(1, ss->regs + HW_SSP_CTRL0); - - if (write) - stmp3xxx_clearl(BM_SSP_CTRL0_READ, - ss->regs + HW_SSP_CTRL0); - else - stmp3xxx_setl(BM_SSP_CTRL0_READ, - ss->regs + HW_SSP_CTRL0); - - /* Run! */ - stmp3xxx_setl(BM_SSP_CTRL0_RUN, ss->regs + HW_SSP_CTRL0); - - if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & - BM_SSP_CTRL0_RUN)) - break; - - if (write) - writel(*buf, ss->regs + HW_SSP_DATA); - - /* Set TRANSFER */ - stmp3xxx_setl(BM_SSP_CTRL0_DATA_XFER, ss->regs + HW_SSP_CTRL0); - - if (!write) { - if (busy_wait((readl(ss->regs + HW_SSP_STATUS) & - BM_SSP_STATUS_FIFO_EMPTY))) - break; - *buf = readl(ss->regs + HW_SSP_DATA) & 0xFF; - } - - if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & - BM_SSP_CTRL0_RUN)) - break; - - /* advance to the next byte */ - buf++; - } - - return len < 0 ? 0 : -ETIMEDOUT; -} - -static int stmp_spi_handle_message(struct stmp_spi *ss, struct spi_message *m) -{ - bool first, last; - struct spi_transfer *t, *tmp_t; - int status = 0; - int cs; - - cs = m->spi->chip_select; - - list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { - - first = (&t->transfer_list == m->transfers.next); - last = (&t->transfer_list == m->transfers.prev); - - if (first || t->speed_hz || t->bits_per_word) - stmp_spi_setup_transfer(m->spi, t); - - /* reject "not last" transfers which request to change cs */ - if (t->cs_change && !last) { - dev_err(&m->spi->dev, - "Message with t->cs_change has been skipped\n"); - continue; - } - - if (t->tx_buf) { - status = pio ? - stmp_spi_txrx_pio(ss, cs, (void *)t->tx_buf, - t->len, first, last, true) : - stmp_spi_txrx_dma(ss, cs, (void *)t->tx_buf, - t->tx_dma, t->len, first, last, true); -#ifdef DEBUG - if (t->len < 0x10) - print_hex_dump_bytes("Tx ", - DUMP_PREFIX_OFFSET, - t->tx_buf, t->len); - else - pr_debug("Tx: %d bytes\n", t->len); -#endif - } - if (t->rx_buf) { - status = pio ? - stmp_spi_txrx_pio(ss, cs, t->rx_buf, - t->len, first, last, false) : - stmp_spi_txrx_dma(ss, cs, t->rx_buf, - t->rx_dma, t->len, first, last, false); -#ifdef DEBUG - if (t->len < 0x10) - print_hex_dump_bytes("Rx ", - DUMP_PREFIX_OFFSET, - t->rx_buf, t->len); - else - pr_debug("Rx: %d bytes\n", t->len); -#endif - } - - if (t->delay_usecs) - udelay(t->delay_usecs); - - if (status) - break; - - } - return status; -} - -/** - * stmp_spi_handle - handle messages from the queue - */ -static void stmp_spi_handle(struct work_struct *w) -{ - struct stmp_spi *ss = container_of(w, struct stmp_spi, work); - unsigned long flags; - struct spi_message *m; - - spin_lock_irqsave(&ss->lock, flags); - while (!list_empty(&ss->queue)) { - m = list_entry(ss->queue.next, struct spi_message, queue); - list_del_init(&m->queue); - spin_unlock_irqrestore(&ss->lock, flags); - - m->status = stmp_spi_handle_message(ss, m); - m->complete(m->context); - - spin_lock_irqsave(&ss->lock, flags); - } - spin_unlock_irqrestore(&ss->lock, flags); - - return; -} - -/** - * stmp_spi_transfer - perform message transfer. - * Called indirectly from spi_async, queues all the messages to - * spi_handle_message. - * @spi: spi device - * @m: message to be queued - */ -static int stmp_spi_transfer(struct spi_device *spi, struct spi_message *m) -{ - struct stmp_spi *ss = spi_master_get_devdata(spi->master); - unsigned long flags; - - m->status = -EINPROGRESS; - spin_lock_irqsave(&ss->lock, flags); - list_add_tail(&m->queue, &ss->queue); - queue_work(ss->workqueue, &ss->work); - spin_unlock_irqrestore(&ss->lock, flags); - return 0; -} - -static irqreturn_t stmp_spi_irq(int irq, void *dev_id) -{ - struct stmp_spi *ss = dev_id; - - stmp3xxx_dma_clear_interrupt(ss->dma); - complete(&ss->done); - return IRQ_HANDLED; -} - -static irqreturn_t stmp_spi_irq_err(int irq, void *dev_id) -{ - struct stmp_spi *ss = dev_id; - u32 c1, st; - - c1 = readl(ss->regs + HW_SSP_CTRL1); - st = readl(ss->regs + HW_SSP_STATUS); - dev_err(ss->master_dev, "%s: status = 0x%08X, c1 = 0x%08X\n", - __func__, st, c1); - stmp3xxx_clearl(c1 & 0xCCCC0000, ss->regs + HW_SSP_CTRL1); - - return IRQ_HANDLED; -} - -static int __devinit stmp_spi_probe(struct platform_device *dev) -{ - int err = 0; - struct spi_master *master; - struct stmp_spi *ss; - struct resource *r; - - master = spi_alloc_master(&dev->dev, sizeof(struct stmp_spi)); - if (master == NULL) { - err = -ENOMEM; - goto out0; - } - master->flags = SPI_MASTER_HALF_DUPLEX; - - ss = spi_master_get_devdata(master); - platform_set_drvdata(dev, master); - - /* Get resources(memory, IRQ) associated with the device */ - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - err = -ENODEV; - goto out_put_master; - } - ss->regs = ioremap(r->start, resource_size(r)); - if (!ss->regs) { - err = -EINVAL; - goto out_put_master; - } - - ss->master_dev = &dev->dev; - ss->id = dev->id; - - INIT_WORK(&ss->work, stmp_spi_handle); - INIT_LIST_HEAD(&ss->queue); - spin_lock_init(&ss->lock); - - ss->workqueue = create_singlethread_workqueue(dev_name(&dev->dev)); - if (!ss->workqueue) { - err = -ENXIO; - goto out_put_master; - } - master->transfer = stmp_spi_transfer; - master->setup = stmp_spi_setup; - - /* the spi->mode bits understood by this driver: */ - master->mode_bits = SPI_CPOL | SPI_CPHA; - - ss->irq = platform_get_irq(dev, 0); - if (ss->irq < 0) { - err = ss->irq; - goto out_put_master; - } - ss->err_irq = platform_get_irq(dev, 1); - if (ss->err_irq < 0) { - err = ss->err_irq; - goto out_put_master; - } - - r = platform_get_resource(dev, IORESOURCE_DMA, 0); - if (r == NULL) { - err = -ENODEV; - goto out_put_master; - } - - ss->dma = r->start; - err = stmp3xxx_dma_request(ss->dma, &dev->dev, dev_name(&dev->dev)); - if (err) - goto out_put_master; - - err = stmp3xxx_dma_allocate_command(ss->dma, &ss->d); - if (err) - goto out_free_dma; - - master->bus_num = dev->id; - master->num_chipselect = 1; - - /* SPI controller initializations */ - err = stmp_spi_init_hw(ss); - if (err) { - dev_dbg(&dev->dev, "cannot initialize hardware\n"); - goto out_free_dma_desc; - } - - if (clock) { - dev_info(&dev->dev, "clock rate forced to %d\n", clock); - clk_set_rate(ss->clk, clock); - } - ss->speed_khz = clk_get_rate(ss->clk); - ss->divider = 2; - dev_info(&dev->dev, "max possible speed %d = %ld/%d kHz\n", - ss->speed_khz, clk_get_rate(ss->clk), ss->divider); - - /* Register for SPI interrupt */ - err = request_irq(ss->irq, stmp_spi_irq, 0, - dev_name(&dev->dev), ss); - if (err) { - dev_dbg(&dev->dev, "request_irq failed, %d\n", err); - goto out_release_hw; - } - - /* ..and shared interrupt for all SSP controllers */ - err = request_irq(ss->err_irq, stmp_spi_irq_err, IRQF_SHARED, - dev_name(&dev->dev), ss); - if (err) { - dev_dbg(&dev->dev, "request_irq(error) failed, %d\n", err); - goto out_free_irq; - } - - err = spi_register_master(master); - if (err) { - dev_dbg(&dev->dev, "cannot register spi master, %d\n", err); - goto out_free_irq_2; - } - dev_info(&dev->dev, "at (mapped) 0x%08X, irq=%d, bus %d, %s mode\n", - (u32)ss->regs, ss->irq, master->bus_num, - pio ? "PIO" : "DMA"); - return 0; - -out_free_irq_2: - free_irq(ss->err_irq, ss); -out_free_irq: - free_irq(ss->irq, ss); -out_free_dma_desc: - stmp3xxx_dma_free_command(ss->dma, &ss->d); -out_free_dma: - stmp3xxx_dma_release(ss->dma); -out_release_hw: - stmp_spi_release_hw(ss); -out_put_master: - if (ss->workqueue) - destroy_workqueue(ss->workqueue); - if (ss->regs) - iounmap(ss->regs); - platform_set_drvdata(dev, NULL); - spi_master_put(master); -out0: - return err; -} - -static int __devexit stmp_spi_remove(struct platform_device *dev) -{ - struct stmp_spi *ss; - struct spi_master *master; - - master = platform_get_drvdata(dev); - if (master == NULL) - goto out0; - ss = spi_master_get_devdata(master); - - spi_unregister_master(master); - - free_irq(ss->err_irq, ss); - free_irq(ss->irq, ss); - stmp3xxx_dma_free_command(ss->dma, &ss->d); - stmp3xxx_dma_release(ss->dma); - stmp_spi_release_hw(ss); - destroy_workqueue(ss->workqueue); - iounmap(ss->regs); - spi_master_put(master); - platform_set_drvdata(dev, NULL); -out0: - return 0; -} - -#ifdef CONFIG_PM -static int stmp_spi_suspend(struct platform_device *pdev, pm_message_t pmsg) -{ - struct stmp_spi *ss; - struct spi_master *master; - - master = platform_get_drvdata(pdev); - ss = spi_master_get_devdata(master); - - ss->saved_timings = readl(HW_SSP_TIMING + ss->regs); - clk_disable(ss->clk); - - return 0; -} - -static int stmp_spi_resume(struct platform_device *pdev) -{ - struct stmp_spi *ss; - struct spi_master *master; - - master = platform_get_drvdata(pdev); - ss = spi_master_get_devdata(master); - - clk_enable(ss->clk); - stmp3xxx_reset_block(ss->regs, false); - writel(ss->saved_timings, ss->regs + HW_SSP_TIMING); - - return 0; -} - -#else -#define stmp_spi_suspend NULL -#define stmp_spi_resume NULL -#endif - -static struct platform_driver stmp_spi_driver = { - .probe = stmp_spi_probe, - .remove = __devexit_p(stmp_spi_remove), - .driver = { - .name = "stmp3xxx_ssp", - .owner = THIS_MODULE, - }, - .suspend = stmp_spi_suspend, - .resume = stmp_spi_resume, -}; - -static int __init stmp_spi_init(void) -{ - return platform_driver_register(&stmp_spi_driver); -} - -static void __exit stmp_spi_exit(void) -{ - platform_driver_unregister(&stmp_spi_driver); -} - -module_init(stmp_spi_init); -module_exit(stmp_spi_exit); -module_param(pio, int, S_IRUGO); -module_param(clock, int, S_IRUGO); -MODULE_AUTHOR("dmitry pervushin "); -MODULE_DESCRIPTION("STMP3xxx SPI/SSP driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index f921bd1109e1..606e7a40a8da 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -688,4 +688,3 @@ module_exit(spidev_exit); MODULE_AUTHOR("Andrea Paterniani, "); MODULE_DESCRIPTION("User mode SPI device interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:spidev"); diff --git a/trunk/drivers/spi/tle62x0.c b/trunk/drivers/spi/tle62x0.c index bf9540f5fb98..455991fbe28f 100644 --- a/trunk/drivers/spi/tle62x0.c +++ b/trunk/drivers/spi/tle62x0.c @@ -329,4 +329,3 @@ module_exit(tle62x0_exit); MODULE_AUTHOR("Ben Dooks "); MODULE_DESCRIPTION("TLE62x0 SPI driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:tle62x0"); diff --git a/trunk/drivers/staging/stlc45xx/stlc45xx.c b/trunk/drivers/staging/stlc45xx/stlc45xx.c index be99eb33d817..12d414deaad6 100644 --- a/trunk/drivers/staging/stlc45xx/stlc45xx.c +++ b/trunk/drivers/staging/stlc45xx/stlc45xx.c @@ -2591,4 +2591,3 @@ module_exit(stlc45xx_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kalle Valo "); -MODULE_ALIAS("spi:cx3110x"); diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 380233bd6a39..80e65f29921c 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -163,7 +163,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action) usb_kill_urb(onetouch->irq); break; case US_RESUME: - if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) + if (usb_submit_urb(onetouch->irq, GFP_NOIO) != 0) dev_err(&onetouch->irq->dev->dev, "usb_submit_urb failed\n"); break; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 9bbb2855ea91..11af4cb8924e 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1275,6 +1275,26 @@ config FB_MATROX_MAVEN painting procedures (the secondary head does not use acceleration engine). +config FB_MATROX_MULTIHEAD + bool "Multihead support" + depends on FB_MATROX + ---help--- + Say Y here if you have more than one (supported) Matrox device in + your computer and you want to use all of them for different monitors + ("multihead"). If you have only one device, you should say N because + the driver compiled with Y is larger and a bit slower, especially on + ia32 (ix86). + + If you said M to "Matrox unified accelerated driver" and N here, you + will still be able to use several Matrox devices simultaneously: + insert several instances of the module matroxfb into the kernel + with insmod, supplying the parameter "dev=N" where N is 0, 1, etc. + for the different Matrox devices. This method is slightly faster but + uses 40 KB of kernel memory per Matrox card. + + There is no need for enabling 'Matrox multihead support' if you have + only one Matrox card in the box. + config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI @@ -2021,17 +2041,6 @@ config FB_SH7760 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for panels <= 320 pixel horizontal resolution. -config FB_DA8XX - tristate "DA8xx/OMAP-L1xx Framebuffer support" - depends on FB && ARCH_DAVINCI_DA8XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - This is the frame buffer device driver for the TI LCD controller - found on DA8xx/OMAP-L1xx SoCs. - If unsure, say N. - config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" depends on FB @@ -2108,17 +2117,6 @@ config FB_MB862XX_LIME ---help--- Framebuffer support for Fujitsu Lime GDC on host CPU bus. -config FB_EP93XX - tristate "EP93XX frame buffer support" - depends on FB && ARCH_EP93XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Framebuffer driver for the Cirrus Logic EP93XX series of processors. - This driver is also available as a module. The module will be called - ep93xx-fb. - config FB_PRE_INIT_FB bool "Don't reinitialize, use bootloader's GDC/Display configuration" depends on FB_MB862XX_LIME @@ -2126,14 +2124,6 @@ config FB_PRE_INIT_FB Select this option if display contents should be inherited as set by the bootloader. -config FB_MSM - tristate - depends on FB && ARCH_MSM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default y - config FB_MX3 tristate "MX3 Framebuffer support" depends on FB && MX3_IPU diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 80232e124889..01a819f47371 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -85,7 +85,6 @@ obj-$(CONFIG_FB_Q40) += q40fb.o obj-$(CONFIG_FB_TGA) += tgafb.o obj-$(CONFIG_FB_HP300) += hpfb.o obj-$(CONFIG_FB_G364) += g364fb.o -obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o obj-$(CONFIG_FB_SA1100) += sa1100fb.o obj-$(CONFIG_FB_HIT) += hitfb.o obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o @@ -127,7 +126,6 @@ obj-$(CONFIG_FB_OMAP) += omap/ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_MB862XX) += mb862xx/ -obj-$(CONFIG_FB_MSM) += msm/ # Platform or fallback drivers go here obj-$(CONFIG_FB_UVESA) += uvesafb.o @@ -138,7 +136,6 @@ obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o obj-$(CONFIG_FB_MX3) += mx3fb.o -obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 913b4a47ae52..63d3739d43a8 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -132,7 +132,7 @@ #endif #define PRINTKI(fmt, args...) printk(KERN_INFO "atyfb: " fmt, ## args) -#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) +#define PRINTKE(fmt, args...) printk(KERN_ERR "atyfb: " fmt, ## args) #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) @@ -188,23 +188,24 @@ u32 aty_ld_lcd(int index, const struct atyfb_par *par) */ static void ATIReduceRatio(int *Numerator, int *Denominator) { - int Multiplier, Divider, Remainder; + int Multiplier, Divider, Remainder; - Multiplier = *Numerator; - Divider = *Denominator; + Multiplier = *Numerator; + Divider = *Denominator; - while ((Remainder = Multiplier % Divider)) { - Multiplier = Divider; - Divider = Remainder; - } + while ((Remainder = Multiplier % Divider)) + { + Multiplier = Divider; + Divider = Remainder; + } - *Numerator /= Divider; - *Denominator /= Divider; + *Numerator /= Divider; + *Denominator /= Divider; } #endif -/* - * The Hardware parameters for each card - */ + /* + * The Hardware parameters for each card + */ struct pci_mmap_map { unsigned long voff; @@ -222,19 +223,17 @@ static struct fb_fix_screeninfo atyfb_fix __devinitdata = { .ypanstep = 1, }; -/* - * Frame buffer device API - */ + /* + * Frame buffer device API + */ static int atyfb_open(struct fb_info *info, int user); static int atyfb_release(struct fb_info *info, int user); -static int atyfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info); +static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); static int atyfb_set_par(struct fb_info *info); static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info); -static int atyfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info); + u_int transp, struct fb_info *info); +static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); static int atyfb_blank(int blank, struct fb_info *info); static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); #ifdef __sparc__ @@ -242,9 +241,9 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); #endif static int atyfb_sync(struct fb_info *info); -/* - * Internal routines - */ + /* + * Internal routines + */ static int aty_init(struct fb_info *info); @@ -255,11 +254,8 @@ static int store_video_par(char *videopar, unsigned char m64_num); static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); -static int aty_var_to_crtc(const struct fb_info *info, - const struct fb_var_screeninfo *var, - struct crtc *crtc); -static int aty_crtc_to_var(const struct crtc *crtc, - struct fb_var_screeninfo *var); +static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc); +static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var); static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); #ifdef CONFIG_PPC static int read_aty_sense(const struct atyfb_par *par); @@ -268,9 +264,9 @@ static int read_aty_sense(const struct atyfb_par *par); static DEFINE_MUTEX(reboot_lock); static struct fb_info *reboot_info; -/* - * Interface used by the world - */ + /* + * Interface used by the world + */ static struct fb_var_screeninfo default_var = { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ @@ -456,14 +452,14 @@ static int __devinit correct_chipset(struct atyfb_par *par) type = chip_id & CFG_CHIP_TYPE; rev = (chip_id & CFG_CHIP_REV) >> 24; - switch (par->pci_id) { + switch(par->pci_id) { #ifdef CONFIG_FB_ATY_GX case PCI_CHIP_MACH64GX: - if (type != 0x00d7) + if(type != 0x00d7) return -ENODEV; break; case PCI_CHIP_MACH64CX: - if (type != 0x0057) + if(type != 0x0057) return -ENODEV; break; #endif @@ -568,8 +564,7 @@ static char *aty_xl_ram[8] __devinitdata = { }; #endif /* CONFIG_FB_ATY_CT */ -static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, - struct atyfb_par *par) +static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par) { u32 pixclock = var->pixclock; #ifdef CONFIG_FB_ATY_GENERIC_LCD @@ -577,7 +572,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, par->pll.ct.xres = 0; if (par->lcd_table != 0) { lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par); - if (lcd_on_off & LCD_ON) { + if(lcd_on_off & LCD_ON) { par->pll.ct.xres = var->xres; pixclock = par->lcd_pixclock; } @@ -589,7 +584,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, #if defined(CONFIG_PPC) /* - * Apple monitor sense + * Apple monitor sense */ static int __devinit read_aty_sense(const struct atyfb_par *par) @@ -630,16 +625,16 @@ static int __devinit read_aty_sense(const struct atyfb_par *par) /* ------------------------------------------------------------------------- */ /* - * CRTC programming + * CRTC programming */ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) { #ifdef CONFIG_FB_ATY_GENERIC_LCD if (par->lcd_table != 0) { - if (!M64_HAS(LT_LCD_REGS)) { - crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); - aty_st_le32(LCD_INDEX, crtc->lcd_index, par); + if(!M64_HAS(LT_LCD_REGS)) { + crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); + aty_st_le32(LCD_INDEX, crtc->lcd_index, par); } crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); @@ -647,7 +642,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) /* switch to non shadow registers */ aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & - ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); + ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); /* save stretching */ crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); @@ -668,7 +663,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) if (par->lcd_table != 0) { /* switch to shadow registers */ aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | - SHADOW_EN | SHADOW_RW_EN, par); + SHADOW_EN | SHADOW_RW_EN, par); crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par); crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par); @@ -685,20 +680,21 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) #ifdef CONFIG_FB_ATY_GENERIC_LCD if (par->lcd_table != 0) { /* stop CRTC */ - aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & - ~(CRTC_EXT_DISP_EN | CRTC_EN), par); + aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); /* update non-shadow registers first */ aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & - ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); + ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); /* temporarily disable stretching */ - aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching & - ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); - aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching & - ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 | - VERT_STRETCH_USE0 | VERT_STRETCH_EN), par); + aty_st_lcd(HORZ_STRETCHING, + crtc->horz_stretching & + ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par); + aty_st_lcd(VERT_STRETCHING, + crtc->vert_stretching & + ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 | + VERT_STRETCH_USE0 | VERT_STRETCH_EN), par); } #endif /* turn off CRT */ @@ -706,19 +702,17 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) DPRINTK("setting up CRTC\n"); DPRINTK("set primary CRT to %ix%i %c%c composite %c\n", - ((((crtc->h_tot_disp >> 16) & 0xff) + 1) << 3), - (((crtc->v_tot_disp >> 16) & 0x7ff) + 1), - (crtc->h_sync_strt_wid & 0x200000) ? 'N' : 'P', - (crtc->v_sync_strt_wid & 0x200000) ? 'N' : 'P', - (crtc->gen_cntl & CRTC_CSYNC_EN) ? 'P' : 'N'); - - DPRINTK("CRTC_H_TOTAL_DISP: %x\n", crtc->h_tot_disp); - DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n", crtc->h_sync_strt_wid); - DPRINTK("CRTC_V_TOTAL_DISP: %x\n", crtc->v_tot_disp); - DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n", crtc->v_sync_strt_wid); + ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1), + (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P', + (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N'); + + DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp); + DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid); + DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp); + DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid); DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch); DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline); - DPRINTK("CRTC_GEN_CNTL: %x\n", crtc->gen_cntl); + DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl); aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par); aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par); @@ -738,22 +732,16 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) if (par->lcd_table != 0) { /* switch to shadow registers */ aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | - SHADOW_EN | SHADOW_RW_EN, par); + (SHADOW_EN | SHADOW_RW_EN), par); DPRINTK("set shadow CRT to %ix%i %c%c\n", - ((((crtc->shadow_h_tot_disp >> 16) & 0xff) + 1) << 3), - (((crtc->shadow_v_tot_disp >> 16) & 0x7ff) + 1), - (crtc->shadow_h_sync_strt_wid & 0x200000) ? 'N' : 'P', - (crtc->shadow_v_sync_strt_wid & 0x200000) ? 'N' : 'P'); - - DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", - crtc->shadow_h_tot_disp); - DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", - crtc->shadow_h_sync_strt_wid); - DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", - crtc->shadow_v_tot_disp); - DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", - crtc->shadow_v_sync_strt_wid); + ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), + (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); + + DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp); + DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid); + DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp); + DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid); aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par); aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par); @@ -764,16 +752,16 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl); DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching); DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching); - if (!M64_HAS(LT_LCD_REGS)) - DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); + if(!M64_HAS(LT_LCD_REGS)) + DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch); aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par); aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par); aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par); - if (!M64_HAS(LT_LCD_REGS)) { - aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); - aty_ld_le32(LCD_INDEX, par); - aty_st_le32(LCD_INDEX, crtc->lcd_index, par); + if(!M64_HAS(LT_LCD_REGS)) { + aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par); + aty_ld_le32(LCD_INDEX, par); + aty_st_le32(LCD_INDEX, crtc->lcd_index, par); } } #endif /* CONFIG_FB_ATY_GENERIC_LCD */ @@ -791,8 +779,7 @@ static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) } static int aty_var_to_crtc(const struct fb_info *info, - const struct fb_var_screeninfo *var, - struct crtc *crtc) + const struct fb_var_screeninfo *var, struct crtc *crtc) { struct atyfb_par *par = (struct atyfb_par *) info->par; u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp; @@ -827,32 +814,34 @@ static int aty_var_to_crtc(const struct fb_info *info, if (bpp <= 8) { bpp = 8; pix_width = CRTC_PIX_WIDTH_8BPP; - dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | - BYTE_ORDER_LSB_TO_MSB; + dp_pix_width = + HOST_8BPP | SRC_8BPP | DST_8BPP | + BYTE_ORDER_LSB_TO_MSB; dp_chain_mask = DP_CHAIN_8BPP; } else if (bpp <= 15) { bpp = 16; pix_width = CRTC_PIX_WIDTH_15BPP; dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP | - BYTE_ORDER_LSB_TO_MSB; + BYTE_ORDER_LSB_TO_MSB; dp_chain_mask = DP_CHAIN_15BPP; } else if (bpp <= 16) { bpp = 16; pix_width = CRTC_PIX_WIDTH_16BPP; dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP | - BYTE_ORDER_LSB_TO_MSB; + BYTE_ORDER_LSB_TO_MSB; dp_chain_mask = DP_CHAIN_16BPP; } else if (bpp <= 24 && M64_HAS(INTEGRATED)) { bpp = 24; pix_width = CRTC_PIX_WIDTH_24BPP; - dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | - BYTE_ORDER_LSB_TO_MSB; + dp_pix_width = + HOST_8BPP | SRC_8BPP | DST_8BPP | + BYTE_ORDER_LSB_TO_MSB; dp_chain_mask = DP_CHAIN_24BPP; } else if (bpp <= 32) { bpp = 32; pix_width = CRTC_PIX_WIDTH_32BPP; dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP | - BYTE_ORDER_LSB_TO_MSB; + BYTE_ORDER_LSB_TO_MSB; dp_chain_mask = DP_CHAIN_32BPP; } else FAIL("invalid bpp"); @@ -865,9 +854,9 @@ static int aty_var_to_crtc(const struct fb_info *info, h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; - if ((xres > 1600) || (yres > 1200)) { + if((xres > 1600) || (yres > 1200)) { FAIL("MACH64 chips are designed for max 1600x1200\n" - "select anoter resolution."); + "select anoter resolution."); } h_sync_strt = h_disp + var->right_margin; h_sync_end = h_sync_strt + var->hsync_len; @@ -880,12 +869,11 @@ static int aty_var_to_crtc(const struct fb_info *info, #ifdef CONFIG_FB_ATY_GENERIC_LCD if (par->lcd_table != 0) { - if (!M64_HAS(LT_LCD_REGS)) { - u32 lcd_index = aty_ld_le32(LCD_INDEX, par); - crtc->lcd_index = lcd_index & - ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | - LCD_SRC_SEL | CRTC2_DISPLAY_DIS); - aty_st_le32(LCD_INDEX, lcd_index, par); + if(!M64_HAS(LT_LCD_REGS)) { + u32 lcd_index = aty_ld_le32(LCD_INDEX, par); + crtc->lcd_index = lcd_index & + ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS); + aty_st_le32(LCD_INDEX, lcd_index, par); } if (!M64_HAS(MOBIL_BUS)) @@ -900,14 +888,12 @@ static int aty_var_to_crtc(const struct fb_info *info, USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT; - if ((crtc->lcd_gen_cntl & LCD_ON) && - ((xres > par->lcd_width) || (yres > par->lcd_height))) { - /* - * We cannot display the mode on the LCD. If the CRT is - * enabled we can turn off the LCD. - * If the CRT is off, it isn't a good idea to switch it - * on; we don't know if one is connected. So it's better - * to fail then. + if((crtc->lcd_gen_cntl & LCD_ON) && + ((xres > par->lcd_width) || (yres > par->lcd_height))) { + /* We cannot display the mode on the LCD. If the CRT is enabled + we can turn off the LCD. + If the CRT is off, it isn't a good idea to switch it on; we don't + know if one is connected. So it's better to fail then. */ if (crtc->lcd_gen_cntl & CRT_ON) { if (!(var->activate & FB_ACTIVATE_TEST)) @@ -930,18 +916,17 @@ static int aty_var_to_crtc(const struct fb_info *info, vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); - /* - * This is horror! When we simulate, say 640x480 on an 800x600 - * LCD monitor, the CRTC should be programmed 800x600 values for - * the non visible part, but 640x480 for the visible part. - * This code has been tested on a laptop with it's 1400x1050 LCD - * monitor and a conventional monitor both switched on. - * Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, - * works with little glitches also with DOUBLESCAN modes + /* This is horror! When we simulate, say 640x480 on an 800x600 + LCD monitor, the CRTC should be programmed 800x600 values for + the non visible part, but 640x480 for the visible part. + This code has been tested on a laptop with it's 1400x1050 LCD + monitor and a conventional monitor both switched on. + Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, + works with little glitches also with DOUBLESCAN modes */ if (yres < par->lcd_height) { VScan = par->lcd_height / yres; - if (VScan > 1) { + if(VScan > 1) { VScan = 2; vmode |= FB_VMODE_DOUBLE; } @@ -967,7 +952,7 @@ static int aty_var_to_crtc(const struct fb_info *info, FAIL_MAX("h_disp too large", h_disp, 0xff); FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff); /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/ - if (h_sync_wid > 0x1f) + if(h_sync_wid > 0x1f) h_sync_wid = 0x1f; FAIL_MAX("h_total too large", h_total, 0x1ff); @@ -993,7 +978,7 @@ static int aty_var_to_crtc(const struct fb_info *info, FAIL_MAX("v_disp too large", v_disp, 0x7ff); FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff); /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/ - if (v_sync_wid > 0x1f) + if(v_sync_wid > 0x1f) v_sync_wid = 0x1f; FAIL_MAX("v_total too large", v_total, 0x7ff); @@ -1010,13 +995,11 @@ static int aty_var_to_crtc(const struct fb_info *info, ((line_length / bpp) << 22); crtc->vline_crnt_vline = 0; - crtc->h_tot_disp = h_total | (h_disp << 16); - crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) | - ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) | - (h_sync_pol << 21); - crtc->v_tot_disp = v_total | (v_disp << 16); - crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) | - (v_sync_pol << 21); + crtc->h_tot_disp = h_total | (h_disp<<16); + crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) | + ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21); + crtc->v_tot_disp = v_total | (v_disp<<16); + crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21); /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */ crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync; @@ -1031,15 +1014,13 @@ static int aty_var_to_crtc(const struct fb_info *info, #ifdef CONFIG_FB_ATY_GENERIC_LCD if (par->lcd_table != 0) { vdisplay = yres; - if (vmode & FB_VMODE_DOUBLE) + if(vmode & FB_VMODE_DOUBLE) vdisplay <<= 1; crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | - /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ - USE_SHADOWED_VEND | - USE_SHADOWED_ROWCUR | - SHADOW_EN | SHADOW_RW_EN); - crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR/* | LOCK_8DOT*/; + /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ + USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN); + crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/); /* MOBILITY M1 tested, FIXME: LT */ crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par); @@ -1047,32 +1028,28 @@ static int aty_var_to_crtc(const struct fb_info *info, crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) & ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3); - crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO | - HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | - HORZ_STRETCH_MODE | HORZ_STRETCH_EN); + crtc->horz_stretching &= + ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | + HORZ_STRETCH_MODE | HORZ_STRETCH_EN); if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { do { /* - * The horizontal blender misbehaves when - * HDisplay is less than a certain threshold - * (440 for a 1024-wide panel). It doesn't - * stretch such modes enough. Use pixel - * replication instead of blending to stretch - * modes that can be made to exactly fit the - * panel width. The undocumented "NoLCDBlend" - * option allows the pixel-replicated mode to - * be slightly wider or narrower than the - * panel width. It also causes a mode that is - * exactly half as wide as the panel to be - * pixel-replicated, rather than blended. - */ + * The horizontal blender misbehaves when HDisplay is less than a + * a certain threshold (440 for a 1024-wide panel). It doesn't + * stretch such modes enough. Use pixel replication instead of + * blending to stretch modes that can be made to exactly fit the + * panel width. The undocumented "NoLCDBlend" option allows the + * pixel-replicated mode to be slightly wider or narrower than the + * panel width. It also causes a mode that is exactly half as wide + * as the panel to be pixel-replicated, rather than blended. + */ int HDisplay = xres & ~7; int nStretch = par->lcd_width / HDisplay; int Remainder = par->lcd_width % HDisplay; if ((!Remainder && ((nStretch > 2))) || - (((HDisplay * 16) / par->lcd_width) < 7)) { - static const char StretchLoops[] = { 10, 12, 13, 15, 16 }; + (((HDisplay * 16) / par->lcd_width) < 7)) { + static const char StretchLoops[] = {10, 12, 13, 15, 16}; int horz_stretch_loop = -1, BestRemainder; int Numerator = HDisplay, Denominator = par->lcd_width; int Index = 5; @@ -1121,12 +1098,12 @@ static int aty_var_to_crtc(const struct fb_info *info, (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); if (!M64_HAS(LT_LCD_REGS) && - xres <= (M64_HAS(MOBIL_BUS) ? 1024 : 800)) + xres <= (M64_HAS(MOBIL_BUS)?1024:800)) crtc->ext_vert_stretch |= VERT_STRETCH_MODE; } else { /* - * Don't use vertical blending if the mode is too wide - * or not vertically stretched. + * Don't use vertical blending if the mode is too wide or not + * vertically stretched. */ crtc->vert_stretching = 0; } @@ -1148,11 +1125,11 @@ static int aty_var_to_crtc(const struct fb_info *info, return 0; } -static int aty_crtc_to_var(const struct crtc *crtc, - struct fb_var_screeninfo *var) +static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var) { u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync; - u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol; + u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, + h_sync_pol; u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync; u32 pix_width; u32 double_scan, interlace; @@ -1184,8 +1161,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, lower = v_sync_strt - v_disp; vslen = v_sync_wid; sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) | - (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | - (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); + (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) | + (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0); switch (pix_width) { #if 0 @@ -1275,21 +1252,20 @@ static int aty_crtc_to_var(const struct crtc *crtc, var->vsync_len = vslen; var->sync = sync; var->vmode = FB_VMODE_NONINTERLACED; - /* - * In double scan mode, the vertical parameters are doubled, - * so we need to halve them to get the right values. - * In interlaced mode the values are already correct, - * so no correction is necessary. + /* In double scan mode, the vertical parameters are doubled, so we need to + half them to get the right values. + In interlaced mode the values are already correct, so no correction is + necessary. */ if (interlace) var->vmode = FB_VMODE_INTERLACED; if (double_scan) { var->vmode = FB_VMODE_DOUBLE; - var->yres >>= 1; - var->upper_margin >>= 1; - var->lower_margin >>= 1; - var->vsync_len >>= 1; + var->yres>>=1; + var->upper_margin>>=1; + var->lower_margin>>=1; + var->vsync_len>>=1; } return 0; @@ -1310,8 +1286,7 @@ static int atyfb_set_par(struct fb_info *info) if (par->asleep) return 0; - err = aty_var_to_crtc(info, var, &par->crtc); - if (err) + if ((err = aty_var_to_crtc(info, var, &par->crtc))) return err; pixclock = atyfb_get_pixclock(var, par); @@ -1320,9 +1295,7 @@ static int atyfb_set_par(struct fb_info *info) PRINTKE("Invalid pixclock\n"); return -EINVAL; } else { - err = par->pll_ops->var_to_pll(info, pixclock, - var->bits_per_pixel, &par->pll); - if (err) + if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) return err; } @@ -1340,23 +1313,22 @@ static int atyfb_set_par(struct fb_info *info) wait_for_idle(par); aty_set_crtc(par, &par->crtc); - par->dac_ops->set_dac(info, &par->pll, - var->bits_per_pixel, par->accel_flags); + par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags); par->pll_ops->set_pll(info, &par->pll); #ifdef DEBUG - if (par->pll_ops && par->pll_ops->pll_to_var) - pixclock_in_ps = par->pll_ops->pll_to_var(info, &par->pll); + if(par->pll_ops && par->pll_ops->pll_to_var) + pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll)); else pixclock_in_ps = 0; - if (0 == pixclock_in_ps) { + if(0 == pixclock_in_ps) { PRINTKE("ALERT ops->pll_to_var get 0\n"); pixclock_in_ps = pixclock; } memset(&debug, 0, sizeof(debug)); - if (!aty_crtc_to_var(&par->crtc, &debug)) { + if(!aty_crtc_to_var(&(par->crtc), &debug)) { u32 hSync, vRefresh; u32 h_disp, h_sync_strt, h_sync_end, h_total; u32 v_disp, v_sync_strt, v_sync_end, v_total; @@ -1372,20 +1344,16 @@ static int atyfb_set_par(struct fb_info *info) hSync = 1000000000 / (pixclock_in_ps * h_total); vRefresh = (hSync * 1000) / v_total; - if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) - vRefresh *= 2; - if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) - vRefresh /= 2; + if (par->crtc.gen_cntl & CRTC_INTERLACE_EN) + vRefresh *= 2; + if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) + vRefresh /= 2; DPRINTK("atyfb_set_par\n"); - DPRINTK(" Set Visible Mode to %ix%i-%i\n", - var->xres, var->yres, var->bits_per_pixel); - DPRINTK(" Virtual resolution %ix%i, " - "pixclock_in_ps %i (calculated %i)\n", - var->xres_virtual, var->yres_virtual, - pixclock, pixclock_in_ps); - DPRINTK(" Dot clock: %i MHz\n", - 1000000 / pixclock_in_ps); + DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel); + DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n", + var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps); + DPRINTK(" Dot clock: %i MHz\n", 1000000 / pixclock_in_ps); DPRINTK(" Horizontal sync: %i kHz\n", hSync); DPRINTK(" Vertical refresh: %i Hz\n", vRefresh); DPRINTK(" x style: %i.%03i %i %i %i %i %i %i %i %i\n", @@ -1480,8 +1448,7 @@ static int atyfb_set_par(struct fb_info *info) base = 0x2000; printk("debug atyfb: Mach64 non-shadow register values:"); for (i = 0; i < 256; i = i+4) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%04X: ", base + i); + if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i); printk(" %08X", aty_ld_le32(i, par)); } printk("\n\n"); @@ -1491,10 +1458,8 @@ static int atyfb_set_par(struct fb_info *info) base = 0x00; printk("debug atyfb: Mach64 PLL register values:"); for (i = 0; i < 64; i++) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%02X: ", base + i); - if (i % 4 == 0) - printk(" "); + if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); + if(i%4 == 0) printk(" "); printk("%02X", aty_ld_pll_ct(i, par)); } printk("\n\n"); @@ -1505,21 +1470,19 @@ static int atyfb_set_par(struct fb_info *info) /* LCD registers */ base = 0x00; printk("debug atyfb: LCD register values:"); - if (M64_HAS(LT_LCD_REGS)) { - for (i = 0; i <= POWER_MANAGEMENT; i++) { - if (i == EXT_VERT_STRETCH) - continue; - printk("\ndebug atyfb: 0x%04X: ", - lt_lcd_regs[i]); - printk(" %08X", aty_ld_lcd(i, par)); - } + if(M64_HAS(LT_LCD_REGS)) { + for(i = 0; i <= POWER_MANAGEMENT; i++) { + if(i == EXT_VERT_STRETCH) + continue; + printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]); + printk(" %08X", aty_ld_lcd(i, par)); + } + } else { - for (i = 0; i < 64; i++) { - if (i % 4 == 0) - printk("\ndebug atyfb: 0x%02X: ", - base + i); - printk(" %08X", aty_ld_lcd(i, par)); - } + for (i = 0; i < 64; i++) { + if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i); + printk(" %08X", aty_ld_lcd(i, par)); + } } printk("\n\n"); } @@ -1537,10 +1500,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) union aty_pll pll; u32 pixclock; - memcpy(&pll, &par->pll, sizeof(pll)); + memcpy(&pll, &(par->pll), sizeof(pll)); - err = aty_var_to_crtc(info, var, &crtc); - if (err) + if((err = aty_var_to_crtc(info, var, &crtc))) return err; pixclock = atyfb_get_pixclock(var, par); @@ -1550,9 +1512,7 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) PRINTKE("Invalid pixclock\n"); return -EINVAL; } else { - err = par->pll_ops->var_to_pll(info, pixclock, - var->bits_per_pixel, &pll); - if (err) + if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) return err; } @@ -1579,9 +1539,9 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) } -/* - * Open/Release the frame buffer device - */ + /* + * Open/Release the frame buffer device + */ static int atyfb_open(struct fb_info *info, int user) { @@ -1593,7 +1553,7 @@ static int atyfb_open(struct fb_info *info, int user) par->mmaped = 0; #endif } - return 0; + return (0); } static irqreturn_t aty_irq(int irq, void *dev_id) @@ -1608,8 +1568,7 @@ static irqreturn_t aty_irq(int irq, void *dev_id) if (int_cntl & CRTC_VBLANK_INT) { /* clear interrupt */ - aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | - CRTC_VBLANK_INT_AK, par); + aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par); par->vblank.count++; if (par->vblank.pan_display) { par->vblank.pan_display = 0; @@ -1644,11 +1603,9 @@ static int aty_enable_irq(struct atyfb_par *par, int reenable) spin_lock_irq(&par->int_lock); int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; if (!(int_cntl & CRTC_VBLANK_INT_EN)) { - printk("atyfb: someone disabled IRQ [%08x]\n", - int_cntl); + printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl); /* re-enable interrupt */ - aty_st_le32(CRTC_INT_CNTL, int_cntl | - CRTC_VBLANK_INT_EN, par); + aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par ); } spin_unlock_irq(&par->int_lock); } @@ -1668,7 +1625,7 @@ static int aty_disable_irq(struct atyfb_par *par) spin_lock_irq(&par->int_lock); int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK; /* disable interrupt */ - aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par); + aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par ); spin_unlock_irq(&par->int_lock); free_irq(par->irq, par); } @@ -1679,62 +1636,50 @@ static int aty_disable_irq(struct atyfb_par *par) static int atyfb_release(struct fb_info *info, int user) { struct atyfb_par *par = (struct atyfb_par *) info->par; + if (user) { + par->open--; + mdelay(1); + wait_for_idle(par); + if (!par->open) { #ifdef __sparc__ - int was_mmaped; -#endif - - if (!user) - return 0; - - par->open--; - mdelay(1); - wait_for_idle(par); - - if (par->open) - return 0; - -#ifdef __sparc__ - was_mmaped = par->mmaped; + int was_mmaped = par->mmaped; - par->mmaped = 0; + par->mmaped = 0; - if (was_mmaped) { - struct fb_var_screeninfo var; + if (was_mmaped) { + struct fb_var_screeninfo var; - /* - * Now reset the default display config, we have - * no idea what the program(s) which mmap'd the - * chip did to the configuration, nor whether it - * restored it correctly. - */ - var = default_var; - if (noaccel) - var.accel_flags &= ~FB_ACCELF_TEXT; - else - var.accel_flags |= FB_ACCELF_TEXT; - if (var.yres == var.yres_virtual) { - u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); - var.yres_virtual = - ((videoram * 8) / var.bits_per_pixel) / - var.xres_virtual; - if (var.yres_virtual < var.yres) - var.yres_virtual = var.yres; + /* Now reset the default display config, we have no + * idea what the program(s) which mmap'd the chip did + * to the configuration, nor whether it restored it + * correctly. + */ + var = default_var; + if (noaccel) + var.accel_flags &= ~FB_ACCELF_TEXT; + else + var.accel_flags |= FB_ACCELF_TEXT; + if (var.yres == var.yres_virtual) { + u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2)); + var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual; + if (var.yres_virtual < var.yres) + var.yres_virtual = var.yres; + } + } +#endif + aty_disable_irq(par); } } -#endif - aty_disable_irq(par); - - return 0; + return (0); } -/* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ + /* + * Pan or Wrap the Display + * + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag + */ -static int atyfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) +static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { struct atyfb_par *par = (struct atyfb_par *) info->par; u32 xres, yres, xoffset, yoffset; @@ -1745,8 +1690,7 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, yres >>= 1; xoffset = (var->xoffset + 7) & ~7; yoffset = var->yoffset; - if (xoffset + xres > par->crtc.vxres || - yoffset + yres > par->crtc.vyres) + if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres) return -EINVAL; info->var.xoffset = xoffset; info->var.yoffset = yoffset; @@ -1783,10 +1727,10 @@ static int aty_waitforvblank(struct atyfb_par *par, u32 crtc) return ret; count = vbl->count; - ret = wait_event_interruptible_timeout(vbl->wait, - count != vbl->count, HZ/10); - if (ret < 0) + ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10); + if (ret < 0) { return ret; + } if (ret == 0) { aty_enable_irq(par, 1); return -ETIMEDOUT; @@ -1840,8 +1784,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) fbtyp.fb_depth = info->var.bits_per_pixel; fbtyp.fb_cmsize = info->cmap.len; fbtyp.fb_size = info->fix.smem_len; - if (copy_to_user((struct fbtype __user *) arg, &fbtyp, - sizeof(fbtyp))) + if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp))) return -EFAULT; break; #endif /* __sparc__ */ @@ -1861,7 +1804,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) case ATYIO_CLKR: if (M64_HAS(INTEGRATED)) { struct atyclk clk; - union aty_pll *pll = &par->pll; + union aty_pll *pll = &(par->pll); u32 dsp_config = pll->ct.dsp_config; u32 dsp_on_off = pll->ct.dsp_on_off; clk.ref_clk_per = par->ref_clk_per; @@ -1886,9 +1829,8 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) case ATYIO_CLKW: if (M64_HAS(INTEGRATED)) { struct atyclk clk; - union aty_pll *pll = &par->pll; - if (copy_from_user(&clk, (struct atyclk __user *) arg, - sizeof(clk))) + union aty_pll *pll = &(par->pll); + if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk))) return -EFAULT; par->ref_clk_per = clk.ref_clk_per; pll->ct.pll_ref_div = clk.pll_ref_div; @@ -1899,10 +1841,8 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) pll->ct.vclk_fb_div = clk.vclk_fb_div; pll->ct.vclk_post_div_real = clk.vclk_post_div; pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) | - ((clk.dsp_loop_latency & 0xf) << 16) | - ((clk.dsp_precision & 7) << 20); - pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | - ((clk.dsp_on & 0x7ff) << 16); + ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20); + pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16); /*aty_calc_pll_ct(info, &pll->ct);*/ aty_set_pll_ct(info, pll); } else @@ -1973,7 +1913,8 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) continue; map_size = par->mmap_map[i].size - (offset - start); - map_offset = par->mmap_map[i].poff + (offset - start); + map_offset = + par->mmap_map[i].poff + (offset - start); break; } if (!map_size) { @@ -1983,7 +1924,8 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) if (page + map_size > size) map_size = size - page; - pgprot_val(vma->vm_page_prot) &= ~(par->mmap_map[i].prot_mask); + pgprot_val(vma->vm_page_prot) &= + ~(par->mmap_map[i].prot_mask); pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag; if (remap_pfn_range(vma, vma->vm_start + page, @@ -2087,8 +2029,7 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) par->asleep = 1; par->lock_blank = 1; - /* - * Because we may change PCI D state ourselves, we need to + /* Because we may change PCI D state ourselves, we need to * first save the config space content so the core can * restore it properly on resume. */ @@ -2139,8 +2080,7 @@ static int atyfb_pci_resume(struct pci_dev *pdev) acquire_console_sem(); - /* - * PCI state will have been restored by the core, so + /* PCI state will have been restored by the core, so * we should be in D0 now with our config space fully * restored */ @@ -2252,8 +2192,8 @@ static void aty_bl_init(struct atyfb_par *par) info->bl_dev = bd; fb_bl_default_curve(info, 0, - 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, - 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); + 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, + 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; @@ -2296,16 +2236,16 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) size = ARRAY_SIZE(ragepro_tbl); } - for (i = 0; i < size; i++) { + for (i=0; i < size; i++) { if (xclk < refresh_tbl[i]) - break; + break; } par->mem_refresh_rate = i; } -/* - * Initialisation - */ + /* + * Initialisation + */ static struct fb_info *fb_list = NULL; @@ -2435,10 +2375,8 @@ static int __devinit aty_init(struct fb_info *info) } #endif #ifdef CONFIG_PPC_PMAC - /* - * The Apple iBook1 uses non-standard memory frequencies. - * We detect it and set the frequency manually. - */ + /* The Apple iBook1 uses non-standard memory frequencies. We detect it + * and set the frequency manually. */ if (machine_is_compatible("PowerBook2,1")) { par->pll_limits.mclk = 70; par->pll_limits.xclk = 53; @@ -2483,14 +2421,13 @@ static int __devinit aty_init(struct fb_info *info) /* save previous video mode */ aty_get_crtc(par, &par->saved_crtc); - if (par->pll_ops->get_pll) + if(par->pll_ops->get_pll) par->pll_ops->get_pll(info, &par->saved_pll); par->mem_cntl = aty_ld_le32(MEM_CNTL, par); gtb_memsize = M64_HAS(GTB_DSP); if (gtb_memsize) - /* 0xF used instead of MEM_SIZE_ALIAS */ - switch (par->mem_cntl & 0xF) { + switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ case MEM_SIZE_512K: info->fix.smem_len = 0x80000; break; @@ -2559,8 +2496,8 @@ static int __devinit aty_init(struct fb_info *info) } /* - * Reg Block 0 (CT-compatible block) is at mmio_start - * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 + * Reg Block 0 (CT-compatible block) is at mmio_start + * Reg Block 1 (multimedia extensions) is at mmio_start - 0x400 */ if (M64_HAS(GX)) { info->fix.mmio_len = 0x400; @@ -2579,98 +2516,84 @@ static int __devinit aty_init(struct fb_info *info) } PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n", - info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len>>20), - info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, - par->pll_limits.pll_max, par->pll_limits.mclk, - par->pll_limits.xclk); + info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20), + info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max, + par->pll_limits.mclk, par->pll_limits.xclk); #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) if (M64_HAS(INTEGRATED)) { int i; - printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL " - "EXT_MEM_CNTL CRTC_GEN_CNTL DSP_CONFIG " - "DSP_ON_OFF CLOCK_CNTL\n" - "debug atyfb: %08x %08x %08x " - "%08x %08x %08x " - "%08x %08x\n" + printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL " + "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n" + "debug atyfb: %08x %08x %08x %08x %08x %08x %08x %08x\n" "debug atyfb: PLL", - aty_ld_le32(BUS_CNTL, par), - aty_ld_le32(DAC_CNTL, par), - aty_ld_le32(MEM_CNTL, par), - aty_ld_le32(EXT_MEM_CNTL, par), - aty_ld_le32(CRTC_GEN_CNTL, par), - aty_ld_le32(DSP_CONFIG, par), - aty_ld_le32(DSP_ON_OFF, par), - aty_ld_le32(CLOCK_CNTL, par)); + aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par), + aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par), + aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par), + aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par)); for (i = 0; i < 40; i++) printk(" %02x", aty_ld_pll_ct(i, par)); printk("\n"); } #endif - if (par->pll_ops->init_pll) + if(par->pll_ops->init_pll) par->pll_ops->init_pll(info, &par->pll); if (par->pll_ops->resume_pll) par->pll_ops->resume_pll(info, &par->pll); /* - * Last page of 8 MB (4 MB on ISA) aperture is MMIO, - * unless the auxiliary register aperture is used. + * Last page of 8 MB (4 MB on ISA) aperture is MMIO, + * unless the auxiliary register aperture is used. */ + if (!par->aux_start && - (info->fix.smem_len == 0x800000 || - (par->bus_type == ISA && info->fix.smem_len == 0x400000))) + (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000))) info->fix.smem_len -= GUI_RESERVE; /* - * Disable register access through the linear aperture - * if the auxiliary aperture is used so we can access - * the full 8 MB of video RAM on 8 MB boards. + * Disable register access through the linear aperture + * if the auxiliary aperture is used so we can access + * the full 8 MB of video RAM on 8 MB boards. */ if (par->aux_start) - aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | - BUS_APER_REG_DIS, par); + aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par); #ifdef CONFIG_MTRR par->mtrr_aper = -1; par->mtrr_reg = -1; if (!nomtrr) { /* Cover the whole resource. */ - par->mtrr_aper = mtrr_add(par->res_start, par->res_size, - MTRR_TYPE_WRCOMB, 1); - if (par->mtrr_aper >= 0 && !par->aux_start) { + par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1); + if (par->mtrr_aper >= 0 && !par->aux_start) { /* Make a hole for mmio. */ - par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - - GUI_RESERVE, GUI_RESERVE, - MTRR_TYPE_UNCACHABLE, 1); + par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE, + GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1); if (par->mtrr_reg < 0) { mtrr_del(par->mtrr_aper, 0, 0); par->mtrr_aper = -1; } - } + } } #endif info->fbops = &atyfb_ops; info->pseudo_palette = par->pseudo_palette; info->flags = FBINFO_DEFAULT | - FBINFO_HWACCEL_IMAGEBLIT | - FBINFO_HWACCEL_FILLRECT | - FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_YPAN; + FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_YPAN; #ifdef CONFIG_PMAC_BACKLIGHT if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { - /* - * these bits let the 101 powerbook - * wake up from sleep -- paulus - */ - aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) | - USE_F32KHZ | TRISTATE_MEM_EN, par); + /* these bits let the 101 powerbook wake up from sleep -- paulus */ + aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par) + | (USE_F32KHZ | TRISTATE_MEM_EN), par); } else #endif if (M64_HAS(MOBIL_BUS) && backlight) { #ifdef CONFIG_FB_ATY_BACKLIGHT - aty_bl_init(par); + aty_bl_init (par); #endif } @@ -2678,8 +2601,8 @@ static int __devinit aty_init(struct fb_info *info) #ifdef CONFIG_PPC if (machine_is(powermac)) { /* - * FIXME: The NVRAM stuff should be put in a Mac-specific file, - * as it applies to all Mac video cards + * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it + * applies to all Mac video cards */ if (mode) { if (mac_find_mode(&var, info, mode, 8)) @@ -2692,7 +2615,8 @@ static int __devinit aty_init(struct fb_info *info) default_vmode = VMODE_1024_768_60; else if (machine_is_compatible("iMac")) default_vmode = VMODE_1024_768_75; - else if (machine_is_compatible("PowerBook2,1")) + else if (machine_is_compatible + ("PowerBook2,1")) /* iBook with 800x600 LCD */ default_vmode = VMODE_800_600_60; else @@ -2706,7 +2630,7 @@ static int __devinit aty_init(struct fb_info *info) if (default_cmode < CMODE_8 || default_cmode > CMODE_32) default_cmode = CMODE_8; if (!mac_vmode_to_var(default_vmode, default_cmode, - &var)) + &var)) has_var = 1; } } @@ -2778,12 +2702,12 @@ static int __devinit aty_init(struct fb_info *info) #ifdef CONFIG_MTRR if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; + mtrr_del(par->mtrr_reg, 0, 0); + par->mtrr_reg = -1; } if (par->mtrr_aper >= 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; + mtrr_del(par->mtrr_aper, 0, 0); + par->mtrr_aper = -1; } #endif return ret; @@ -2811,18 +2735,18 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num) phys_size[m64_num] = size; phys_guiregbase[m64_num] = guiregbase; PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size, - guiregbase); + guiregbase); return 0; - mach64_invalid: + mach64_invalid: phys_vmembase[m64_num] = 0; return -1; } #endif /* CONFIG_ATARI */ -/* - * Blank the display. - */ + /* + * Blank the display. + */ static int atyfb_blank(int blank, struct fb_info *info) { @@ -2844,20 +2768,20 @@ static int atyfb_blank(int blank, struct fb_info *info) gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); gen_cntl &= ~0x400004c; switch (blank) { - case FB_BLANK_UNBLANK: - break; - case FB_BLANK_NORMAL: - gen_cntl |= 0x4000040; - break; - case FB_BLANK_VSYNC_SUSPEND: - gen_cntl |= 0x4000048; - break; - case FB_BLANK_HSYNC_SUSPEND: - gen_cntl |= 0x4000044; - break; - case FB_BLANK_POWERDOWN: - gen_cntl |= 0x400004c; - break; + case FB_BLANK_UNBLANK: + break; + case FB_BLANK_NORMAL: + gen_cntl |= 0x4000040; + break; + case FB_BLANK_VSYNC_SUSPEND: + gen_cntl |= 0x4000048; + break; + case FB_BLANK_HSYNC_SUSPEND: + gen_cntl |= 0x4000044; + break; + case FB_BLANK_POWERDOWN: + gen_cntl |= 0x400004c; + break; } aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); @@ -2882,15 +2806,15 @@ static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue, aty_st_8(DAC_DATA, blue, par); } -/* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR - */ + /* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + * !! 4 & 8 = PSEUDO, > 8 = DIRECTCOLOR + */ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) + u_int transp, struct fb_info *info) { struct atyfb_par *par = (struct atyfb_par *) info->par; int i, depth; @@ -2944,15 +2868,16 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, if (depth == 16) { if (regno < 32) aty_st_pal(regno << 3, red, - par->palette[regno << 1].green, + par->palette[regno<<1].green, blue, par); - red = par->palette[regno >> 1].red; - blue = par->palette[regno >> 1].blue; + red = par->palette[regno>>1].red; + blue = par->palette[regno>>1].blue; regno <<= 2; } else if (depth == 15) { regno <<= 3; - for (i = 0; i < 8; i++) - aty_st_pal(regno + i, red, green, blue, par); + for(i = 0; i < 8; i++) { + aty_st_pal(regno + i, red, green, blue, par); + } } } aty_st_pal(regno, red, green, blue, par); @@ -2965,8 +2890,7 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, #ifdef __sparc__ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, - struct fb_info *info, - unsigned long addr) + struct fb_info *info, unsigned long addr) { struct atyfb_par *par = info->par; struct device_node *dp; @@ -3054,8 +2978,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, j++; } - ret = correct_chipset(par); - if (ret) + if((ret = correct_chipset(par))) return ret; if (IS_XL(pdev->device)) { @@ -3185,28 +3108,28 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) u32 driv_inf_tab, sig; u16 lcd_ofs; - /* - * To support an LCD panel, we should know it's dimensions and + /* To support an LCD panel, we should know it's dimensions and * it's desired pixel clock. * There are two ways to do it: * - Check the startup video mode and calculate the panel * size from it. This is unreliable. * - Read it from the driver information table in the video BIOS. - */ + */ /* Address of driver information table is at offset 0x78. */ driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78)); /* Check for the driver information table signature. */ - sig = *(u32 *)driv_inf_tab; + sig = (*(u32 *)driv_inf_tab); if ((sig == 0x54504c24) || /* Rage LT pro */ - (sig == 0x544d5224) || /* Rage mobility */ - (sig == 0x54435824) || /* Rage XC */ - (sig == 0x544c5824)) { /* Rage XL */ + (sig == 0x544d5224) || /* Rage mobility */ + (sig == 0x54435824) || /* Rage XC */ + (sig == 0x544c5824)) { /* Rage XL */ PRINTKI("BIOS contains driver information table.\n"); - lcd_ofs = *(u16 *)(driv_inf_tab + 10); + lcd_ofs = (*(u16 *)(driv_inf_tab + 10)); par->lcd_table = 0; - if (lcd_ofs != 0) + if (lcd_ofs != 0) { par->lcd_table = bios_base + lcd_ofs; + } } if (par->lcd_table != 0) { @@ -3221,16 +3144,14 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) u16 width, height, panel_type, refresh_rates; u16 *lcdmodeptr; u32 format; - u8 lcd_refresh_rates[16] = { 50, 56, 60, 67, 70, 72, 75, 76, 85, - 90, 100, 120, 140, 150, 160, 200 }; - /* - * The most important information is the panel size at + u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200}; + /* The most important information is the panel size at * offset 25 and 27, but there's some other nice information * which we print to the screen. */ id = *(u8 *)par->lcd_table; - strncpy(model, (char *)par->lcd_table+1, 24); - model[23] = 0; + strncpy(model,(char *)par->lcd_table+1,24); + model[23]=0; width = par->lcd_width = *(u16 *)(par->lcd_table+25); height = par->lcd_height = *(u16 *)(par->lcd_table+27); @@ -3243,7 +3164,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) txtdual = "dual (split) "; else txtdual = ""; - tech = (panel_type >> 2) & 63; + tech = (panel_type>>2) & 63; switch (tech) { case 0: txtmonitor = "passive matrix"; @@ -3303,24 +3224,22 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) } } PRINTKI("%s%s %s monitor detected: %s\n", - txtdual, txtcolour, txtmonitor, model); + txtdual ,txtcolour, txtmonitor, model); PRINTKI(" id=%d, %dx%d pixels, %s\n", id, width, height, txtformat); refresh_rates_buf[0] = 0; refresh_rates = *(u16 *)(par->lcd_table+62); m = 1; f = 0; - for (i = 0; i < 16; i++) { + for (i=0;i<16;i++) { if (refresh_rates & m) { if (f == 0) { - sprintf(strbuf, "%d", - lcd_refresh_rates[i]); + sprintf(strbuf, "%d", lcd_refresh_rates[i]); f++; } else { - sprintf(strbuf, ",%d", - lcd_refresh_rates[i]); + sprintf(strbuf, ",%d", lcd_refresh_rates[i]); } - strcat(refresh_rates_buf, strbuf); + strcat(refresh_rates_buf,strbuf); } m = m << 1; } @@ -3328,8 +3247,7 @@ static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) PRINTKI(" supports refresh rates [%s], default %d Hz\n", refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; - /* - * We now need to determine the crtc parameters for the + /* We now need to determine the crtc parameters for the * LCD monitor. This is tricky, because they are not stored * individually in the BIOS. Instead, the BIOS contains a * table of display modes that work for this monitor. @@ -3464,9 +3382,7 @@ static int __devinit init_from_bios(struct atyfb_par *par) } #endif /* __i386__ */ -static int __devinit atyfb_setup_generic(struct pci_dev *pdev, - struct fb_info *info, - unsigned long addr) +static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr) { struct atyfb_par *par = info->par; u16 tmp; @@ -3513,12 +3429,10 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, goto atyfb_setup_generic_fail; } - ret = correct_chipset(par); - if (ret) + if((ret = correct_chipset(par))) goto atyfb_setup_generic_fail; #ifdef __i386__ - ret = init_from_bios(par); - if (ret) + if((ret = init_from_bios(par))) goto atyfb_setup_generic_fail; #endif if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN)) @@ -3543,8 +3457,7 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, #endif /* !__sparc__ */ -static int __devinit atyfb_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long addr, res_start, res_size; struct fb_info *info; @@ -3569,10 +3482,10 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, /* Reserve space */ res_start = rp->start; res_size = rp->end - rp->start + 1; - if (!request_mem_region(res_start, res_size, "atyfb")) + if (!request_mem_region (res_start, res_size, "atyfb")) return -EBUSY; - /* Allocate framebuffer */ + /* Allocate framebuffer */ info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev); if (!info) { PRINTKE("atyfb_pci_probe() can't alloc fb_info\n"); @@ -3660,8 +3573,7 @@ static int __init atyfb_atari_probe(void) for (m64_num = 0; m64_num < mach64_count; m64_num++) { if (!phys_vmembase[m64_num] || !phys_size[m64_num] || !phys_guiregbase[m64_num]) { - PRINTKI("phys_*[%d] parameters not set => " - "returning early. \n", m64_num); + PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num); continue; } @@ -3677,8 +3589,8 @@ static int __init atyfb_atari_probe(void) par->irq = (unsigned int) -1; /* something invalid */ /* - * Map the video memory (physical address given) - * to somewhere in the kernel address space. + * Map the video memory (physical address given) to somewhere in the + * kernel address space. */ info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */ @@ -3749,12 +3661,12 @@ static void __devexit atyfb_remove(struct fb_info *info) #ifdef CONFIG_MTRR if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; + mtrr_del(par->mtrr_reg, 0, 0); + par->mtrr_reg = -1; } if (par->mtrr_aper >= 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; + mtrr_del(par->mtrr_aper, 0, 0); + par->mtrr_aper = -1; } #endif #ifndef __sparc__ @@ -3988,29 +3900,29 @@ static const struct dmi_system_id atyfb_reboot_ids[] = { static int __init atyfb_init(void) { - int err1 = 1, err2 = 1; + int err1 = 1, err2 = 1; #ifndef MODULE - char *option = NULL; + char *option = NULL; - if (fb_get_options("atyfb", &option)) - return -ENODEV; - atyfb_setup(option); + if (fb_get_options("atyfb", &option)) + return -ENODEV; + atyfb_setup(option); #endif #ifdef CONFIG_PCI - err1 = pci_register_driver(&atyfb_driver); + err1 = pci_register_driver(&atyfb_driver); #endif #ifdef CONFIG_ATARI - err2 = atyfb_atari_probe(); + err2 = atyfb_atari_probe(); #endif - if (err1 && err2) - return -ENODEV; + if (err1 && err2) + return -ENODEV; - if (dmi_check_system(atyfb_reboot_ids)) - register_reboot_notifier(&atyfb_reboot_notifier); + if (dmi_check_system(atyfb_reboot_ids)) + register_reboot_notifier(&atyfb_reboot_notifier); - return 0; + return 0; } static void __exit atyfb_exit(void) @@ -4039,7 +3951,8 @@ MODULE_PARM_DESC(mclk, "int: override memory clock"); module_param(xclk, int, 0); MODULE_PARM_DESC(xclk, "int: override accelerated engine clock"); module_param(comp_sync, int, 0); -MODULE_PARM_DESC(comp_sync, "Set composite sync signal to low (0) or high (1)"); +MODULE_PARM_DESC(comp_sync, + "Set composite sync signal to low (0) or high (1)"); module_param(mode, charp, 0); MODULE_PARM_DESC(mode, "Specify resolution as \"x[-][@]\" "); #ifdef CONFIG_MTRR diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index a699aab63820..378f27745a1d 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -715,11 +715,8 @@ int au1100fb_setup(char *options) } /* Mode option (only option that start with digit) */ else if (isdigit(this_opt[0])) { - mode = kstrdup(this_opt, GFP_KERNEL); - if (!mode) { - print_err("memory allocation failed"); - return -ENOMEM; - } + mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); + strncpy(mode, this_opt, strlen(this_opt) + 1); } /* Unsupported option */ else { diff --git a/trunk/drivers/video/backlight/corgi_lcd.c b/trunk/drivers/video/backlight/corgi_lcd.c index 2211a852af9c..f8a4bb20f41a 100644 --- a/trunk/drivers/video/backlight/corgi_lcd.c +++ b/trunk/drivers/video/backlight/corgi_lcd.c @@ -639,4 +639,3 @@ module_exit(corgi_lcd_exit); MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00"); MODULE_AUTHOR("Eric Miao "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:corgi-lcd"); diff --git a/trunk/drivers/video/backlight/ltv350qv.c b/trunk/drivers/video/backlight/ltv350qv.c index 4631ca8fa4a4..2eb206bf73e6 100644 --- a/trunk/drivers/video/backlight/ltv350qv.c +++ b/trunk/drivers/video/backlight/ltv350qv.c @@ -328,4 +328,3 @@ module_exit(ltv350qv_exit); MODULE_AUTHOR("Haavard Skinnemoen "); MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:ltv350qv"); diff --git a/trunk/drivers/video/backlight/tdo24m.c b/trunk/drivers/video/backlight/tdo24m.c index bbfb502add67..51422fc4f606 100644 --- a/trunk/drivers/video/backlight/tdo24m.c +++ b/trunk/drivers/video/backlight/tdo24m.c @@ -472,4 +472,3 @@ module_exit(tdo24m_exit); MODULE_AUTHOR("Eric Miao "); MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:tdo24m"); diff --git a/trunk/drivers/video/backlight/tosa_lcd.c b/trunk/drivers/video/backlight/tosa_lcd.c index 50ec17dfc517..b7fbc75a62fc 100644 --- a/trunk/drivers/video/backlight/tosa_lcd.c +++ b/trunk/drivers/video/backlight/tosa_lcd.c @@ -300,4 +300,4 @@ module_exit(tosa_lcd_exit); MODULE_AUTHOR("Dmitry Baryshkov"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA"); -MODULE_ALIAS("spi:tosa-lcd"); + diff --git a/trunk/drivers/video/backlight/vgg2432a4.c b/trunk/drivers/video/backlight/vgg2432a4.c index b49063c831e7..8e653b8a6f17 100644 --- a/trunk/drivers/video/backlight/vgg2432a4.c +++ b/trunk/drivers/video/backlight/vgg2432a4.c @@ -280,4 +280,5 @@ module_exit(vgg2432a4_exit); MODULE_AUTHOR("Ben Dooks "); MODULE_DESCRIPTION("VGG2432A4 LCD Driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:VGG2432A4"); + + diff --git a/trunk/drivers/video/console/bitblit.c b/trunk/drivers/video/console/bitblit.c index 6b7c8fbc5495..69864b1b3f9e 100644 --- a/trunk/drivers/video/console/bitblit.c +++ b/trunk/drivers/video/console/bitblit.c @@ -25,7 +25,7 @@ static inline void update_attr(u8 *dst, u8 *src, int attribute, struct vc_data *vc) { int i, offset = (vc->vc_font.height < 10) ? 1 : 2; - int width = DIV_ROUND_UP(vc->vc_font.width, 8); + int width = (vc->vc_font.width + 7) >> 3; unsigned int cellsize = vc->vc_font.height * width; u8 c; @@ -144,7 +144,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, int fg, int bg) { struct fb_image image; - u32 width = DIV_ROUND_UP(vc->vc_font.width, 8); + u32 width = (vc->vc_font.width + 7)/8; u32 cellsize = width * vc->vc_font.height; u32 maxcnt = info->pixmap.size/cellsize; u32 scan_align = info->pixmap.scan_align - 1; @@ -173,7 +173,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, cnt = count; image.width = vc->vc_font.width * cnt; - pitch = DIV_ROUND_UP(image.width, 8) + scan_align; + pitch = ((image.width + 7) >> 3) + scan_align; pitch &= ~scan_align; size = pitch * image.height + buf_align; size &= ~buf_align; @@ -239,7 +239,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, struct fb_cursor cursor; struct fbcon_ops *ops = info->fbcon_par; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; - int w = DIV_ROUND_UP(vc->vc_font.width, 8), c; + int w = (vc->vc_font.width + 7) >> 3, c; int y = real_y(ops->p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); int err = 1; diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 5a686cea23f4..3a44695b9c09 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -114,7 +114,6 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; static int fbcon_has_exited; static int primary_device = -1; -static int fbcon_has_console_bind; #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY static int map_override; @@ -545,8 +544,6 @@ static int fbcon_takeover(int show_logo) con2fb_map[i] = -1; } info_idx = -1; - } else { - fbcon_has_console_bind = 1; } return err; @@ -728,7 +725,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, int oldidx, int found) { struct fbcon_ops *ops = oldinfo->fbcon_par; - int err = 0, ret; + int err = 0; if (oldinfo->fbops->fb_release && oldinfo->fbops->fb_release(oldinfo, 0)) { @@ -755,14 +752,8 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, newinfo in an undefined state. Thus, a call to fb_set_par() may be needed for the newinfo. */ - if (newinfo->fbops->fb_set_par) { - ret = newinfo->fbops->fb_set_par(newinfo); - - if (ret) - printk(KERN_ERR "con2fb_release_oldinfo: " - "detected unhandled fb_set_par error, " - "error code %d\n", ret); - } + if (newinfo->fbops->fb_set_par) + newinfo->fbops->fb_set_par(newinfo); } return err; @@ -772,18 +763,11 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, int unit, int show_logo) { struct fbcon_ops *ops = info->fbcon_par; - int ret; ops->currcon = fg_console; - if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) { - ret = info->fbops->fb_set_par(info); - - if (ret) - printk(KERN_ERR "con2fb_init_display: detected " - "unhandled fb_set_par error, " - "error code %d\n", ret); - } + if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) + info->fbops->fb_set_par(info); ops->flags |= FBCON_FLAGS_INIT; ops->graphics = 0; @@ -1022,7 +1006,7 @@ static void fbcon_init(struct vc_data *vc, int init) struct vc_data *svc = *default_mode; struct display *t, *p = &fb_display[vc->vc_num]; int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; - int cap, ret; + int cap; if (info_idx == -1 || info == NULL) return; @@ -1108,15 +1092,8 @@ static void fbcon_init(struct vc_data *vc, int init) */ if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { if (info->fbops->fb_set_par && - !(ops->flags & FBCON_FLAGS_INIT)) { - ret = info->fbops->fb_set_par(info); - - if (ret) - printk(KERN_ERR "fbcon_init: detected " - "unhandled fb_set_par error, " - "error code %d\n", ret); - } - + !(ops->flags & FBCON_FLAGS_INIT)) + info->fbops->fb_set_par(info); ops->flags |= FBCON_FLAGS_INIT; } @@ -2142,7 +2119,7 @@ static int fbcon_switch(struct vc_data *vc) struct fbcon_ops *ops; struct display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var; - int i, ret, prev_console, charcnt = 256; + int i, prev_console, charcnt = 256; info = registered_fb[con2fb_map[vc->vc_num]]; ops = info->fbcon_par; @@ -2197,14 +2174,8 @@ static int fbcon_switch(struct vc_data *vc) if (old_info != NULL && (old_info != info || info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { - if (info->fbops->fb_set_par) { - ret = info->fbops->fb_set_par(info); - - if (ret) - printk(KERN_ERR "fbcon_switch: detected " - "unhandled fb_set_par error, " - "error code %d\n", ret); - } + if (info->fbops->fb_set_par) + info->fbops->fb_set_par(info); if (old_info != info) fbcon_del_cursor_timer(old_info); @@ -2952,10 +2923,6 @@ static int fbcon_unbind(void) ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); - - if (!ret) - fbcon_has_console_bind = 0; - return ret; } #else @@ -2969,9 +2936,6 @@ static int fbcon_fb_unbind(int idx) { int i, new_idx = -1, ret = 0; - if (!fbcon_has_console_bind) - return 0; - for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] != idx && con2fb_map[i] != -1) { diff --git a/trunk/drivers/video/console/newport_con.c b/trunk/drivers/video/console/newport_con.c index 3772433c49d1..d31b203bf654 100644 --- a/trunk/drivers/video/console/newport_con.c +++ b/trunk/drivers/video/console/newport_con.c @@ -216,7 +216,7 @@ static void newport_get_screensize(void) } newport_xsize = newport_ysize = 0; - for (i = 0; i < ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) { + for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) { cols = 0; newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]); npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index da55ccaf4d55..74e96cf83b7e 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -589,14 +589,12 @@ static void vgacon_init(struct vc_data *c, int init) static void vgacon_deinit(struct vc_data *c) { - /* When closing the active console, reset video origin */ - if (CON_IS_VISIBLE(c)) { + /* When closing the last console, reset video origin */ + if (!--vgacon_uni_pagedir[1]) { c->vc_visible_origin = vga_vram_base; vga_set_mem_top(c); - } - - if (!--vgacon_uni_pagedir[1]) con_free_unimap(c); + } c->vc_uni_pagedir_loc = &c->vc_uni_pagedir; con_set_default_unimap(c); } diff --git a/trunk/drivers/video/da8xx-fb.c b/trunk/drivers/video/da8xx-fb.c deleted file mode 100644 index 42e1005e2916..000000000000 --- a/trunk/drivers/video/da8xx-fb.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * Copyright (C) 2008-2009 MontaVista Software Inc. - * Copyright (C) 2008-2009 Texas Instruments Inc - * - * Based on the LCD driver for TI Avalanche processors written by - * Ajay Singh and Shalom Hai. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include