aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/i2c/writing-clients18
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--Documentation/networking/ip-sysctl.txt12
-rw-r--r--Documentation/networking/s2io.txt6
-rw-r--r--Documentation/video4linux/CARDLIST.au08282
-rw-r--r--MAINTAINERS8
-rw-r--r--arch/arm/Kconfig39
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/dmabounce.c3
-rw-r--r--arch/arm/common/rtctime.c434
-rw-r--r--arch/arm/configs/at91cap9adk_defconfig82
-rw-r--r--arch/arm/configs/at91rm9200dk_defconfig1
-rw-r--r--arch/arm/configs/at91rm9200ek_defconfig1
-rw-r--r--arch/arm/configs/at91sam9260ek_defconfig1
-rw-r--r--arch/arm/configs/at91sam9261ek_defconfig1
-rw-r--r--arch/arm/configs/at91sam9263ek_defconfig1
-rw-r--r--arch/arm/configs/at91sam9g20ek_defconfig1168
-rw-r--r--arch/arm/configs/at91sam9rlek_defconfig1
-rw-r--r--arch/arm/configs/ateb9200_defconfig1
-rw-r--r--arch/arm/configs/cm_x270_defconfig1
-rw-r--r--arch/arm/configs/collie_defconfig1
-rw-r--r--arch/arm/configs/corgi_defconfig1
-rw-r--r--arch/arm/configs/ecbat91_defconfig1
-rw-r--r--arch/arm/configs/em_x270_defconfig1
-rw-r--r--arch/arm/configs/ep93xx_defconfig1
-rw-r--r--arch/arm/configs/eseries_pxa_defconfig1
-rw-r--r--arch/arm/configs/iop13xx_defconfig1
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/iop33x_defconfig1
-rw-r--r--arch/arm/configs/ixp2000_defconfig1
-rw-r--r--arch/arm/configs/ixp23xx_defconfig1
-rw-r--r--arch/arm/configs/ixp4xx_defconfig9
-rw-r--r--arch/arm/configs/kafa_defconfig1
-rw-r--r--arch/arm/configs/kb9202_defconfig1
-rw-r--r--arch/arm/configs/ks8695_defconfig1
-rw-r--r--arch/arm/configs/lpd270_defconfig1
-rw-r--r--arch/arm/configs/lpd7a404_defconfig1
-rw-r--r--arch/arm/configs/netx_defconfig1
-rw-r--r--arch/arm/configs/onearm_defconfig1
-rw-r--r--arch/arm/configs/picotux200_defconfig1
-rw-r--r--arch/arm/configs/pnx4008_defconfig1
-rw-r--r--arch/arm/configs/qil-a9260_defconfig1256
-rw-r--r--arch/arm/configs/realview-smp_defconfig1
-rw-r--r--arch/arm/configs/realview_defconfig1
-rw-r--r--arch/arm/configs/rpc_defconfig1
-rw-r--r--arch/arm/configs/s3c2410_defconfig1043
-rw-r--r--arch/arm/configs/sam9_l9260_defconfig1
-rw-r--r--arch/arm/configs/spitz_defconfig1
-rw-r--r--arch/arm/configs/tct_hammer_defconfig1
-rw-r--r--arch/arm/configs/trizeps4_defconfig1
-rw-r--r--arch/arm/configs/usb-a9260_defconfig1142
-rw-r--r--arch/arm/configs/usb-a9263_defconfig1134
-rw-r--r--arch/arm/configs/versatile_defconfig1
-rw-r--r--arch/arm/kernel/atags.c83
-rw-r--r--arch/arm/kernel/ecard.c13
-rw-r--r--arch/arm/kernel/ecard.h13
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/arm/kernel/time.c120
-rw-r--r--arch/arm/mach-at91/Kconfig56
-rw-r--r--arch/arm/mach-at91/Makefile8
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c99
-rw-r--r--arch/arm/mach-at91/at91sam9260.c16
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c44
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c12
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c4
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c107
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c9
-rw-r--r--arch/arm/mach-at91/board-carmeva.c23
-rw-r--r--arch/arm/mach-at91/board-csb637.c4
-rw-r--r--arch/arm/mach-at91/board-dk.c25
-rw-r--r--arch/arm/mach-at91/board-eb9200.c26
-rw-r--r--arch/arm/mach-at91/board-ek.c25
-rw-r--r--arch/arm/mach-at91/board-kb9202.c29
-rw-r--r--arch/arm/mach-at91/board-qil-a9260.c255
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c218
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c10
-rw-r--r--arch/arm/mach-at91/board-usb-a9260.c215
-rw-r--r--arch/arm/mach-at91/board-usb-a9263.c230
-rwxr-xr-xarch/arm/mach-at91/board-yl-9200.c853
-rw-r--r--arch/arm/mach-at91/clock.c64
-rw-r--r--arch/arm/mach-at91/pm.c2
-rw-r--r--arch/arm/mach-ep93xx/clock.c5
-rw-r--r--arch/arm/mach-footbridge/Makefile2
-rw-r--r--arch/arm/mach-footbridge/co285.c39
-rw-r--r--arch/arm/mach-footbridge/common.c21
-rw-r--r--arch/arm/mach-footbridge/ebsa285-leds.c2
-rw-r--r--arch/arm/mach-footbridge/time.c3
-rw-r--r--arch/arm/mach-imx/dma.c13
-rw-r--r--arch/arm/mach-integrator/Makefile2
-rw-r--r--arch/arm/mach-integrator/time.c223
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig9
-rw-r--r--arch/arm/mach-ixp4xx/Makefile2
-rw-r--r--arch/arm/mach-ixp4xx/fsg-pci.c71
-rw-r--r--arch/arm/mach-ixp4xx/fsg-setup.c276
-rw-r--r--arch/arm/mach-omap1/Makefile4
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c17
-rw-r--r--arch/arm/mach-omap1/board-osk.c18
-rw-r--r--arch/arm/mach-omap1/fpga.c10
-rw-r--r--arch/arm/mach-omap1/mcbsp.c280
-rw-r--r--arch/arm/mach-omap1/pm.c7
-rw-r--r--arch/arm/mach-omap1/sram.S (renamed from arch/arm/plat-omap/sram-fn.S)6
-rw-r--r--arch/arm/mach-omap2/Makefile8
-rw-r--r--arch/arm/mach-omap2/clock.c201
-rw-r--r--arch/arm/mach-omap2/clock.h6
-rw-r--r--arch/arm/mach-omap2/clock24xx.c12
-rw-r--r--arch/arm/mach-omap2/clock24xx.h47
-rw-r--r--arch/arm/mach-omap2/clock34xx.c299
-rw-r--r--arch/arm/mach-omap2/clock34xx.h147
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h18
-rw-r--r--arch/arm/mach-omap2/cm.h15
-rw-r--r--arch/arm/mach-omap2/control.c24
-rw-r--r--arch/arm/mach-omap2/gpmc.c2
-rw-r--r--arch/arm/mach-omap2/id.c195
-rw-r--r--arch/arm/mach-omap2/mcbsp.c208
-rw-r--r--arch/arm/mach-omap2/memory.c11
-rw-r--r--arch/arm/mach-omap2/mux.c2
-rw-r--r--arch/arm/mach-omap2/pm.c7
-rw-r--r--arch/arm/mach-omap2/prcm-common.h1
-rw-r--r--arch/arm/mach-omap2/prcm.c98
-rw-r--r--arch/arm/mach-omap2/prm.h30
-rw-r--r--arch/arm/mach-omap2/sdrc.h10
-rw-r--r--arch/arm/mach-omap2/sram242x.S (renamed from arch/arm/mach-omap2/sram-fn.S)105
-rw-r--r--arch/arm/mach-omap2/sram243x.S321
-rw-r--r--arch/arm/mach-omap2/timer-gp.c9
-rw-r--r--arch/arm/mach-realview/platsmp.c2
-rw-r--r--arch/arm/mach-s3c2410/Kconfig21
-rw-r--r--arch/arm/mach-s3c2410/Makefile8
-rw-r--r--arch/arm/mach-s3c2410/bast-ide.c112
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c59
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c474
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c72
-rw-r--r--arch/arm/mach-s3c2410/nor-simtec.c86
-rw-r--r--arch/arm/mach-s3c2410/nor-simtec.h14
-rw-r--r--arch/arm/mach-s3c2412/Kconfig10
-rw-r--r--arch/arm/mach-s3c2412/Makefile1
-rw-r--r--arch/arm/mach-s3c2412/clock.c13
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c687
-rw-r--r--arch/arm/mach-s3c2440/Kconfig6
-rw-r--r--arch/arm/mach-s3c2440/Makefile1
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c41
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c198
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c15
-rw-r--r--arch/arm/mach-s3c2443/clock.c91
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/mm/fault-armv.c4
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/arm/plat-iop/gpio.c43
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/clock.c128
-rw-r--r--arch/arm/plat-omap/common.c59
-rw-r--r--arch/arm/plat-omap/devices.c48
-rw-r--r--arch/arm/plat-omap/dma.c766
-rw-r--r--arch/arm/plat-omap/dmtimer.c212
-rw-r--r--arch/arm/plat-omap/mcbsp.c767
-rw-r--r--arch/arm/plat-omap/sram.c211
-rw-r--r--arch/arm/plat-omap/usb.c131
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig8
-rw-r--r--arch/arm/plat-s3c24xx/Makefile3
-rw-r--r--arch/arm/plat-s3c24xx/devs.c100
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c259
-rw-r--r--arch/arm/plat-s3c24xx/pwm-clock.c437
-rw-r--r--arch/arm/plat-s3c24xx/pwm.c402
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c6
-rw-r--r--arch/blackfin/kernel/irqchip.c5
-rw-r--r--arch/ia64/kernel/setup.c3
-rw-r--r--arch/ia64/kernel/time.c1
-rw-r--r--arch/powerpc/boot/Makefile3
-rw-r--r--arch/powerpc/kernel/legacy_serial.c5
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c14
-rw-r--r--arch/sh/configs/landisk_defconfig1
-rw-r--r--arch/sh/configs/lboxre2_defconfig1
-rw-r--r--arch/sh/configs/se7705_defconfig1
-rw-r--r--arch/sh/configs/se7712_defconfig1
-rw-r--r--arch/sh/configs/se7750_defconfig1
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/kernel/i387.c4
-rw-r--r--arch/x86/kernel/smpboot.c1
-rw-r--r--arch/x86/mm/init_64.c8
-rw-r--r--block/as-iosched.c2
-rw-r--r--drivers/acorn/char/Makefile5
-rw-r--r--drivers/acorn/char/defkeymap-l7200.c386
-rw-r--r--drivers/acpi/bay.c3
-rw-r--r--drivers/acpi/dock.c3
-rw-r--r--drivers/acpi/glue.c3
-rw-r--r--drivers/char/drm/i915_irq.c4
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/connector/connector.c40
-rw-r--r--drivers/firewire/fw-sbp2.c3
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c28
-rw-r--r--drivers/i2c/chips/isp1301_omap.c163
-rw-r--r--drivers/ide/Kconfig7
-rw-r--r--drivers/ide/arm/Makefile1
-rw-r--r--drivers/ide/arm/bast-ide.c90
-rw-r--r--drivers/ide/ide-proc.c2
-rw-r--r--drivers/input/ff-core.c18
-rw-r--r--drivers/md/dm-crypt.c1
-rw-r--r--drivers/md/md.c6
-rw-r--r--drivers/md/raid10.c2
-rw-r--r--drivers/md/raid5.c7
-rw-r--r--drivers/media/common/ir-keymaps.c38
-rw-r--r--drivers/media/common/tuners/tda18271-common.c10
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c53
-rw-r--r--drivers/media/common/tuners/xc5000.c30
-rw-r--r--drivers/media/common/tuners/xc5000_priv.h1
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.c27
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/frontends/au8522.c29
-rw-r--r--drivers/media/dvb/frontends/stv0299.c15
-rw-r--r--drivers/media/dvb/frontends/tda10023.c20
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c29
-rw-r--r--drivers/media/dvb/ttpci/Kconfig1
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c5
-rw-r--r--drivers/media/video/Kconfig8
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c18
-rw-r--r--drivers/media/video/cx18/Kconfig4
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c73
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h16
-rw-r--r--drivers/media/video/cx18/cx18-cards.c84
-rw-r--r--drivers/media/video/cx18/cx18-cards.h50
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c17
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c26
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h1
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c18
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c4
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c10
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c24
-rw-r--r--drivers/media/video/pxa_camera.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c56
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c43
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c37
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c9
-rw-r--r--drivers/media/video/soc_camera.c16
-rw-r--r--drivers/media/video/uvc/Makefile3
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c1256
-rw-r--r--drivers/media/video/uvc/uvc_driver.c1955
-rw-r--r--drivers/media/video/uvc/uvc_isight.c134
-rw-r--r--drivers/media/video/uvc/uvc_queue.c477
-rw-r--r--drivers/media/video/uvc/uvc_status.c207
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c1105
-rw-r--r--drivers/media/video/uvc/uvc_video.c934
-rw-r--r--drivers/media/video/uvc/uvcvideo.h796
-rw-r--r--drivers/media/video/videodev.c245
-rw-r--r--drivers/media/video/vivi.c7
-rw-r--r--drivers/mmc/host/imxmmc.c4
-rw-r--r--drivers/mtd/maps/omap_nor.c23
-rw-r--r--drivers/net/3c59x.c5
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/arm/etherh.c2
-rw-r--r--drivers/net/e100.c2
-rw-r--r--drivers/net/e1000/e1000_ethtool.c2
-rw-r--r--drivers/net/e1000e/netdev.c3
-rw-r--r--drivers/net/hamradio/dmascc.c2
-rw-r--r--drivers/net/igb/igb_main.c3
-rw-r--r--drivers/net/ipg.c16
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c3
-rw-r--r--drivers/net/netxen/netxen_nic_main.c18
-rw-r--r--drivers/net/pcmcia/axnet_cs.c2
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c3
-rw-r--r--drivers/net/qla3xxx.c2
-rw-r--r--drivers/net/r6040.c2
-rw-r--r--drivers/net/s2io.c35
-rw-r--r--drivers/net/s2io.h4
-rw-r--r--drivers/net/tc35815.c4
-rw-r--r--drivers/net/wan/x25_asy.c3
-rw-r--r--drivers/net/wireless/b43/leds.c3
-rw-r--r--drivers/net/wireless/b43/main.c12
-rw-r--r--drivers/net/wireless/b43legacy/dma.c2
-rw-r--r--drivers/net/wireless/b43legacy/main.c6
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c10
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c39
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c36
-rw-r--r--drivers/pci/access.c14
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c17
-rw-r--r--drivers/pci/pci-sysfs.c4
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/quirks.c42
-rw-r--r--drivers/pcmcia/omap_cf.c25
-rw-r--r--drivers/rtc/Kconfig19
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-at91rm9200.c4
-rw-r--r--drivers/rtc/rtc-at91sam9.c1
-rw-r--r--drivers/rtc/rtc-omap.c1
-rw-r--r--drivers/rtc/rtc-pl030.c217
-rw-r--r--drivers/rtc/rtc-pl031.c36
-rw-r--r--drivers/rtc/rtc-s3c.c4
-rw-r--r--drivers/rtc/rtc-sa1100.c41
-rw-r--r--drivers/scsi/arm/Kconfig2
-rw-r--r--drivers/scsi/arm/acornscsi-io.S15
-rw-r--r--drivers/scsi/arm/acornscsi.c426
-rw-r--r--drivers/scsi/arm/acornscsi.h9
-rw-r--r--drivers/scsi/esp_scsi.c22
-rw-r--r--drivers/scsi/ses.c2
-rw-r--r--drivers/serial/Kconfig54
-rw-r--r--drivers/serial/Makefile4
-rw-r--r--drivers/serial/s3c2400.c106
-rw-r--r--drivers/serial/s3c2410.c1860
-rw-r--r--drivers/serial/s3c2412.c151
-rw-r--r--drivers/serial/s3c2440.c181
-rw-r--r--drivers/serial/samsung.c1317
-rw-r--r--drivers/serial/samsung.h102
-rw-r--r--drivers/spi/spi_imx.c16
-rw-r--r--drivers/thermal/Kconfig9
-rw-r--r--drivers/thermal/thermal_sys.c4
-rw-r--r--drivers/usb/gadget/Kconfig4
-rw-r--r--drivers/usb/gadget/at91_udc.c4
-rw-r--r--drivers/usb/gadget/omap_udc.c510
-rw-r--r--drivers/usb/gadget/omap_udc.h61
-rw-r--r--drivers/usb/host/ohci-omap.c5
-rw-r--r--drivers/video/pxafb.c52
-rw-r--r--fs/block_dev.c10
-rw-r--r--fs/buffer.c13
-rw-r--r--fs/dcache.c68
-rw-r--r--fs/locks.c6
-rw-r--r--fs/namei.c26
-rw-r--r--fs/pipe.c10
-rw-r--r--fs/udf/super.c57
-rw-r--r--fs/utimes.c59
-rw-r--r--include/asm-arm/arch-at91/at91_pmc.h7
-rw-r--r--include/asm-arm/arch-at91/at91cap9.h2
-rw-r--r--include/asm-arm/arch-at91/at91cap9_matrix.h5
-rw-r--r--include/asm-arm/arch-at91/at91sam9260.h11
-rw-r--r--include/asm-arm/arch-at91/at91sam9rl.h2
-rw-r--r--include/asm-arm/arch-at91/board.h6
-rw-r--r--include/asm-arm/arch-at91/cpu.h7
-rw-r--r--include/asm-arm/arch-at91/hardware.h2
-rw-r--r--include/asm-arm/arch-at91/timex.h22
-rw-r--r--include/asm-arm/arch-ebsa285/hardware.h26
-rw-r--r--include/asm-arm/arch-ebsa285/memory.h19
-rw-r--r--include/asm-arm/arch-ebsa285/vmalloc.h4
-rw-r--r--include/asm-arm/arch-imx/imx-dma.h2
-rw-r--r--include/asm-arm/arch-iop13xx/dma.h2
-rw-r--r--include/asm-arm/arch-iop32x/gpio.h6
-rw-r--r--include/asm-arm/arch-iop33x/gpio.h6
-rw-r--r--include/asm-arm/arch-ixp4xx/fsg.h50
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/irqs.h7
-rw-r--r--include/asm-arm/arch-msm/irqs.h1
-rw-r--r--include/asm-arm/arch-msm/timex.h1
-rw-r--r--include/asm-arm/arch-ns9xxx/hardware.h4
-rw-r--r--include/asm-arm/arch-omap/board-2430sdp.h5
-rw-r--r--include/asm-arm/arch-omap/board-h3.h6
-rw-r--r--include/asm-arm/arch-omap/board-innovator.h3
-rw-r--r--include/asm-arm/arch-omap/board-perseus2.h6
-rw-r--r--include/asm-arm/arch-omap/clock.h17
-rw-r--r--include/asm-arm/arch-omap/common.h15
-rw-r--r--include/asm-arm/arch-omap/control.h4
-rw-r--r--include/asm-arm/arch-omap/cpu.h39
-rw-r--r--include/asm-arm/arch-omap/dma.h378
-rw-r--r--include/asm-arm/arch-omap/dmtimer.h1
-rw-r--r--include/asm-arm/arch-omap/fpga.h49
-rw-r--r--include/asm-arm/arch-omap/hardware.h1
-rw-r--r--include/asm-arm/arch-omap/io.h26
-rw-r--r--include/asm-arm/arch-omap/irqs.h44
-rw-r--r--include/asm-arm/arch-omap/mcbsp.h62
-rw-r--r--include/asm-arm/arch-omap/omap34xx.h72
-rw-r--r--include/asm-arm/arch-omap/sram.h37
-rw-r--r--include/asm-arm/arch-omap/tc.h10
-rw-r--r--include/asm-arm/arch-omap/usb.h23
-rw-r--r--include/asm-arm/arch-rpc/io.h5
-rw-r--r--include/asm-arm/arch-s3c2410/gpio.h74
-rw-r--r--include/asm-arm/arch-s3c2410/regs-clock.h2
-rw-r--r--include/asm-arm/cacheflush.h7
-rw-r--r--include/asm-arm/dyntick.h6
-rw-r--r--include/asm-arm/ecard.h35
-rw-r--r--include/asm-arm/hardware/iop3xx-gpio.h73
-rw-r--r--include/asm-arm/hw_irq.h11
-rw-r--r--include/asm-arm/kexec.h2
-rw-r--r--include/asm-arm/mach/time.h22
-rw-r--r--include/asm-arm/mmu_context.h5
-rw-r--r--include/asm-arm/plat-s3c/regs-timer.h9
-rw-r--r--include/asm-arm/plat-s3c24xx/devs.h7
-rw-r--r--include/asm-arm/rtc.h43
-rw-r--r--include/asm-generic/Kbuild.asm2
-rw-r--r--include/asm-powerpc/Kbuild1
-rw-r--r--include/asm-x86/msr.h2
-rw-r--r--include/linux/Kbuild2
-rw-r--r--include/linux/audit.h2
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/linux/i2c.h2
-rw-r--r--include/linux/inet_lro.h6
-rw-r--r--include/linux/input.h2
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--include/linux/thermal.h6
-rw-r--r--include/media/cx25840.h6
-rw-r--r--include/media/ir-common.h1
-rw-r--r--include/media/v4l2-dev.h4
-rw-r--r--include/net/mac80211.h9
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--kernel/audit.c6
-rw-r--r--kernel/auditfilter.c3
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--kernel/rcuclassic.c16
-rw-r--r--kernel/sched.c4
-rw-r--r--kernel/sysctl.c12
-rw-r--r--kernel/timer.c10
-rw-r--r--lib/debugobjects.c15
-rw-r--r--lib/ts_bm.c2
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/fib_rules.c4
-rw-r--r--net/core/filter.c1
-rw-r--r--net/core/skbuff.c17
-rw-r--r--net/ipv4/inet_fragment.c16
-rw-r--r--net/ipv4/inet_lro.c3
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/tcp.c9
-rw-r--r--net/ipv4/tcp_ipv4.c6
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c3
-rw-r--r--net/ipv6/reassembly.c2
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/mac80211/key.c9
-rw-r--r--net/mac80211/wext.c7
-rw-r--r--net/mac80211/wme.c3
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c13
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/netlink/attr.c7
-rw-r--r--net/sched/Kconfig11
-rw-r--r--net/sched/sch_api.c6
-rw-r--r--net/sched/sch_atm.c7
-rw-r--r--net/sched/sch_cbq.c8
-rw-r--r--net/sched/sch_dsmark.c2
-rw-r--r--net/sched/sch_generic.c2
-rw-r--r--net/sched/sch_hfsc.c6
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_ingress.c2
-rw-r--r--net/sched/sch_prio.c2
-rw-r--r--net/sched/sch_sfq.c2
-rw-r--r--net/unix/af_unix.c52
-rw-r--r--net/wireless/reg.c18
-rw-r--r--sound/soc/at91/at91-ssc.c2
452 files changed, 25930 insertions, 7742 deletions
diff --git a/.gitignore b/.gitignore
index 9bb1cb6d825..869e1a3b64b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,10 @@
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
+# NOTE! Please use 'git-ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
# Normal rules
#
.*
@@ -18,19 +22,21 @@
*.lst
*.symtypes
*.order
+*.elf
+*.bin
+*.gz
#
# Top-level generic files
#
tags
TAGS
-vmlinux*
-!vmlinux.lds.S
-!vmlinux.lds.h
+vmlinux
System.map
Module.markers
Module.symvers
!.gitignore
+!.mailmap
#
# Generated include files
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5b3f31faed5..46ece3fba6f 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -312,3 +312,12 @@ When: 2.6.26
Why: Implementation became generic; users should now include
linux/semaphore.h instead.
Who: Matthew Wilcox <willy@linux.intel.com>
+
+---------------------------
+
+What: CONFIG_THERMAL_HWMON
+When: January 2009
+Why: This option was introduced just to allow older lm-sensors userspace
+ to keep working over the upgrade to 2.6.26. At the scheduled time of
+ removal fixed lm-sensors (2.x or 3.x) should be readily available.
+Who: Rene Herman <rene.herman@gmail.com>
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index ee75cbace28..d4cd4126d1a 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -25,12 +25,23 @@ routines, and should be zero-initialized except for fields with data you
provide. A client structure holds device-specific information like the
driver model device node, and its I2C address.
+/* iff driver uses driver model ("new style") binding model: */
+
+static struct i2c_device_id foo_idtable[] = {
+ { "foo", my_id_for_foo },
+ { "bar", my_id_for_bar },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, foo_idtable);
+
static struct i2c_driver foo_driver = {
.driver = {
.name = "foo",
},
/* iff driver uses driver model ("new style") binding model: */
+ .id_table = foo_ids,
.probe = foo_probe,
.remove = foo_remove,
@@ -173,10 +184,9 @@ handle may be used during foo_probe(). If foo_probe() reports success
(zero not a negative status code) it may save the handle and use it until
foo_remove() returns. That binding model is used by most Linux drivers.
-Drivers match devices when i2c_client.driver_name and the driver name are
-the same; this approach is used in several other busses that don't have
-device typing support in the hardware. The driver and module name should
-match, so hotplug/coldplug mechanisms will modprobe the driver.
+The probe function is called when an entry in the id_table name field
+matches the device's name. It is passed the entry that was matched so
+the driver knows which one in the table matched.
Device Creation (Standard driver model)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e07c432c731..f1e970acad4 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1208,6 +1208,11 @@ and is between 256 and 4096 characters. It is defined in the file
mtdparts= [MTD]
See drivers/mtd/cmdlinepart.c.
+ mtdset= [ARM]
+ ARM/S3C2412 JIVE boot control
+
+ See arch/arm/mach-s3c2412/mach-jive.c
+
mtouchusb.raw_coordinates=
[HW] Make the MicroTouch USB driver use raw coordinates
('y', default) or cooked coordinates ('n')
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 17a6e46fbd4..17f1f91af35 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -81,23 +81,23 @@ inet_peer_minttl - INTEGER
Minimum time-to-live of entries. Should be enough to cover fragment
time-to-live on the reassembling side. This minimum time-to-live is
guaranteed if the pool size is less than inet_peer_threshold.
- Measured in jiffies(1).
+ Measured in seconds.
inet_peer_maxttl - INTEGER
Maximum time-to-live of entries. Unused entries will expire after
this period of time if there is no memory pressure on the pool (i.e.
when the number of entries in the pool is very small).
- Measured in jiffies(1).
+ Measured in seconds.
inet_peer_gc_mintime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under high memory pressure on the pool.
- Measured in jiffies(1).
+ Measured in seconds.
inet_peer_gc_maxtime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under low (or absent) memory pressure on the pool.
- Measured in jiffies(1).
+ Measured in seconds.
TCP variables:
@@ -794,10 +794,6 @@ tag - INTEGER
Allows you to write a number, which can be used as required.
Default value is 0.
-(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
-Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
-value on your system.
-
Alexey Kuznetsov.
kuznet@ms2.inr.ac.ru
diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt
index 4bde53e85f3..1e28e2ddb90 100644
--- a/Documentation/networking/s2io.txt
+++ b/Documentation/networking/s2io.txt
@@ -83,9 +83,9 @@ Valid range: Limited by memory on system
Default: 30
e. intr_type
-Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X)
-Valid range: 1-3
-Default: 1
+Specifies interrupt type. Possible values 0(INTA), 2(MSI-X)
+Valid values: 0, 2
+Default: 2
5. Performance suggestions
General:
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828
index aaae360312e..86d1c8e7b18 100644
--- a/Documentation/video4linux/CARDLIST.au0828
+++ b/Documentation/video4linux/CARDLIST.au0828
@@ -1,4 +1,4 @@
0 -> Unknown board (au0828)
- 1 -> Hauppauge HVR950Q (au0828) [2040:7200]
+ 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f0ec46a709..e6c06fa3290 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4314,6 +4314,14 @@ L: netdev@vger.kernel.org
W: http://www.linux-usb.org/usbnet
S: Maintained
+USB VIDEO CLASS
+P: Laurent Pinchart
+M: laurent.pinchart@skynet.be
+L: linx-uvc-devel@berlios.de
+L: video4linux-list@redhat.com
+W: http://linux-uvc.berlios.de
+S: Maintained
+
USB W996[87]CF DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5bf60d5897d..b92925c7017 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -152,6 +152,10 @@ config FIQ
config ARCH_MTD_XIP
bool
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ bool
+ def_bool y
+
if OPROFILE
config OPROFILE_ARMV6
@@ -237,13 +241,6 @@ config ARCH_CLPS711X
help
Support for Cirrus Logic 711x/721x based boards.
-config ARCH_CO285
- bool "Co-EBSA285"
- select FOOTBRIDGE
- select FOOTBRIDGE_ADDIN
- help
- Support for Intel's EBSA285 companion chip.
-
config ARCH_EBSA110
bool "EBSA-110"
select ISA
@@ -304,6 +301,8 @@ config ARCH_IOP32X
depends on MMU
select PLAT_IOP
select PCI
+ select GENERIC_GPIO
+ select HAVE_GPIO_LIB
help
Support for Intel's 80219 and IOP32X (XScale) family of
processors.
@@ -313,6 +312,8 @@ config ARCH_IOP33X
depends on MMU
select PLAT_IOP
select PCI
+ select GENERIC_GPIO
+ select HAVE_GPIO_LIB
help
Support for Intel's IOP33X (XScale) family of processors.
@@ -440,6 +441,7 @@ config ARCH_RPC
select FIQ
select TIMER_ACORN
select ARCH_MAY_HAVE_PC_FDC
+ select HAVE_PATA_PLATFORM
select ISA_DMA_API
select NO_IOPORT
help
@@ -743,27 +745,6 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure.
-config NO_IDLE_HZ
- bool "Dynamic tick timer"
- depends on !GENERIC_CLOCKEVENTS
- help
- Select this option if you want to disable continuous timer ticks
- and have them programmed to occur as required. This option saves
- power as the system can remain in idle state for longer.
-
- By default dynamic tick is disabled during the boot, and can be
- manually enabled with:
-
- echo 1 > /sys/devices/system/timer/timer0/dyn_tick
-
- Alternatively, if you want dynamic tick automatically enabled
- during boot, pass "dyntick=enable" via the kernel command string.
-
- Please note that dynamic tick may affect the accuracy of
- timekeeping on some platforms depending on the implementation.
- Currently at least OMAP, PXA2xx and SA11x0 platforms are known
- to have accurate timekeeping with dynamic tick.
-
config HZ
int
default 128 if ARCH_L7200
@@ -829,7 +810,7 @@ source "mm/Kconfig"
config LEDS
bool "Timer and CPU usage LEDs"
- depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
+ depends on ARCH_CDB89712 || ARCH_EBSA110 || \
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index b53237bb6f1..91fac81833e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -100,8 +100,6 @@ textofs-y := 0x00008000
incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
machine-$(CONFIG_FOOTBRIDGE) := footbridge
incdir-$(CONFIG_FOOTBRIDGE) := ebsa285
- machine-$(CONFIG_ARCH_CO285) := footbridge
- incdir-$(CONFIG_ARCH_CO285) := ebsa285
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SA1100) := sa1100
ifeq ($(CONFIG_ARCH_SA1100),y)
@@ -193,8 +191,6 @@ core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
-drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
-drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
libs-y := arch/arm/lib/ $(libs-y)
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 3d0b9fa42f8..325e4b6a6af 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -2,7 +2,6 @@
# Makefile for the linux kernel.
#
-obj-y += rtctime.o
obj-$(CONFIG_ARM_GIC) += gic.o
obj-$(CONFIG_ARM_VIC) += vic.o
obj-$(CONFIG_ICST525) += icst525.o
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 52fc6a88328..2744673314b 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -650,7 +650,8 @@ EXPORT_SYMBOL(dma_map_sg);
EXPORT_SYMBOL(dma_unmap_sg);
EXPORT_SYMBOL(dma_sync_single_for_cpu);
EXPORT_SYMBOL(dma_sync_single_for_device);
-EXPORT_SYMBOL(dma_sync_sg);
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+EXPORT_SYMBOL(dma_sync_sg_for_device);
EXPORT_SYMBOL(dmabounce_register_dev);
EXPORT_SYMBOL(dmabounce_unregister_dev);
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
deleted file mode 100644
index aa8f7739c82..00000000000
--- a/arch/arm/common/rtctime.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * linux/arch/arm/common/rtctime.c
- *
- * Copyright (C) 2003 Deep Blue Solutions Ltd.
- * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
- * Based on rtc.c by Paul Gortmaker
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/rtc.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/capability.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-
-#include <asm/rtc.h>
-
-static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
-static struct fasync_struct *rtc_async_queue;
-
-/*
- * rtc_lock protects rtc_irq_data
- */
-static DEFINE_SPINLOCK(rtc_lock);
-static unsigned long rtc_irq_data;
-
-/*
- * rtc_sem protects rtc_inuse and rtc_ops
- */
-static DEFINE_MUTEX(rtc_mutex);
-static unsigned long rtc_inuse;
-static struct rtc_ops *rtc_ops;
-
-#define rtc_epoch 1900UL
-
-/*
- * Calculate the next alarm time given the requested alarm time mask
- * and the current time.
- */
-void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
-{
- unsigned long next_time;
- unsigned long now_time;
-
- next->tm_year = now->tm_year;
- next->tm_mon = now->tm_mon;
- next->tm_mday = now->tm_mday;
- next->tm_hour = alrm->tm_hour;
- next->tm_min = alrm->tm_min;
- next->tm_sec = alrm->tm_sec;
-
- rtc_tm_to_time(now, &now_time);
- rtc_tm_to_time(next, &next_time);
-
- if (next_time < now_time) {
- /* Advance one day */
- next_time += 60 * 60 * 24;
- rtc_time_to_tm(next_time, next);
- }
-}
-EXPORT_SYMBOL(rtc_next_alarm_time);
-
-static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
-{
- memset(tm, 0, sizeof(struct rtc_time));
- return ops->read_time(tm);
-}
-
-static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm)
-{
- int ret;
-
- ret = rtc_valid_tm(tm);
- if (ret == 0)
- ret = ops->set_time(tm);
-
- return ret;
-}
-
-static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
-{
- int ret = -EINVAL;
- if (ops->read_alarm) {
- memset(alrm, 0, sizeof(struct rtc_wkalrm));
- ret = ops->read_alarm(alrm);
- }
- return ret;
-}
-
-static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
-{
- int ret = -EINVAL;
- if (ops->set_alarm)
- ret = ops->set_alarm(alrm);
- return ret;
-}
-
-void rtc_update(unsigned long num, unsigned long events)
-{
- spin_lock(&rtc_lock);
- rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
- spin_unlock(&rtc_lock);
-
- wake_up_interruptible(&rtc_wait);
- kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
-}
-EXPORT_SYMBOL(rtc_update);
-
-
-static ssize_t
-rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long data;
- ssize_t ret;
-
- if (count < sizeof(unsigned long))
- return -EINVAL;
-
- add_wait_queue(&rtc_wait, &wait);
- do {
- __set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irq(&rtc_lock);
- data = rtc_irq_data;
- rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
-
- if (data != 0) {
- ret = 0;
- break;
- }
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- schedule();
- } while (1);
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&rtc_wait, &wait);
-
- if (ret == 0) {
- ret = put_user(data, (unsigned long __user *)buf);
- if (ret == 0)
- ret = sizeof(unsigned long);
- }
- return ret;
-}
-
-static unsigned int rtc_poll(struct file *file, poll_table *wait)
-{
- unsigned long data;
-
- poll_wait(file, &rtc_wait, wait);
-
- spin_lock_irq(&rtc_lock);
- data = rtc_irq_data;
- spin_unlock_irq(&rtc_lock);
-
- return data != 0 ? POLLIN | POLLRDNORM : 0;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct rtc_ops *ops = file->private_data;
- struct rtc_time tm;
- struct rtc_wkalrm alrm;
- void __user *uarg = (void __user *)arg;
- int ret = -EINVAL;
-
- switch (cmd) {
- case RTC_ALM_READ:
- ret = rtc_arm_read_alarm(ops, &alrm);
- if (ret)
- break;
- ret = copy_to_user(uarg, &alrm.time, sizeof(tm));
- if (ret)
- ret = -EFAULT;
- break;
-
- case RTC_ALM_SET:
- ret = copy_from_user(&alrm.time, uarg, sizeof(tm));
- if (ret) {
- ret = -EFAULT;
- break;
- }
- alrm.enabled = 0;
- alrm.pending = 0;
- alrm.time.tm_mday = -1;
- alrm.time.tm_mon = -1;
- alrm.time.tm_year = -1;
- alrm.time.tm_wday = -1;
- alrm.time.tm_yday = -1;
- alrm.time.tm_isdst = -1;
- ret = rtc_arm_set_alarm(ops, &alrm);
- break;
-
- case RTC_RD_TIME:
- ret = rtc_arm_read_time(ops, &tm);
- if (ret)
- break;
- ret = copy_to_user(uarg, &tm, sizeof(tm));
- if (ret)
- ret = -EFAULT;
- break;
-
- case RTC_SET_TIME:
- if (!capable(CAP_SYS_TIME)) {
- ret = -EACCES;
- break;
- }
- ret = copy_from_user(&tm, uarg, sizeof(tm));
- if (ret) {
- ret = -EFAULT;
- break;
- }
- ret = rtc_arm_set_time(ops, &tm);
- break;
-
- case RTC_EPOCH_SET:
-#ifndef rtc_epoch
- /*
- * There were no RTC clocks before 1900.
- */
- if (arg < 1900) {
- ret = -EINVAL;
- break;
- }
- if (!capable(CAP_SYS_TIME)) {
- ret = -EACCES;
- break;
- }
- rtc_epoch = arg;
- ret = 0;
-#endif
- break;
-
- case RTC_EPOCH_READ:
- ret = put_user(rtc_epoch, (unsigned long __user *)uarg);
- break;
-
- case RTC_WKALM_SET:
- ret = copy_from_user(&alrm, uarg, sizeof(alrm));
- if (ret) {
- ret = -EFAULT;
- break;
- }
- ret = rtc_arm_set_alarm(ops, &alrm);
- break;
-
- case RTC_WKALM_RD:
- ret = rtc_arm_read_alarm(ops, &alrm);
- if (ret)
- break;
- ret = copy_to_user(uarg, &alrm, sizeof(alrm));
- if (ret)
- ret = -EFAULT;
- break;
-
- default:
- if (ops->ioctl)
- ret = ops->ioctl(cmd, arg);
- break;
- }
- return ret;
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
- int ret;
-
- mutex_lock(&rtc_mutex);
-
- if (rtc_inuse) {
- ret = -EBUSY;
- } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
- ret = -ENODEV;
- } else {
- file->private_data = rtc_ops;
-
- ret = rtc_ops->open ? rtc_ops->open() : 0;
- if (ret == 0) {
- spin_lock_irq(&rtc_lock);
- rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
-
- rtc_inuse = 1;
- }
- }
- mutex_unlock(&rtc_mutex);
-
- return ret;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
- struct rtc_ops *ops = file->private_data;
-
- if (ops->release)
- ops->release();
-
- spin_lock_irq(&rtc_lock);
- rtc_irq_data = 0;
- spin_unlock_irq(&rtc_lock);
-
- module_put(rtc_ops->owner);
- rtc_inuse = 0;
-
- return 0;
-}
-
-static int rtc_fasync(int fd, struct file *file, int on)
-{
- return fasync_helper(fd, file, on, &rtc_async_queue);
-}
-
-static const struct file_operations rtc_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = rtc_read,
- .poll = rtc_poll,
- .ioctl = rtc_ioctl,
- .open = rtc_open,
- .release = rtc_release,
- .fasync = rtc_fasync,
-};
-
-static struct miscdevice rtc_miscdev = {
- .minor = RTC_MINOR,
- .name = "rtc",
- .fops = &rtc_fops,
-};
-
-
-static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- struct rtc_ops *ops = data;
- struct rtc_wkalrm alrm;
- struct rtc_time tm;
- char *p = page;
-
- if (rtc_arm_read_time(ops, &tm) == 0) {
- p += sprintf(p,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n"
- "rtc_epoch\t: %04lu\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- rtc_epoch);
- }
-
- if (rtc_arm_read_alarm(ops, &alrm) == 0) {
- p += sprintf(p, "alrm_time\t: ");
- if ((unsigned int)alrm.time.tm_hour <= 24)
- p += sprintf(p, "%02d:", alrm.time.tm_hour);
- else
- p += sprintf(p, "**:");
- if ((unsigned int)alrm.time.tm_min <= 59)
- p += sprintf(p, "%02d:", alrm.time.tm_min);
- else
- p += sprintf(p, "**:");
- if ((unsigned int)alrm.time.tm_sec <= 59)
- p += sprintf(p, "%02d\n", alrm.time.tm_sec);
- else
- p += sprintf(p, "**\n");
-
- p += sprintf(p, "alrm_date\t: ");
- if ((unsigned int)alrm.time.tm_year <= 200)
- p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
- else
- p += sprintf(p, "****-");
- if ((unsigned int)alrm.time.tm_mon <= 11)
- p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
- else
- p += sprintf(p, "**-");
- if ((unsigned int)alrm.time.tm_mday <= 31)
- p += sprintf(p, "%02d\n", alrm.time.tm_mday);
- else
- p += sprintf(p, "**\n");
- p += sprintf(p, "alrm_wakeup\t: %s\n",
- alrm.enabled ? "yes" : "no");
- p += sprintf(p, "alrm_pending\t: %s\n",
- alrm.pending ? "yes" : "no");
- }
-
- if (ops->proc)
- p += ops->proc(p);
-
- return p - page;
-}
-
-int register_rtc(struct rtc_ops *ops)
-{
- int ret = -EBUSY;
-
- mutex_lock(&rtc_mutex);
- if (rtc_ops == NULL) {
- rtc_ops = ops;
-
- ret = misc_register(&rtc_miscdev);
- if (ret == 0)
- create_proc_read_entry("driver/rtc", 0, NULL,
- rtc_read_proc, ops);
- }
- mutex_unlock(&rtc_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(register_rtc);
-
-void unregister_rtc(struct rtc_ops *rtc)
-{
- mutex_lock(&rtc_mutex);
- if (rtc == rtc_ops) {
- remove_proc_entry("driver/rtc", NULL);
- misc_deregister(&rtc_miscdev);
- rtc_ops = NULL;
- }
- mutex_unlock(&rtc_mutex);
-}
-EXPORT_SYMBOL(unregister_rtc);
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig
index e32e7364812..be2b2f38fd9 100644
--- a/arch/arm/configs/at91cap9adk_defconfig
+++ b/arch/arm/configs/at91cap9adk_defconfig
@@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
@@ -907,7 +906,32 @@ CONFIG_USB_MON=y
#
# USB Gadget Support
#
-# CONFIG_USB_GADGET is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -926,7 +950,59 @@ CONFIG_MMC_AT91=y
# CONFIG_MMC_SPI is not set
# CONFIG_NEW_LEDS is not set
CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_DRV_AT91SAM9_RTT=0
+CONFIG_RTC_DRV_AT91SAM9_GPBR=0
#
# File systems
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
index 2dbbbc3d4ac..868fb7b9530 100644
--- a/arch/arm/configs/at91rm9200dk_defconfig
+++ b/arch/arm/configs/at91rm9200dk_defconfig
@@ -169,7 +169,6 @@ CONFIG_AT91_CF=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index 6e994f7820c..de43fc67561 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -160,7 +160,6 @@ CONFIG_ISA_DMA_API=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig
index f659c938473..2011adfa675 100644
--- a/arch/arm/configs/at91sam9260ek_defconfig
+++ b/arch/arm/configs/at91sam9260ek_defconfig
@@ -220,7 +220,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig
index 3802e85f748..4049768962d 100644
--- a/arch/arm/configs/at91sam9261ek_defconfig
+++ b/arch/arm/configs/at91sam9261ek_defconfig
@@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig
index 32a0d74e0c8..fa1c5aecb5a 100644
--- a/arch/arm/configs/at91sam9263ek_defconfig
+++ b/arch/arm/configs/at91sam9263ek_defconfig
@@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig
new file mode 100644
index 00000000000..c0686384736
--- /dev/null
+++ b/arch/arm/configs/at91sam9g20ek_defconfig
@@ -0,0 +1,1168 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Tue Jun 10 15:51:52 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+CONFIG_ARCH_AT91SAM9G20=y
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9G20 Board Type
+#
+CONFIG_MACH_AT91SAM9G20EK=y
+
+#
+# AT91 Board Options
+#
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_AT91_SLOW_CLOCK is not set
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+CONFIG_MTD_NAND_AT91_ECC_SOFT=y
+# CONFIG_MTD_NAND_AT91_ECC_HW is not set
+# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_AT91_AC97 is not set
+
+#
+# SPI devices
+#
+CONFIG_SND_AT73C213=y
+CONFIG_SND_AT73C213_TARGET_BITRATE=48000
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ETH is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_AT91=y
+# CONFIG_MMC_SPI is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=y
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_DRV_AT91SAM9_RTT=0
+CONFIG_RTC_DRV_AT91SAM9_GPBR=0
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig
index 98e6746d02b..d8ec5f9ca6e 100644
--- a/arch/arm/configs/at91sam9rlek_defconfig
+++ b/arch/arm/configs/at91sam9rlek_defconfig
@@ -211,7 +211,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
index d846a492e5c..85c80f723d8 100644
--- a/arch/arm/configs/ateb9200_defconfig
+++ b/arch/arm/configs/ateb9200_defconfig
@@ -171,7 +171,6 @@ CONFIG_AT91_CF=m
# Kernel Features
#
CONFIG_PREEMPT=y
-CONFIG_NO_IDLE_HZ=y
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig
index 5cab08397ae..33b201c3b30 100644
--- a/arch/arm/configs/cm_x270_defconfig
+++ b/arch/arm/configs/cm_x270_defconfig
@@ -194,7 +194,6 @@ CONFIG_PCI_HOST_ITE8152=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 4264e273202..f7622e65816 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -166,7 +166,6 @@ CONFIG_PCMCIA_SA1100=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index e8980a9bb89..9b8748a8d9d 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -165,7 +165,6 @@ CONFIG_PCMCIA_PXA2XX=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig
index 90ed214e367..cfeb817ad21 100644
--- a/arch/arm/configs/ecbat91_defconfig
+++ b/arch/arm/configs/ecbat91_defconfig
@@ -230,7 +230,6 @@ CONFIG_AT91_CF=y
#
# CONFIG_TICK_ONESHOT is not set
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
index 6bea0901bdf..d3114c23603 100644
--- a/arch/arm/configs/em_x270_defconfig
+++ b/arch/arm/configs/em_x270_defconfig
@@ -197,7 +197,6 @@ CONFIG_XSCALE_PMU=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index 24a701ab33e..21aa013793c 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -184,7 +184,6 @@ CONFIG_ARM_AMBA=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig
index ed487b90dbe..493ecee24f9 100644
--- a/arch/arm/configs/eseries_pxa_defconfig
+++ b/arch/arm/configs/eseries_pxa_defconfig
@@ -251,7 +251,6 @@ CONFIG_PCMCIA_PXA2XX=m
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index 988b4d13e76..482e5706105 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 83f40d4041a..8612f58e105 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -201,7 +201,6 @@ CONFIG_PCI_LEGACY=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index 917afb5ccfa..8b0098d19d0 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig
index f8f9793b526..84680db6c61 100644
--- a/arch/arm/configs/ixp2000_defconfig
+++ b/arch/arm/configs/ixp2000_defconfig
@@ -184,7 +184,6 @@ CONFIG_PCI=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig
index 27cf022dd80..4a2f7b2372d 100644
--- a/arch/arm/configs/ixp23xx_defconfig
+++ b/arch/arm/configs/ixp23xx_defconfig
@@ -180,7 +180,6 @@ CONFIG_PCI=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index efa0485d2f7..fc14932e3ab 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -165,6 +165,7 @@ CONFIG_ARCH_PRPMC1100=y
CONFIG_MACH_NAS100D=y
CONFIG_MACH_DSMG600=y
CONFIG_ARCH_IXDP4XX=y
+CONFIG_MACH_FSG=y
CONFIG_CPU_IXP46X=y
CONFIG_CPU_IXP43X=y
CONFIG_MACH_GTWX5715=y
@@ -770,7 +771,7 @@ CONFIG_ATA=y
# CONFIG_SATA_SIL24 is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
+CONFIG_SATA_VIA=y
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
@@ -1143,7 +1144,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83781D is not set
+CONFIG_SENSORS_W83781D=y
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
@@ -1334,8 +1335,8 @@ CONFIG_LEDS_CLASS=y
#
# LED drivers
#
-# CONFIG_LEDS_IXP4XX is not set
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_FSG=y
#
# LED Triggers
@@ -1367,7 +1368,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
+CONFIG_RTC_DRV_ISL1208=y
CONFIG_RTC_DRV_X1205=y
CONFIG_RTC_DRV_PCF8563=y
# CONFIG_RTC_DRV_PCF8583 is not set
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
index ae51a40db6f..6dd95a2c8d5 100644
--- a/arch/arm/configs/kafa_defconfig
+++ b/arch/arm/configs/kafa_defconfig
@@ -162,7 +162,6 @@ CONFIG_CPU_TLB_V4WBI=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
index c16537d9d67..8e74c66f239 100644
--- a/arch/arm/configs/kb9202_defconfig
+++ b/arch/arm/configs/kb9202_defconfig
@@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y
#
# Kernel Features
#
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig
index 8ab21a0719e..6077f2cb88e 100644
--- a/arch/arm/configs/ks8695_defconfig
+++ b/arch/arm/configs/ks8695_defconfig
@@ -174,7 +174,6 @@ CONFIG_PCCARD_NONSTATIC=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
index a3bf5833b87..1a38d8e3fe6 100644
--- a/arch/arm/configs/lpd270_defconfig
+++ b/arch/arm/configs/lpd270_defconfig
@@ -173,7 +173,6 @@ CONFIG_XSCALE_PMU=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
index 46a0f7fe1fa..7a2e932da1c 100644
--- a/arch/arm/configs/lpd7a404_defconfig
+++ b/arch/arm/configs/lpd7a404_defconfig
@@ -148,7 +148,6 @@ CONFIG_ARM_AMBA=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_AEABI is not set
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig
index 57f32f39d0f..0884f2370c3 100644
--- a/arch/arm/configs/netx_defconfig
+++ b/arch/arm/configs/netx_defconfig
@@ -154,7 +154,6 @@ CONFIG_ARM_AMBA=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig
index 650a248613e..418ca2febbe 100644
--- a/arch/arm/configs/onearm_defconfig
+++ b/arch/arm/configs/onearm_defconfig
@@ -202,7 +202,6 @@ CONFIG_AT91_CF=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig
index 95a22f51280..14826f0dabd 100644
--- a/arch/arm/configs/picotux200_defconfig
+++ b/arch/arm/configs/picotux200_defconfig
@@ -201,7 +201,6 @@ CONFIG_ARM_THUMB=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-CONFIG_NO_IDLE_HZ=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig
index b5e11aa2e29..811b8f60d19 100644
--- a/arch/arm/configs/pnx4008_defconfig
+++ b/arch/arm/configs/pnx4008_defconfig
@@ -151,7 +151,6 @@ CONFIG_ARM_THUMB=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/qil-a9260_defconfig b/arch/arm/configs/qil-a9260_defconfig
new file mode 100644
index 00000000000..ef903bed061
--- /dev/null
+++ b/arch/arm/configs/qil-a9260_defconfig
@@ -0,0 +1,1256 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Tue Apr 15 12:28:38 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_AT91SAM9260=y
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9260 Variants
+#
+# CONFIG_ARCH_AT91SAM9260_SAM9XE is not set
+
+#
+# AT91SAM9260 / AT91SAM9XE Board Type
+#
+# CONFIG_MACH_AT91SAM9260EK is not set
+# CONFIG_MACH_CAM60 is not set
+# CONFIG_MACH_SAM9_L9260 is not set
+# CONFIG_MACH_USB_A9260 is not set
+CONFIG_MACH_QIL_A9260=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_TIMER_HZ=100
+# CONFIG_AT91_EARLY_DBGU is not set
+CONFIG_AT91_EARLY_USART0=y
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS1,115200"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+CONFIG_MTD_NAND_AT91_ECC_SOFT=y
+# CONFIG_MTD_NAND_AT91_ECC_HW is not set
+# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_AT91SAM9_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_AT91=y
+# CONFIG_MMC_SPI is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+CONFIG_RTC_DRV_M41T94=y
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT91SAM9 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index fc39ba1a89f..0c09b23167e 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -177,7 +177,6 @@ CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
CONFIG_LOCAL_TIMERS=y
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index accbf529ce5..907e54344da 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y
#
# Kernel Features
#
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 5ddecb9ddf0..f62d1817d2c 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -190,7 +190,6 @@ CONFIG_ISA_DMA_API=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index f8a1645b3d4..35faaea8623 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,15 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc6
-# Mon Apr 9 10:12:58 2007
+# Linux kernel version: 2.6.26-rc8
+# Mon Jul 7 16:59:23 2008
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
CONFIG_NO_IOPORT=y
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -18,34 +21,39 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_ZONE_DMA=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -53,6 +61,7 @@ CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -60,34 +69,43 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -101,6 +119,7 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
#
# System Type
@@ -119,14 +138,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
@@ -134,18 +156,32 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_ARCH_S3C2410=y
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
CONFIG_PLAT_S3C24XX=y
CONFIG_CPU_S3C244X=y
+# CONFIG_S3C24XX_PWM is not set
CONFIG_PM_SIMTEC=y
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_MACH_SMDK=y
+CONFIG_PLAT_S3C=y
+CONFIG_CPU_LLSERIAL_S3C2410=y
+CONFIG_CPU_LLSERIAL_S3C2440=y
+
+#
+# Boot options
+#
# CONFIG_S3C_BOOT_WATCHDOG is not set
# CONFIG_S3C_BOOT_ERROR_RESET is not set
+
+#
+# Power management
+#
# CONFIG_S3C2410_PM_DEBUG is not set
# CONFIG_S3C2410_PM_CHECK is not set
CONFIG_S3C_LOWLEVEL_UART_PORT=0
-CONFIG_S3C2410_DMA=y
-# CONFIG_S3C2410_DMA_DEBUG is not set
-CONFIG_MACH_SMDK=y
#
# S3C2400 Machines
@@ -155,6 +191,8 @@ CONFIG_CPU_S3C2410_DMA=y
CONFIG_S3C2410_PM=y
CONFIG_S3C2410_GPIO=y
CONFIG_S3C2410_CLOCK=y
+CONFIG_SIMTEC_NOR=y
+CONFIG_MACH_BAST_IDE=y
#
# S3C2410 Machines
@@ -167,6 +205,7 @@ CONFIG_ARCH_BAST=y
CONFIG_MACH_OTOM=y
CONFIG_MACH_AML_M5900=y
CONFIG_BAST_PC104_IRQ=y
+# CONFIG_MACH_TCT_HAMMER is not set
CONFIG_MACH_VR1000=y
CONFIG_MACH_QT2410=y
CONFIG_CPU_S3C2412=y
@@ -176,8 +215,10 @@ CONFIG_S3C2412_PM=y
#
# S3C2412 Machines
#
+# CONFIG_MACH_JIVE is not set
CONFIG_MACH_SMDK2413=y
CONFIG_MACH_S3C2413=y
+# CONFIG_MACH_SMDK2412 is not set
CONFIG_MACH_VSTMS=y
CONFIG_CPU_S3C2440=y
CONFIG_S3C2440_DMA=y
@@ -191,6 +232,7 @@ CONFIG_MACH_RX3715=y
CONFIG_ARCH_S3C2440=y
CONFIG_MACH_NEXCODER_2440=y
CONFIG_SMDK2440_CPU2440=y
+# CONFIG_MACH_AT2440EVB is not set
CONFIG_CPU_S3C2442=y
#
@@ -215,6 +257,7 @@ CONFIG_CPU_32v4T=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV4T=y
CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_V4WT=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
@@ -236,17 +279,15 @@ CONFIG_CPU_CP15_MMU=y
# Bus support
#
CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
#
# Kernel Features
#
+# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=200
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -257,9 +298,13 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -279,7 +324,7 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0"
# At least one emulation must be selected
#
CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
+CONFIG_FPE_NWFPE_XP=y
# CONFIG_FPE_FASTFPE is not set
# CONFIG_VFP is not set
@@ -295,10 +340,12 @@ CONFIG_BINFMT_AOUT=y
# Power management options
#
CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-# CONFIG_APM_EMULATION is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=m
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
#
# Networking
@@ -308,59 +355,67 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+# CONFIG_IPV6_ROUTE_INFO is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -373,20 +428,71 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
+CONFIG_NET_SCH_FIFO=y
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
# CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=m
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
+
+#
+# Selecting 'y' for an algorithm will
+#
+
+#
+# build the algorithm into mac80211.
+#
+CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
+# CONFIG_MAC80211_DEBUG is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -395,21 +501,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -420,6 +519,7 @@ CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
@@ -432,6 +532,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -457,7 +558,6 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
CONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
@@ -486,13 +586,10 @@ CONFIG_MTD_BAST_MAXSIZE=4
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y
CONFIG_MTD_NAND_S3C2410=y
# CONFIG_MTD_NAND_S3C2410_DEBUG is not set
@@ -500,30 +597,25 @@ CONFIG_MTD_NAND_S3C2410=y
# CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# OneNAND Flash Device Drivers
-#
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
CONFIG_PARPORT=y
-# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_AX88796=m
CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
+CONFIG_PARPORT_NOT_PC=y
# CONFIG_PNP is not set
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
+# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -532,34 +624,34 @@ CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
CONFIG_BLK_DEV_IDETAPE=m
CONFIG_BLK_DEV_IDEFLOPPY=m
+# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDE_BAST=y
-# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_BLK_DEV_HD is not set
@@ -567,101 +659,119 @@ CONFIG_BLK_DEV_IDE_BAST=y
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_DEBUG is not set
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+CONFIG_HAVE_PATA_PLATFORM=y
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_AX88796 is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_SMC91X is not set
CONFIG_DM9000=y
+# CONFIG_ENC28J60 is not set
+CONFIG_DM9000_DEBUGLEVEL=4
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
+CONFIG_NETDEV_1000=y
+# CONFIG_E1000E_ENABLED is not set
+CONFIG_NETDEV_10000=y
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
#
-# Wan interfaces
+# USB Network Adapters
#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
#
@@ -669,6 +779,7 @@ CONFIG_DM9000=y
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -678,7 +789,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
@@ -695,12 +805,21 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_GPIO is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -721,6 +840,7 @@ CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
@@ -728,8 +848,6 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_MOXA_SMARTIO_NEW is not set
-# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_RISCOM8 is not set
# CONFIG_SPECIALIX is not set
@@ -758,8 +876,12 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
# Non-8250 serial port support
#
+CONFIG_SERIAL_SAMSUNG=y
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_S3C2410=y
-CONFIG_SERIAL_S3C2410_CONSOLE=y
+CONFIG_SERIAL_S3C2412=y
+CONFIG_SERIAL_S3C2440=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
@@ -768,89 +890,50 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_PRINTER=y
# CONFIG_LP_CONSOLE is not set
CONFIG_PPDEV=y
-# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_S3C2410_WATCHDOG=y
-
-#
-# ISA-based Watchdog Cards
-#
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_WDT is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGOBIT=y
#
# I2C Hardware Bus support
#
# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SIMTEC=y
+# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
#
# Miscellaneous I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
CONFIG_SENSORS_EEPROM=m
# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
@@ -860,6 +943,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BITBANG=m
# CONFIG_SPI_BUTTERFLY is not set
+# CONFIG_SPI_LM70_LLP is not set
CONFIG_SPI_S3C24XX=m
CONFIG_SPI_S3C24XX_GPIO=m
@@ -867,30 +951,43 @@ CONFIG_SPI_S3C24XX_GPIO=m
# SPI Protocol Masters
#
# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_HAVE_GPIO_LIB=y
#
-# Dallas's 1-wire bus
+# GPIO Support
#
-# CONFIG_W1 is not set
+# CONFIG_DEBUG_GPIO is not set
#
-# Hardware Monitoring support
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=m
-# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -905,72 +1002,95 @@ CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
#
-# Misc devices
+# Watchdog Device Drivers
#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_S3C2410_WATCHDOG=y
#
-# Multifunction device drivers
+# ISA-based Watchdog Cards
#
-# CONFIG_MFD_SM501 is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
#
-# LED devices
+# USB-based Watchdog Cards
#
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=m
+# CONFIG_USBPCWATCHDOG is not set
#
-# LED drivers
+# Sonics Silicon Backplane
#
-CONFIG_LEDS_S3C24XX=m
-CONFIG_LEDS_H1940=m
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# LED Triggers
+# Multifunction device drivers
#
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=m
-# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_MFD_SM501=y
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
#
# Multimedia devices
#
+
+#
+# Multimedia core support
+#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
#
-# Digital Video Broadcasting Devices
+# Multimedia drivers
#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# 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
@@ -978,12 +1098,19 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
#
-# Frambuffer hardware drivers
+# Frame buffer hardware drivers
#
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_S3C2410=y
# CONFIG_FB_S3C2410_DEBUG is not set
+CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
@@ -992,40 +1119,45 @@ CONFIG_FB_S3C2410=y
# CONFIG_MDA_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
-
-#
-# Logo configuration
-#
# CONFIG_LOGO is not set
#
# Sound
#
# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
#
-# HID Devices
+# USB Input Devices
#
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
+# CONFIG_USB_HID is not set
#
-# USB support
+# USB HID Boot Protocol drivers
#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
@@ -1033,18 +1165,22 @@ CONFIG_USB_DEVICEFS=y
#
# USB Host Controller Drivers
#
+# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1053,57 +1189,78 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# may also be needed; see USB_STORAGE Help for more information
#
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
+# CONFIG_USB_MICROTEK is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+CONFIG_USB_SERIAL_FTDI_SIO=y
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=y
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+CONFIG_USB_SERIAL_OPTION=m
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
#
# USB Miscellaneous drivers
@@ -1116,35 +1273,38 @@ CONFIG_USB_MON=y
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
+CONFIG_USB_LED=m
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_LD is not set
+CONFIG_USB_LD=m
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
#
-# MMC/SD Card support
+# LED drivers
#
-# CONFIG_MMC is not set
+CONFIG_LEDS_S3C24XX=m
+CONFIG_LEDS_H1940=m
+# CONFIG_LEDS_GPIO is not set
#
-# Real Time Clock
+# LED Triggers
#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1158,61 +1318,86 @@ CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
#
-# RTC drivers
+# I2C RTC drivers
#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-CONFIG_RTC_DRV_S3C=y
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_S3C=y
+# CONFIG_UIO is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
#
# CD-ROM/DVD Filesystems
#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
@@ -1222,7 +1407,9 @@ CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
#
# Pseudo filesystems
@@ -1230,10 +1417,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
#
# Miscellaneous filesystems
@@ -1248,31 +1435,32 @@ CONFIG_RAMFS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1280,7 +1468,6 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1302,94 +1489,93 @@ CONFIG_SOLARIS_X86_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=16
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set
CONFIG_DEBUG_S3C_PORT=y
@@ -1400,21 +1586,100 @@ CONFIG_DEBUG_S3C_UART=0
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
#
-# Cryptographic options
+# Compression
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
#
# Library routines
#
CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig
index 484dc9739df..8688362bcf7 100644
--- a/arch/arm/configs/sam9_l9260_defconfig
+++ b/arch/arm/configs/sam9_l9260_defconfig
@@ -211,7 +211,6 @@ CONFIG_ARM_THUMB=y
#
# CONFIG_TICK_ONESHOT is not set
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index aa7a0117950..7d59fb1f1ce 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -164,7 +164,6 @@ CONFIG_PCMCIA_PXA2XX=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig
index 576b8339f0d..07dfb98df4f 100644
--- a/arch/arm/configs/tct_hammer_defconfig
+++ b/arch/arm/configs/tct_hammer_defconfig
@@ -247,7 +247,6 @@ CONFIG_ARM_THUMB=y
#
# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=200
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
index 6db6392806f..8b7a431a8bf 100644
--- a/arch/arm/configs/trizeps4_defconfig
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -195,7 +195,6 @@ CONFIG_PCMCIA_PXA2XX=y
# Kernel Features
#
CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
diff --git a/arch/arm/configs/usb-a9260_defconfig b/arch/arm/configs/usb-a9260_defconfig
new file mode 100644
index 00000000000..3680bd2df26
--- /dev/null
+++ b/arch/arm/configs/usb-a9260_defconfig
@@ -0,0 +1,1142 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Tue Apr 15 11:39:35 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_AT91SAM9260=y
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9260 Variants
+#
+# CONFIG_ARCH_AT91SAM9260_SAM9XE is not set
+
+#
+# AT91SAM9260 / AT91SAM9XE Board Type
+#
+# CONFIG_MACH_AT91SAM9260EK is not set
+# CONFIG_MACH_CAM60 is not set
+# CONFIG_MACH_SAM9_L9260 is not set
+CONFIG_MACH_USB_A9260=y
+# CONFIG_MACH_QIL_A9260 is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+CONFIG_MTD_NAND_AT91_ECC_SOFT=y
+# CONFIG_MTD_NAND_AT91_ECC_HW is not set
+# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/usb-a9263_defconfig b/arch/arm/configs/usb-a9263_defconfig
new file mode 100644
index 00000000000..48d455bc736
--- /dev/null
+++ b/arch/arm/configs/usb-a9263_defconfig
@@ -0,0 +1,1134 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Tue Apr 15 11:15:19 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+CONFIG_ARCH_AT91SAM9263=y
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9263 Board Type
+#
+# CONFIG_MACH_AT91SAM9263EK is not set
+CONFIG_MACH_USB_A9263=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+CONFIG_MTD_NAND_AT91_ECC_SOFT=y
+# CONFIG_MTD_NAND_AT91_ECC_HW is not set
+# CONFIG_MTD_NAND_AT91_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index 48dca69adda..8355f88f729 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -151,7 +151,6 @@ CONFIG_ARM_AMBA=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
index 64c420805e6..42a1a1415fa 100644
--- a/arch/arm/kernel/atags.c
+++ b/arch/arm/kernel/atags.c
@@ -1,5 +1,4 @@
#include <linux/slab.h>
-#include <linux/kexec.h>
#include <linux/proc_fs.h>
#include <asm/setup.h>
#include <asm/types.h>
@@ -7,9 +6,8 @@
struct buffer {
size_t size;
- char *data;
+ char data[];
};
-static struct buffer tags_buffer;
static int
read_buffer(char* page, char** start, off_t off, int count,
@@ -29,58 +27,57 @@ read_buffer(char* page, char** start, off_t off, int count,
return count;
}
-
-static int
-create_proc_entries(void)
-{
- struct proc_dir_entry* tags_entry;
-
- tags_entry = create_proc_read_entry("atags", 0400, NULL, read_buffer, &tags_buffer);
- if (!tags_entry)
- return -ENOMEM;
-
- return 0;
-}
-
-
-static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
-static char __initdata *atags_copy;
+#define BOOT_PARAMS_SIZE 1536
+static char __initdata atags_copy[BOOT_PARAMS_SIZE];
void __init save_atags(const struct tag *tags)
{
- atags_copy = atags_copy_buf;
- memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
+ memcpy(atags_copy, tags, sizeof(atags_copy));
}
-
static int __init init_atags_procfs(void)
{
- struct tag *tag;
- int error;
+ /*
+ * This cannot go into save_atags() because kmalloc and proc don't work
+ * yet when it is called.
+ */
+ struct proc_dir_entry *tags_entry;
+ struct tag *tag = (struct tag *)atags_copy;
+ struct buffer *b;
+ size_t size;
- if (!atags_copy) {
- printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n");
- return -EIO;
+ if (tag->hdr.tag != ATAG_CORE) {
+ printk(KERN_INFO "No ATAGs?");
+ return -EINVAL;
}
- for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag))
+ for (; tag->hdr.size; tag = tag_next(tag))
;
- tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr);
- tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL);
- if (tags_buffer.data == NULL)
- return -ENOMEM;
- memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
-
- error = create_proc_entries();
- if (error) {
- printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
- kfree(tags_buffer.data);
- tags_buffer.size = 0;
- tags_buffer.data = NULL;
- }
+ /* include the terminating ATAG_NONE */
+ size = (char *)tag - atags_copy + sizeof(struct tag_header);
- return error;
-}
+ WARN_ON(tag->hdr.tag != ATAG_NONE);
+
+ b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
+ if (!b)
+ goto nomem;
+ b->size = size;
+ memcpy(b->data, atags_copy, size);
+
+ tags_entry = create_proc_read_entry("atags", 0400,
+ NULL, read_buffer, b);
+
+ if (!tags_entry)
+ goto nomem;
+
+ return 0;
+
+nomem:
+ kfree(b);
+ printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
+
+ return -ENOMEM;
+}
arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index a53c0aba5c1..8bfd299bfe7 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -680,7 +680,7 @@ static int __init ecard_probeirqhw(void)
#define IO_EC_MEMC8_BASE 0
#endif
-unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
{
unsigned long address = 0;
int slot = ec->slot_no;
@@ -1002,7 +1002,7 @@ ecard_probe(int slot, card_type_t type)
}
rc = -ENODEV;
- if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
+ if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
goto nodev;
cid.r_zero = 1;
@@ -1141,10 +1141,10 @@ static int ecard_drv_probe(struct device *dev)
id = ecard_match_device(drv->id_table, ec);
- ecard_claim(ec);
+ ec->claimed = 1;
ret = drv->probe(ec, id);
if (ret)
- ecard_release(ec);
+ ec->claimed = 0;
return ret;
}
@@ -1154,7 +1154,7 @@ static int ecard_drv_remove(struct device *dev)
struct ecard_driver *drv = ECARD_DRV(dev->driver);
drv->remove(ec);
- ecard_release(ec);
+ ec->claimed = 0;
/*
* Restore the default operations. We ensure that the
@@ -1182,7 +1182,7 @@ static void ecard_drv_shutdown(struct device *dev)
if (dev->driver) {
if (drv->shutdown)
drv->shutdown(ec);
- ecard_release(ec);
+ ec->claimed = 0;
}
/*
@@ -1239,7 +1239,6 @@ static int ecard_bus_init(void)
postcore_initcall(ecard_bus_init);
EXPORT_SYMBOL(ecard_readchunk);
-EXPORT_SYMBOL(__ecard_address);
EXPORT_SYMBOL(ecard_register_driver);
EXPORT_SYMBOL(ecard_remove_driver);
EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h
index d7c2dacf935..4642d436be2 100644
--- a/arch/arm/kernel/ecard.h
+++ b/arch/arm/kernel/ecard.h
@@ -54,3 +54,16 @@ struct ex_chunk_dir {
#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
#define c_start(x) ((x)->r_start)
};
+
+typedef enum ecard_type { /* Cards address space */
+ ECARD_IOC,
+ ECARD_MEMC,
+ ECARD_EASI
+} card_type_t;
+
+typedef enum { /* Speed for ECARD_IOC space */
+ ECARD_SLOW = 0,
+ ECARD_MEDIUM = 1,
+ ECARD_FAST = 2,
+ ECARD_SYNC = 3
+} card_speed_t;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 46bf2ede612..199b3680118 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -133,10 +133,8 @@ static void default_idle(void)
cpu_relax();
else {
local_irq_disable();
- if (!need_resched()) {
- timer_dyn_reprogram();
+ if (!need_resched())
arch_idle();
- }
local_irq_enable();
}
}
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index b5867eca1d0..cc5145b28e7 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -365,108 +365,6 @@ static struct sysdev_class timer_sysclass = {
.resume = timer_resume,
};
-#ifdef CONFIG_NO_IDLE_HZ
-static int timer_dyn_tick_enable(void)
-{
- struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
- unsigned long flags;
- int ret = -ENODEV;
-
- if (dyn_tick) {
- spin_lock_irqsave(&dyn_tick->lock, flags);
- ret = 0;
- if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
- ret = dyn_tick->enable();
-
- if (ret == 0)
- dyn_tick->state |= DYN_TICK_ENABLED;
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
- }
-
- return ret;
-}
-
-static int timer_dyn_tick_disable(void)
-{
- struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
- unsigned long flags;
- int ret = -ENODEV;
-
- if (dyn_tick) {
- spin_lock_irqsave(&dyn_tick->lock, flags);
- ret = 0;
- if (dyn_tick->state & DYN_TICK_ENABLED) {
- ret = dyn_tick->disable();
-
- if (ret == 0)
- dyn_tick->state &= ~DYN_TICK_ENABLED;
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
- }
-
- return ret;
-}
-
-/*
- * Reprogram the system timer for at least the calculated time interval.
- * This function should be called from the idle thread with IRQs disabled,
- * immediately before sleeping.
- */
-void timer_dyn_reprogram(void)
-{
- struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
- unsigned long next, seq, flags;
-
- if (!dyn_tick)
- return;
-
- spin_lock_irqsave(&dyn_tick->lock, flags);
- if (dyn_tick->state & DYN_TICK_ENABLED) {
- next = next_timer_interrupt();
- do {
- seq = read_seqbegin(&xtime_lock);
- dyn_tick->reprogram(next - jiffies);
- } while (read_seqretry(&xtime_lock, seq));
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
-}
-
-static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
-{
- return sprintf(buf, "%i\n",
- (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
-}
-
-static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
- size_t count)
-{
- unsigned int enable = simple_strtoul(buf, NULL, 2);
-
- if (enable)
- timer_dyn_tick_enable();
- else
- timer_dyn_tick_disable();
-
- return count;
-}
-static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
-
-/*
- * dyntick=enable|disable
- */
-static char dyntick_str[4] __initdata = "";
-
-static int __init dyntick_setup(char *str)
-{
- if (str)
- strlcpy(dyntick_str, str, sizeof(dyntick_str));
- return 1;
-}
-
-__setup("dyntick=", dyntick_setup);
-#endif
-
static int __init timer_init_sysfs(void)
{
int ret = sysdev_class_register(&timer_sysclass);
@@ -475,19 +373,6 @@ static int __init timer_init_sysfs(void)
ret = sysdev_register(&system_timer->dev);
}
-#ifdef CONFIG_NO_IDLE_HZ
- if (ret == 0 && system_timer->dyn_tick) {
- ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick);
-
- /*
- * Turn on dynamic tick after calibrate delay
- * for correct bogomips
- */
- if (ret == 0 && dyntick_str[0] == 'e')
- ret = timer_dyn_tick_enable();
- }
-#endif
-
return ret;
}
@@ -500,10 +385,5 @@ void __init time_init(void)
system_timer->offset = dummy_gettimeoffset;
#endif
system_timer->init();
-
-#ifdef CONFIG_NO_IDLE_HZ
- if (system_timer->dyn_tick)
- spin_lock_init(&system_timer->dyn_tick->lock);
-#endif
}
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 0fc07b6db74..5bad6b9b00d 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -30,6 +30,11 @@ config ARCH_AT91SAM9RL
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
+config ARCH_AT91SAM9G20
+ bool "AT91SAM9G20"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+
config ARCH_AT91CAP9
bool "AT91CAP9"
select GENERIC_TIME
@@ -126,6 +131,12 @@ config MACH_ECBAT91
Select this if you are using emQbit's ECB_AT91 board.
<http://wiki.emqbit.com/free-ecb-at91>
+config MACH_YL9200
+ bool "ucDragon YL-9200"
+ depends on ARCH_AT91RM9200
+ help
+ Select this if you are using the ucDragon YL-9200 board.
+
endif
# ----------------------------------------------------------
@@ -164,6 +175,20 @@ config MACH_SAM9_L9260
Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260.
<http://www.olimex.com/dev/sam9-L9260.html>
+config MACH_USB_A9260
+ bool "CALAO USB-A9260"
+ depends on ARCH_AT91SAM9260
+ help
+ Select this if you are using a Calao Systems USB-A9260.
+ <http://www.calao-systems.com>
+
+config MACH_QIL_A9260
+ bool "CALAO QIL-A9260 board"
+ depends on ARCH_AT91SAM9260
+ help
+ Select this if you are using a Calao Systems QIL-A9260 Board.
+ <http://www.calao-systems.com>
+
endif
# ----------------------------------------------------------
@@ -194,6 +219,13 @@ config MACH_AT91SAM9263EK
Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
<http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
+config MACH_USB_A9263
+ bool "CALAO USB-A9263"
+ depends on ARCH_AT91SAM9263
+ help
+ Select this if you are using a Calao Systems USB-A9263.
+ <http://www.calao-systems.com>
+
endif
# ----------------------------------------------------------
@@ -212,6 +244,20 @@ endif
# ----------------------------------------------------------
+if ARCH_AT91SAM9G20
+
+comment "AT91SAM9G20 Board Type"
+
+config MACH_AT91SAM9G20EK
+ bool "Atmel AT91SAM9G20-EK Evaluation Kit"
+ depends on ARCH_AT91SAM9G20
+ help
+ Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
+
+endif
+
+# ----------------------------------------------------------
+
if ARCH_AT91CAP9
comment "AT91CAP9 Board Type"
@@ -247,13 +293,13 @@ comment "AT91 Board Options"
config MTD_AT91_DATAFLASH_CARD
bool "Enable DataFlash Card support"
- depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK || MACH_SAM9_L9260 || MACH_ECBAT91)
+ depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK)
help
Enable support for the DataFlash card.
config MTD_NAND_AT91_BUSWIDTH_16
bool "Enable 16-bit data bus interface to NAND flash"
- depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
+ depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK)
help
On AT91SAM926x boards both types of NAND flash can be present
(8 and 16 bit data bus width).
@@ -302,15 +348,15 @@ config AT91_EARLY_USART2
config AT91_EARLY_USART3
bool "USART3"
- depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260)
+ depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
config AT91_EARLY_USART4
bool "USART4"
- depends on ARCH_AT91SAM9260
+ depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20
config AT91_EARLY_USART5
bool "USART5"
- depends on ARCH_AT91SAM9260
+ depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20
endchoice
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 8d9bc0153b1..7d641f97516 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
@@ -30,21 +31,28 @@ obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
+obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
obj-$(CONFIG_MACH_CAM60) += board-cam60.o
obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o
+obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o
+obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o
# AT91SAM9261 board-specific support
obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
# AT91SAM9263 board-specific support
obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
+obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o
# AT91SAM9RL board-specific support
obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
+# AT91SAM9G20 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
+
# AT91CAP9 board-specific support
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index be526746e01..747b9dedab8 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -84,6 +84,105 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
/* --------------------------------------------------------------------
+ * USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+ [0] = {
+ .start = AT91CAP9_UDPHS_FIFO,
+ .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_BASE_UDPHS,
+ .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91CAP9_ID_UDPHS,
+ .end = AT91CAP9_ID_UDPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
+ [idx] = { \
+ .name = nam, \
+ .index = idx, \
+ .fifo_size = maxpkt, \
+ .nr_banks = maxbk, \
+ .can_dma = dma, \
+ .can_isoc = isoc, \
+ }
+
+static struct usba_ep_data usba_udc_ep[] = {
+ EP("ep0", 0, 64, 1, 0, 0),
+ EP("ep1", 1, 1024, 3, 1, 1),
+ EP("ep2", 2, 1024, 3, 1, 1),
+ EP("ep3", 3, 1024, 2, 1, 1),
+ EP("ep4", 4, 1024, 2, 1, 1),
+ EP("ep5", 5, 1024, 2, 1, 0),
+ EP("ep6", 6, 1024, 2, 1, 0),
+ EP("ep7", 7, 1024, 2, 0, 0),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+ struct usba_platform_data pdata;
+ struct usba_ep_data ep[8];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+ .name = "atmel_usba_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &usba_udc_data.pdata,
+ },
+ .resource = usba_udc_resources,
+ .num_resources = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+ at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
+ AT91_MATRIX_UDPHS_BYPASS_LOCK);
+
+ /*
+ * Invalid pins are 0 on AT91, but the usba driver is shared
+ * with AVR32, which use negative values instead. Once/if
+ * gpio_is_valid() is ported to AT91, revisit this code.
+ */
+ usba_udc_data.pdata.vbus_pin = -EINVAL;
+ usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+ memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+
+ if (data && data->vbus_pin > 0) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ /* Clocks */
+ at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
+ at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
+
+ platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
* Ethernet
* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index ee26550cdc2..380f12a1220 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -47,6 +47,20 @@ static struct map_desc at91sam9260_sram_desc[] __initdata = {
}
};
+static struct map_desc at91sam9g20_sram_desc[] __initdata = {
+ {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE),
+ .length = AT91SAM9G20_SRAM0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE),
+ .length = AT91SAM9G20_SRAM1_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
static struct map_desc at91sam9xe_sram_desc[] __initdata = {
{
.pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE),
@@ -307,6 +321,8 @@ void __init at91sam9260_initialize(unsigned long main_clock)
if (cpu_is_at91sam9xe())
at91sam9xe_initialize();
+ else if (cpu_is_at91sam9g20())
+ iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc));
else
iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 393a32aefce..86cba4ac29b 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -18,6 +18,7 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/cpu.h>
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91sam9260_matrix.h>
#include <asm/arch/at91sam9_smc.h>
@@ -320,20 +321,41 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
csa = at91_sys_read(AT91_MATRIX_EBICSA);
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
- /* set the bus interface characteristics */
- at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
- | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+ if (cpu_is_at91sam9260()) {
+ /* Timing for sam9260 */
+ /* set the bus interface characteristics */
+ at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0)
+ | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));
- at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
- | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
+ at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
+ | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
- at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
+ at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
- if (data->bus_width_16)
- mode = AT91_SMC_DBW_16;
- else
- mode = AT91_SMC_DBW_8;
- at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
+ if (data->bus_width_16)
+ mode = AT91_SMC_DBW_16;
+ else
+ mode = AT91_SMC_DBW_8;
+ at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
+ }
+
+ if (cpu_is_at91sam9g20()) {
+ /* Timing for sam9g20 */
+ /* set the bus interface characteristics */
+ at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0)
+ | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0));
+
+ at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(4)
+ | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(4));
+
+ at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));
+
+ if (data->bus_width_16)
+ mode = AT91_SMC_DBW_16;
+ else
+ mode = AT91_SMC_DBW_8;
+ at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(3));
+ }
/* enable pin */
if (data->enable_pin)
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 0babb645b83..ec1891375df 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -232,19 +232,19 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
/* set the bus interface characteristics */
- at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
- | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+ at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0)
+ | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));
- at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5)
- | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5));
+ at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
+ | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
- at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));
+ at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
if (data->bus_width_16)
mode = AT91_SMC_DBW_16;
else
mode = AT91_SMC_DBW_8;
- at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
+ at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
/* enable pin */
if (data->enable_pin)
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 719667e25c9..8a81f76f020 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -391,8 +391,8 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
/* set the bus interface characteristics */
- at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
- | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+ at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0)
+ | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));
at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
| AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 450db304936..ae28101e754 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -26,6 +26,101 @@
/* --------------------------------------------------------------------
+ * USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_UDPHS_FIFO,
+ .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_BASE_UDPHS,
+ .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91SAM9RL_ID_UDPHS,
+ .end = AT91SAM9RL_ID_UDPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
+ [idx] = { \
+ .name = nam, \
+ .index = idx, \
+ .fifo_size = maxpkt, \
+ .nr_banks = maxbk, \
+ .can_dma = dma, \
+ .can_isoc = isoc, \
+ }
+
+static struct usba_ep_data usba_udc_ep[] __initdata = {
+ EP("ep0", 0, 64, 1, 0, 0),
+ EP("ep1", 1, 1024, 2, 1, 1),
+ EP("ep2", 2, 1024, 2, 1, 1),
+ EP("ep3", 3, 1024, 3, 1, 0),
+ EP("ep4", 4, 1024, 3, 1, 0),
+ EP("ep5", 5, 1024, 3, 1, 1),
+ EP("ep6", 6, 1024, 3, 1, 1),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+ struct usba_platform_data pdata;
+ struct usba_ep_data ep[7];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+ .name = "atmel_usba_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &usba_udc_data.pdata,
+ },
+ .resource = usba_udc_resources,
+ .num_resources = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+ /*
+ * Invalid pins are 0 on AT91, but the usba driver is shared
+ * with AVR32, which use negative values instead. Once/if
+ * gpio_is_valid() is ported to AT91, revisit this code.
+ */
+ usba_udc_data.pdata.vbus_pin = -EINVAL;
+ usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+ memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+
+ if (data && data->vbus_pin > 0) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ /* Clocks */
+ at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
+ at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
+
+ platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
* MMC / SD
* -------------------------------------------------------------------- */
@@ -138,15 +233,15 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
/* set the bus interface characteristics */
- at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
- | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
+ at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0)
+ | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));
- at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5)
- | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5));
+ at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
+ | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
- at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));
+ at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
- at91_sys_write(AT91_SMC_MODE(3), AT91_SMC_DBW_8 | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
+ at91_sys_write(AT91_SMC_MODE(3), AT91_SMC_DBW_8 | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
/* enable pin */
if (data->enable_pin)
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
index e5512d1ff21..8a2a958639d 100644
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -78,6 +78,12 @@ static struct at91_usbh_data __initdata cap9adk_usbh_data = {
.ports = 2,
};
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
+ .vbus_pin = AT91_PIN_PB31,
+};
/*
* ADS7846 Touchscreen
@@ -326,6 +332,9 @@ static void __init cap9adk_board_init(void)
/* USB Host */
set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH);
at91_add_device_usbh(&cap9adk_usbh_data);
+ /* USB HS */
+ set_irq_type(AT91CAP9_ID_UDPHS, IRQT_HIGH);
+ at91_add_device_usba(&cap9adk_usba_udc_data);
/* SPI */
at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
/* Touchscreen */
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index 0f0878294a6..9854fc3dd1f 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -40,24 +40,21 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata carmeva_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init carmeva_map_io(void)
{
/* Initialize processor: 20.000 MHz crystal */
at91rm9200_initialize(20000000, AT91RM9200_BGA);
- /* Setup the serial ports and console */
- at91_init_serial(&carmeva_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init carmeva_init_irq(void)
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index 419fd19b620..bb1a5474dda 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -45,10 +45,10 @@ static void __init csb637_map_io(void)
/* Initialize processor: 3.6864 MHz crystal */
at91rm9200_initialize(3686400, AT91RM9200_BGA);
- /* DBGU on ttyS0 */
+ /* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
- /* make console=ttyS0 the default */
+ /* make console=ttyS0 (ie, DBGU) the default */
at91_set_serial_console(0);
}
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index c1a813c7169..dab958d2592 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -45,17 +45,6 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata dk_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init dk_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
@@ -64,8 +53,16 @@ static void __init dk_map_io(void)
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
- /* Setup the serial ports and console */
- at91_init_serial(&dk_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init dk_init_irq(void)
@@ -163,7 +160,7 @@ static struct at91_nand_data __initdata dk_nand_data = {
#define DK_FLASH_SIZE 0x200000
static struct physmap_flash_data dk_flash_data = {
- .width = 2,
+ .width = 2,
};
static struct resource dk_flash_resource = {
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index af1a1d8ecc3..3fe054e0056 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -40,24 +40,24 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata eb9200_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init eb9200_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
at91rm9200_initialize(18432000, AT91RM9200_BGA);
- /* Setup the serial ports and console */
- at91_init_serial(&eb9200_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART2 on ttyS2. (Rx, Tx) - IRDA */
+ at91_register_uart(AT91RM9200_ID_US2, 2, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init eb9200_init_irq(void)
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 0574e50a30d..74aa4325eab 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -45,17 +45,6 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata ek_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init ek_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
@@ -64,8 +53,16 @@ static void __init ek_map_io(void)
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
- /* Setup the serial ports and console */
- at91_init_serial(&ek_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init ek_init_irq(void)
@@ -122,7 +119,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {
#define EK_FLASH_SIZE 0x200000
static struct physmap_flash_data ek_flash_data = {
- .width = 2,
+ .width = 2,
};
static struct resource ek_flash_resource = {
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index 4b39b9cda75..cb065febd95 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -37,19 +37,10 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
-#include "generic.h"
+#include <asm/arch/at91rm9200_mc.h>
+#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata kb9202_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 3,
- .tty_map = { 4, 0, 1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
static void __init kb9202_map_io(void)
{
@@ -59,8 +50,20 @@ static void __init kb9202_map_io(void)
/* Set up the LEDs */
at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
- /* Setup the serial ports and console */
- at91_init_serial(&kb9202_uart_config);
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx & Tx only) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, 0);
+
+ /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */
+ at91_register_uart(AT91RM9200_ID_US1, 2, 0);
+
+ /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */
+ at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init kb9202_init_irq(void)
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c
new file mode 100644
index 00000000000..99b4ec3818d
--- /dev/null
+++ b/arch/arm/mach-at91/board-qil-a9260.c
@@ -0,0 +1,255 @@
+/*
+ * linux/arch/arm/mach-at91/board-qil-a9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91_shdwc.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9260_initialize(12000000);
+
+ /* 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, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS1 (ie, USART0) */
+ at91_set_serial_console(1);
+
+}
+
+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_RTC_DRV_M41T94)
+ { /* M41T94 RTC */
+ .modalias = "m41t94",
+ .chip_select = 0,
+ .max_speed_hz = 1 * 1000 * 1000,
+ .bus_num = 0,
+ }
+#endif
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Uboot & Kernel",
+ .offset = 0x00000000,
+ .size = 16 * 1024 * 1024,
+ },
+ {
+ .name = "Root FS",
+ .offset = 0x01000000,
+ .size = 120 * 1024 * 1024,
+ },
+ {
+ .name = "FS",
+ .offset = 0x08800000,
+ .size = 120 * 1024 * 1024,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct at91_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+ .bus_width_16 = 1,
+#else
+ .bus_width_16 = 0,
+#endif
+};
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+// .det_pin = ... not connected
+// .wp_pin = ... not connected
+// .vcc_pin = ... not connected
+};
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ }
+};
+
+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 */
+ at91_add_device_nand(&ek_nand_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(QIL_A9260, "CALAO QIL_A9260")
+ /* Maintainer: calao-systems */
+ .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/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
new file mode 100644
index 00000000000..45617c20124
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.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_AT91)
+ { /* 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_PA7,
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Bootstrap",
+ .offset = 0,
+ .size = 4 * 1024 * 1024,
+ },
+ {
+ .name = "Partition 1",
+ .offset = 4 * 1024 * 1024,
+ .size = 60 * 1024 * 1024,
+ },
+ {
+ .name = "Partition 2",
+ .offset = 64 * 1024 * 1024,
+ .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 at91_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_AT91_BUSWIDTH_16)
+ .bus_width_16 = 1,
+#else
+ .bus_width_16 = 0,
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 1,
+ .wire4 = 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds5",
+ .gpio = AT91_PIN_PA6,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA9,
+ .default_trigger = "heartbeat",
+ }
+};
+
+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 */
+ at91_add_device_nand(&ek_nand_data);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
+
+MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
+ /* Maintainer: Atmel */
+ .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/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index ffc0597aee8..b6a70fc735c 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -56,6 +56,14 @@ static void __init ek_init_irq(void)
/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata ek_usba_udc_data = {
+ .vbus_pin = AT91_PIN_PA8,
+};
+
+
+/*
* MCI (SD/MMC)
*/
static struct at91_mmc_data __initdata ek_mmc_data = {
@@ -175,6 +183,8 @@ static void __init ek_board_init(void)
{
/* Serial */
at91_add_device_serial();
+ /* USB HS */
+ at91_add_device_usba(&ek_usba_udc_data);
/* I2C */
at91_add_device_i2c(NULL, 0);
/* NAND */
diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c
new file mode 100644
index 00000000000..837aedf8ffe
--- /dev/null
+++ b/arch/arm/mach-at91/board-usb-a9260.c
@@ -0,0 +1,215 @@
+/*
+ * linux/arch/arm/mach-at91/board-usb-a9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91_shdwc.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9260_initialize(12000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* 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 */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Uboot & Kernel",
+ .offset = 0x00000000,
+ .size = 16 * 1024 * 1024,
+ },
+ {
+ .name = "Root FS",
+ .offset = 0x01000000,
+ .size = 120 * 1024 * 1024,
+ },
+ {
+ .name = "FS",
+ .offset = 0x08800000,
+ .size = 120 * 1024 * 1024,
+ }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct at91_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+ .bus_width_16 = 1,
+#else
+ .bus_width_16 = 0,
+#endif
+};
+
+/*
+ * GPIO Buttons
+ */
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ }
+};
+
+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);
+ /* NAND */
+ at91_add_device_nand(&ek_nand_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(USB_A9260, "CALAO USB_A9260")
+ /* Maintainer: calao-systems */
+ .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/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c
new file mode 100644
index 00000000000..95800d32bd4
--- /dev/null
+++ b/arch/arm/mach-at91/board-usb-a9263.c
@@ -0,0 +1,230 @@
+/*
+ * linux/arch/arm/mach-at91/board-usb-a9263.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation.
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91_shdwc.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+ /* Initialize processor: 12.00 MHz crystal */
+ at91sam9263_initialize(12000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9263_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_PB11,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ }
+#endif
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PE31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Linux Kernel",
+ .offset = 0x00000000,
+ .size = 16 * 1024 * 1024,
+ },
+ {
+ .name = "Root FS",
+ .offset = 0x01000000,
+ .size = 120 * 1024 * 1024,
+ },
+ {
+ .name = "FS",
+ .offset = 0x08800000,
+ .size = 120 * 1024 * 1024,
+ }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct at91_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PA22,
+ .enable_pin = AT91_PIN_PD15,
+ .partition_info = nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+ .bus_width_16 = 1,
+#else
+ .bus_width_16 = 0,
+#endif
+};
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ }
+};
+
+
+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));
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* NAND */
+ at91_add_device_nand(&ek_nand_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(USB_A9263, "CALAO USB_A9263")
+ /* Maintainer: calao-systems */
+ .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/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
index b5717108991..7079050ab88 100755
--- a/arch/arm/mach-at91/board-yl-9200.c
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -1,11 +1,10 @@
/*
* linux/arch/arm/mach-at91/board-yl-9200.c
*
- * Adapted from:
- *various board files in
- * /arch/arm/mach-at91
- * modifications to convert to YL-9200 platform
- * Copyright (C) 2007 S.Birtles
+ * Adapted from various board files in arch/arm/mach-at91
+ *
+ * Modifications for YL-9200 platform:
+ * Copyright (C) 2007 S. Birtles
*
* 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
@@ -26,13 +25,14 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
-/*#include <linux/can_bus/candata.h>*/
#include <linux/spi/ads7846.h>
#include <linux/mtd/physmap.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
-/*#include <sound/gpio_sounder.h>*/
#include <asm/hardware.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -45,179 +45,108 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91rm9200_mc.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
#include "generic.h"
-#include <asm/arch/at91_pio.h>
-#define YL_9200_FLASH_BASE AT91_CHIPSELECT_0
-#define YL_9200_FLASH_SIZE 0x800000
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- *atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
- *atmel_usart.1: ttyS1 at MMIO 0xfffc0000 (irq = 6) is a ATMEL_SERIAL
- *atmel_usart.2: ttyS2 at MMIO 0xfffc4000 (irq = 7) is a ATMEL_SERIAL
- *atmel_usart.3: ttyS3 at MMIO 0xfffc8000 (irq = 8) is a ATMEL_SERIAL
- *atmel_usart.4: ttyS4 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL
- * on the YL-9200 we are sitting at the following
- *ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL
- *ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL
- */
+static void __init yl9200_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000, AT91RM9200_PQFP);
-/* extern void __init yl_9200_add_device_sounder(struct gpio_sounder *sounders, int nr);*/
+ /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */
+ at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17);
-static struct at91_uart_config __initdata yl_9200_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 3,
- .tty_map = { 4, 1, 0, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
-static void __init yl_9200_map_io(void)
-{
- /* Initialize processor: 18.432 MHz crystal */
- /*Also initialises register clocks & gpio*/
- at91rm9200_initialize(18432000, AT91RM9200_PQFP); /*we have a 3 bank system*/
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
- /* Setup the serial ports and console */
- at91_init_serial(&yl_9200_uart_config);
+ /* USART0 on ttyS2. (Rx & Tx only to JP3) */
+ at91_register_uart(AT91RM9200_ID_US0, 2, 0);
- /* Setup the LEDs D2=PB17,D3=PB16 */
- at91_init_leds(AT91_PIN_PB16,AT91_PIN_PB17); /*cpu-led,timer-led*/
+ /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */
+ at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
-static void __init yl_9200_init_irq(void)
+static void __init yl9200_init_irq(void)
{
at91rm9200_init_interrupts(NULL);
}
-static struct at91_eth_data __initdata yl_9200_eth_data = {
- .phy_irq_pin = AT91_PIN_PB28,
- .is_rmii = 1,
-};
-static struct at91_usbh_data __initdata yl_9200_usbh_data = {
- .ports = 1, /* this should be 1 not 2 for the Yl9200*/
+/*
+ * LEDs
+ */
+static struct gpio_led yl9200_leds[] = {
+ { /* D2 */
+ .name = "led2",
+ .gpio = AT91_PIN_PB17,
+ .active_low = 1,
+ .default_trigger = "timer",
+ },
+ { /* D3 */
+ .name = "led3",
+ .gpio = AT91_PIN_PB16,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* D4 */
+ .name = "led4",
+ .gpio = AT91_PIN_PB15,
+ .active_low = 1,
+ },
+ { /* D5 */
+ .name = "led5",
+ .gpio = AT91_PIN_PB8,
+ .active_low = 1,
+ }
};
-static struct at91_udc_data __initdata yl_9200_udc_data = {
-/*on sheet 7 Schemitic rev 1.0*/
- .pullup_pin = AT91_PIN_PC4,
- .vbus_pin= AT91_PIN_PC5,
- .pullup_active_low = 1, /*ACTIVE LOW!! due to PNP transistor on page 7*/
-
-};
/*
-static struct at91_cf_data __initdata yl_9200_cf_data = {
-TODO S.BIRTLES
- .det_pin = AT91_PIN_xxx,
- .rst_pin = AT91_PIN_xxx,
- .irq_pin = ... not connected
- .vcc_pin = ... always powered
-
+ * Ethernet
+ */
+static struct at91_eth_data __initdata yl9200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PB28,
+ .is_rmii = 1,
};
-*/
-static struct at91_mmc_data __initdata yl_9200_mmc_data = {
- .det_pin = AT91_PIN_PB9, /*THIS LOOKS CORRECT SHEET7*/
-/* .wp_pin = ... not connected SHEET7*/
- .slot_b = 0,
- .wire4 = 1,
+/*
+ * USB Host
+ */
+static struct at91_usbh_data __initdata yl9200_usbh_data = {
+ .ports = 1, /* PQFP version of AT91RM9200 */
};
-/* --------------------------------------------------------------------
- * Touch screen
- * -------------------------------------------------------------------- */
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-static int ads7843_pendown_state(void)
-{
- return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */
-}
-
-static void __init at91_init_device_ts(void)
-{
-/*IMPORTANT NOTE THE SPI INTERFACE IS ALREADY CONFIGURED BY XXX_DEVICES.C
-THAT IS TO SAY THAT MISO,MOSI,SPCK AND CS are already configured
-we only need to enable the other datapins which are:
-PB10/RK1 BUSY
-*/
-/* Touchscreen BUSY signal , pin,use pullup ( TODO not currently used in the ADS7843/6.c driver)*/
-at91_set_gpio_input(AT91_PIN_PB10, 1);
-}
-
-#else
-static void __init at91_init_device_ts(void) {}
-#endif
-
-static struct ads7846_platform_data ads_info = {
- .model = 7843,
- .x_min = 150,
- .x_max = 3830,
- .y_min = 190,
- .y_max = 3830,
- .vref_delay_usecs = 100,
-/* for a 8" touch screen*/
- //.x_plate_ohms = 603, //= 450, S.Birtles TODO
- //.y_plate_ohms = 332, //= 250, S.Birtles TODO
-/*for a 10.4" touch screen*/
- //.x_plate_ohms =611,
- //.y_plate_ohms =325,
-
- .x_plate_ohms = 576,
- .y_plate_ohms = 366,
- //
- .pressure_max = 15000, /*generally nonsense on the 7843*/
- /*number of times to send query to chip in a given run 0 equals one time (do not set to 0!! ,there is a bug in ADS 7846 code)*/
- .debounce_max = 1,
- .debounce_rep = 0,
- .debounce_tol = (~0),
- .get_pendown_state = ads7843_pendown_state,
-};
+/*
+ * USB Device
+ */
+static struct at91_udc_data __initdata yl9200_udc_data = {
+ .pullup_pin = AT91_PIN_PC4,
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_active_low = 1, /* Active Low due to PNP transistor (pg 7) */
-/*static struct canbus_platform_data can_info = {
- .model = 2510,
};
-*/
-
-static struct spi_board_info yl_9200_spi_devices[] = {
-/*this sticks it at:
- /sys/devices/platform/atmel_spi.0/spi0.0
- /sys/bus/platform/devices/
-Documentation/spi IIRC*/
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
- /*(this IS correct 04-NOV-2007)*/
- {
- .modalias = "ads7846", /* because the driver is called ads7846*/
- .chip_select = 0, /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */
-/*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select*/
- /*.controller_data =AT91_PIN_PA3 ,*/
- .max_speed_hz = 5000*26, /*(4700 * 26)-125000 * 26, (max sample rate @ 3V) * (cmd + data + overhead) */
- .bus_num = 0,
- .platform_data = &ads_info,
- .irq = AT91_PIN_PB11,
- },
-#endif
-/*we need to put our CAN driver data here!!*/
-/*THIS IS ALL DUMMY DATA*/
-/* {
- .modalias = "mcp2510", //DUMMY for MCP2510 chip
- .chip_select = 1,*/ /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */
- /*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select */
- /* .controller_data =AT91_PIN_PA4 ,
- .max_speed_hz = 25000 * 26,
- .bus_num = 0,
- .platform_data = &can_info,
- .irq = AT91_PIN_PC0,
- },
- */
- //max SPI chip needs to go here
+/*
+ * MMC
+ */
+static struct at91_mmc_data __initdata yl9200_mmc_data = {
+ .det_pin = AT91_PIN_PB9,
+ // .wp_pin = ... not connected
+ .wire4 = 1,
};
-static struct mtd_partition __initdata yl_9200_nand_partition[] = {
+/*
+ * NAND Flash
+ */
+static struct mtd_partition __initdata yl9200_nand_partition[] = {
{
.name = "AT91 NAND partition 1, boot",
.offset = 0,
@@ -242,442 +171,434 @@ static struct mtd_partition __initdata yl_9200_nand_partition[] = {
.name = "AT91 NAND partition 5, ext-fs",
.offset = 32 * SZ_1M,
.size = 32 * SZ_1M
- },
+ }
};
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
- *num_partitions = ARRAY_SIZE(yl_9200_nand_partition);
- return yl_9200_nand_partition;
+ *num_partitions = ARRAY_SIZE(yl9200_nand_partition);
+ return yl9200_nand_partition;
}
-static struct at91_nand_data __initdata yl_9200_nand_data = {
- .ale= 6,
- .cle= 7,
- /*.det_pin = AT91_PIN_PCxx,*/ /*we don't have a det pin because NandFlash is fixed to board*/
- .rdy_pin = AT91_PIN_PC14, /*R/!B Sheet10*/
- .enable_pin = AT91_PIN_PC15, /*!CE Sheet10 */
+static struct at91_nand_data __initdata yl9200_nand_data = {
+ .ale = 6,
+ .cle = 7,
+ // .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */
+ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */
.partition_info = nand_partitions,
};
-
-
/*
-TODO S.Birtles
-potentially a problem with the size above
-physmap platform flash device: 00800000 at 10000000
-physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank
-NOR chip too large to fit in mapping. Attempting to cope...
- Intel/Sharp Extended Query Table at 0x0031
-Using buffer write method
-cfi_cmdset_0001: Erase suspend on write enabled
-Reducing visibility of 16384KiB chip to 8192KiB
-*/
+ * NOR Flash
+ */
+#define YL9200_FLASH_BASE AT91_CHIPSELECT_0
+#define YL9200_FLASH_SIZE 0x1000000
-static struct mtd_partition yl_9200_flash_partitions[] = {
+static struct mtd_partition yl9200_flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
{
- .name = "Bootloader",
- .size = 0x00040000,
- .offset = 0,
- .mask_flags = MTD_WRITEABLE /* force read-only */
- },{
- .name = "Kernel",
- .size = 0x001C0000,
- .offset = 0x00040000,
- },{
- .name = "Filesystem",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00200000
+ .name = "Kernel",
+ .size = 0x001C0000,
+ .offset = 0x00040000,
+ },
+ {
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00200000
}
-
};
-static struct physmap_flash_data yl_9200_flash_data = {
- .width = 2,
- .parts = yl_9200_flash_partitions,
- .nr_parts = ARRAY_SIZE(yl_9200_flash_partitions),
+static struct physmap_flash_data yl9200_flash_data = {
+ .width = 2,
+ .parts = yl9200_flash_partitions,
+ .nr_parts = ARRAY_SIZE(yl9200_flash_partitions),
};
-static struct resource yl_9200_flash_resources[] = {
-{
- .start = YL_9200_FLASH_BASE,
- .end = YL_9200_FLASH_BASE + YL_9200_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
+static struct resource yl9200_flash_resources[] = {
+ {
+ .start = YL9200_FLASH_BASE,
+ .end = YL9200_FLASH_BASE + YL9200_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
}
};
-static struct platform_device yl_9200_flash = {
+static struct platform_device yl9200_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
- .platform_data = &yl_9200_flash_data,
+ .platform_data = &yl9200_flash_data,
},
- .resource = yl_9200_flash_resources,
- .num_resources = ARRAY_SIZE(yl_9200_flash_resources),
+ .resource = yl9200_flash_resources,
+ .num_resources = ARRAY_SIZE(yl9200_flash_resources),
};
-
-static struct gpio_led yl_9200_leds[] = {
-/*D2 &D3 are passed directly in via at91_init_leds*/
- {
- .name = "led4", /*D4*/
- .gpio = AT91_PIN_PB15,
- .active_low = 1,
- .default_trigger = "heartbeat",
- /*.default_trigger = "timer",*/
- },
- {
- .name = "led5", /*D5*/
- .gpio = AT91_PIN_PB8,
- .active_low = 1,
- .default_trigger = "heartbeat",
- }
-};
-
-//static struct gpio_sounder yl_9200_sounder[] = {*/
-/*This is a simple speaker attached to a gpo line*/
-
-// {
-// .name = "Speaker", /*LS1*/
-// .gpio = AT91_PIN_PA22,
-// .active_low = 0,
-// .default_trigger = "heartbeat",
- /*.default_trigger = "timer",*/
-// },
-//};
-
-
-
-static struct i2c_board_info __initdata yl_9200_i2c_devices[] = {
- {
- /*TODO*/
- I2C_BOARD_INFO("CS4334", 0x00),
+/*
+ * I2C (TWI)
+ */
+static struct i2c_board_info __initdata yl9200_i2c_devices[] = {
+ { /* EEPROM */
+ I2C_BOARD_INFO("24c128", 0x50),
}
};
-
- /*
+/*
* GPIO Buttons
- */
+*/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-static struct gpio_keys_button yl_9200_buttons[] = {
+static struct gpio_keys_button yl9200_buttons[] = {
{
.gpio = AT91_PIN_PA24,
- .code = BTN_2,
+ .code = BTN_2,
.desc = "SW2",
.active_low = 1,
.wakeup = 1,
},
{
.gpio = AT91_PIN_PB1,
- .code = BTN_3,
+ .code = BTN_3,
.desc = "SW3",
.active_low = 1,
.wakeup = 1,
},
{
.gpio = AT91_PIN_PB2,
- .code = BTN_4,
+ .code = BTN_4,
.desc = "SW4",
.active_low = 1,
.wakeup = 1,
},
{
.gpio = AT91_PIN_PB6,
- .code = BTN_5,
+ .code = BTN_5,
.desc = "SW5",
.active_low = 1,
.wakeup = 1,
- },
-
+ }
};
-static struct gpio_keys_platform_data yl_9200_button_data = {
- .buttons = yl_9200_buttons,
- .nbuttons = ARRAY_SIZE(yl_9200_buttons),
+static struct gpio_keys_platform_data yl9200_button_data = {
+ .buttons = yl9200_buttons,
+ .nbuttons = ARRAY_SIZE(yl9200_buttons),
};
-static struct platform_device yl_9200_button_device = {
+static struct platform_device yl9200_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
- .platform_data = &yl_9200_button_data,
+ .platform_data = &yl9200_button_data,
}
};
-static void __init yl_9200_add_device_buttons(void)
+static void __init yl9200_add_device_buttons(void)
{
- //SW2
- at91_set_gpio_input(AT91_PIN_PA24, 0);
+ at91_set_gpio_input(AT91_PIN_PA24, 1); /* SW2 */
at91_set_deglitch(AT91_PIN_PA24, 1);
-
- //SW3
- at91_set_gpio_input(AT91_PIN_PB1, 0);
+ at91_set_gpio_input(AT91_PIN_PB1, 1); /* SW3 */
at91_set_deglitch(AT91_PIN_PB1, 1);
- //SW4
- at91_set_gpio_input(AT91_PIN_PB2, 0);
+ at91_set_gpio_input(AT91_PIN_PB2, 1); /* SW4 */
at91_set_deglitch(AT91_PIN_PB2, 1);
-
- //SW5
- at91_set_gpio_input(AT91_PIN_PB6, 0);
+ at91_set_gpio_input(AT91_PIN_PB6, 1); /* SW5 */
at91_set_deglitch(AT91_PIN_PB6, 1);
+ /* Enable buttons (Sheet 5) */
+ at91_set_gpio_output(AT91_PIN_PB7, 1);
+
+ platform_device_register(&yl9200_button_device);
+}
+#else
+static void __init yl9200_add_device_buttons(void) {}
+#endif
+
+/*
+ * Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+
+ /* For a 8" touch-screen */
+ // .x_plate_ohms = 603,
+ // .y_plate_ohms = 332,
+
+ /* For a 10.4" touch-screen */
+ // .x_plate_ohms = 611,
+ // .y_plate_ohms = 325,
+
+ .x_plate_ohms = 576,
+ .y_plate_ohms = 366,
+
+ .pressure_max = 15000, /* generally nonsense on the 7843 */
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
- at91_set_gpio_output(AT91_PIN_PB7, 1); /* #TURN BUTTONS ON, SHEET 5 of schematics */
- platform_device_register(&yl_9200_button_device);
+static void __init yl9200_add_device_ts(void)
+{
+ at91_set_gpio_input(AT91_PIN_PB11, 1); /* Touchscreen interrupt pin */
+ at91_set_gpio_input(AT91_PIN_PB10, 1); /* Touchscreen BUSY signal - not used! */
}
#else
-static void __init yl_9200_add_device_buttons(void) {}
+static void __init yl9200_add_device_ts(void) {}
+#endif
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info yl9200_spi_devices[] = {
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ { /* Touchscreen */
+ .modalias = "ads7846",
+ .chip_select = 0,
+ .max_speed_hz = 5000 * 26,
+ .platform_data = &ads_info,
+ .irq = AT91_PIN_PB11,
+ },
#endif
+ { /* CAN */
+ .modalias = "mcp2510",
+ .chip_select = 1,
+ .max_speed_hz = 25000 * 26,
+ .irq = AT91_PIN_PC0,
+ }
+};
+/*
+ * LCD / VGA
+ *
+ * EPSON S1D13806 FB (discontinued chip)
+ * EPSON S1D13506 FB
+ */
#if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
#include <video/s1d13xxxfb.h>
-/* EPSON S1D13806 FB (discontinued chip)*/
-/* EPSON S1D13506 FB */
-
#define AT91_FB_REG_BASE 0x80000000L
#define AT91_FB_REG_SIZE 0x200
#define AT91_FB_VMEM_BASE 0x80200000L
#define AT91_FB_VMEM_SIZE 0x200000L
-/*#define S1D_DISPLAY_WIDTH 640*/
-/*#define S1D_DISPLAY_HEIGHT 480*/
-
-
-static void __init yl_9200_init_video(void)
+static void __init yl9200_init_video(void)
{
- at91_sys_write(AT91_PIOC + PIO_ASR,AT91_PIN_PC6);
- at91_sys_write(AT91_PIOC + PIO_BSR,0);
- at91_sys_write(AT91_PIOC + PIO_ASR,AT91_PIN_PC6);
-
- at91_sys_write( AT91_SMC_CSR(2),
- AT91_SMC_NWS_(0x4) |
- AT91_SMC_WSEN |
- AT91_SMC_TDF_(0x100) |
- AT91_SMC_DBW
- );
-
-
+ /* NWAIT Signal */
+ at91_set_A_periph(AT91_PIN_PC6, 0);
+ /* Initialization of the Static Memory Controller for Chip Select 2 */
+ at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */
+ | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */
+ | AT91_SMC_TDF_(0x100) /* float time */
+ );
}
-
-static struct s1d13xxxfb_regval yl_9200_s1dfb_initregs[] =
+static struct s1d13xxxfb_regval yl9200_s1dfb_initregs[] =
{
- {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/
- {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
- {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/
- {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/
- {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/
- {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/
- {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/
- {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/
- {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/
- {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/
- {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/
- {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/
- {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/
- {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/
- {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/
- {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/
- {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/
- {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/
- {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/
- {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/
- {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/
- {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/
- {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/
- {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/
- {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/
- {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/
- {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/
- {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/
- {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/
- {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/
- {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/
- {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/
- {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/
- {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/
- {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/
- {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/
- {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/
- {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/
- {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/
- {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/
- {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/
- {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/
- {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/
- {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */
- {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/
- {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/
- {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/
- {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/
- {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/
- {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/
- {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/
- {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/
- {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/
- {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/
- {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/
- {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/
- {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/
- {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/
- {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/
- {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/
- {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/
- {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/
- {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/
- {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/
- {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/
- {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/
- {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/
- {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/
- {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/
- {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/
- {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/
- {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/
- {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/
- {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/
- {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/
- {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/
- {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/
- {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/
- {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/
- {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/
- {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/
- {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/
- {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/
- {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/
- {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/
- {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/
- {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/
- {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/
- {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/
- {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/
- {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/
- {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/
- {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/
- {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/
- {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/
- {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/
- {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/
- {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/
- {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/
- {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/
- {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/
- {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/
- {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/
- {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/
- {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+ {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+ {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/
+ {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/
+ {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/
+ {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/
+ {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/
+ {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/
+ {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/
+ {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/
+ {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/
+ {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/
+ {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/
+ {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/
+ {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/
+ {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/
+ {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/
+ {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/
+ {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/
+ {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/
+ {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/
+ {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/
+ {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/
+ {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/
+ {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/
+ {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/
+ {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/
+ {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/
+ {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/
+ {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/
+ {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/
+ {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/
+ {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/
+ {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/
+ {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/
+ {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/
+ {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/
+ {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/
+ {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/
+ {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/
+ {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/
+ {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/
+ {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/
+ {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */
+ {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/
+ {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/
+ {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/
+ {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/
+ {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/
+ {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/
+ {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/
+ {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/
+ {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/
+ {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/
+ {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/
+ {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/
+ {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/
+ {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/
+ {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/
+ {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/
+ {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/
+ {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/
+ {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/
+ {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/
+ {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/
+ {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/
+ {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/
+ {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/
+ {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/
+ {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/
+ {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/
+ {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/
+ {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/
+ {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/
+ {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/
+ {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/
+ {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/
+ {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/
+ {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/
+ {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/
+ {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/
+ {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/
+ {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/
+ {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/
+ {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/
+ {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/
+ {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/
+ {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/
+ {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/
+ {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/
+ {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/
+ {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/
+ {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/
+ {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/
+ {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/
+ {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/
+ {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/
+ {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
};
-static u64 s1dfb_dmamask = 0xffffffffUL;
+static u64 s1dfb_dmamask = DMA_BIT_MASK(32);
-static struct s1d13xxxfb_pdata yl_9200_s1dfb_pdata = {
- .initregs = yl_9200_s1dfb_initregs,
- .initregssize = ARRAY_SIZE(yl_9200_s1dfb_initregs),
- .platform_init_video = yl_9200_init_video,
+static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = {
+ .initregs = yl9200_s1dfb_initregs,
+ .initregssize = ARRAY_SIZE(yl9200_s1dfb_initregs),
+ .platform_init_video = yl9200_init_video,
};
-static struct resource yl_9200_s1dfb_resource[] = {
+static struct resource yl9200_s1dfb_resource[] = {
[0] = { /* video mem */
- .name = "s1d13xxxfb memory",
- /* .name = "s1d13806 memory",*/
- .start = AT91_FB_VMEM_BASE,
- .end = AT91_FB_VMEM_BASE + AT91_FB_VMEM_SIZE -1,
- .flags = IORESOURCE_MEM,
+ .name = "s1d13xxxfb memory",
+ .start = AT91_FB_VMEM_BASE,
+ .end = AT91_FB_VMEM_BASE + AT91_FB_VMEM_SIZE -1,
+ .flags = IORESOURCE_MEM,
},
[1] = { /* video registers */
- .name = "s1d13xxxfb registers",
- /* .name = "s1d13806 registers",*/
- .start = AT91_FB_REG_BASE,
- .end = AT91_FB_REG_BASE + AT91_FB_REG_SIZE -1,
- .flags = IORESOURCE_MEM,
+ .name = "s1d13xxxfb registers",
+ .start = AT91_FB_REG_BASE,
+ .end = AT91_FB_REG_BASE + AT91_FB_REG_SIZE -1,
+ .flags = IORESOURCE_MEM,
},
};
-static struct platform_device yl_9200_s1dfb_device = {
- /*TODO S.Birtles , really we need the chip revision in here as well*/
- .name = "s1d13806fb",
- /* .name = "s1d13506fb",*/
- .id = -1,
- .dev = {
- /*TODO theres a waring here!!*/
- /*WARNING: vmlinux.o(.data+0x2dbc): Section mismatch: reference to .init.text: (between 'yl_9200_s1dfb_pdata' and 's1dfb_dmamask')*/
+static struct platform_device yl9200_s1dfb_device = {
+ .name = "s1d13806fb",
+ .id = -1,
+ .dev = {
.dma_mask = &s1dfb_dmamask,
- .coherent_dma_mask = 0xffffffff,
- .platform_data = &yl_9200_s1dfb_pdata,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &yl9200_s1dfb_pdata,
},
- .resource = yl_9200_s1dfb_resource,
- .num_resources = ARRAY_SIZE(yl_9200_s1dfb_resource),
+ .resource = yl9200_s1dfb_resource,
+ .num_resources = ARRAY_SIZE(yl9200_s1dfb_resource),
};
-void __init yl_9200_add_device_video(void)
+void __init yl9200_add_device_video(void)
{
- platform_device_register(&yl_9200_s1dfb_device);
+ platform_device_register(&yl9200_s1dfb_device);
}
#else
- void __init yl_9200_add_device_video(void) {}
+void __init yl9200_add_device_video(void) {}
#endif
-/*this is not called first , yl_9200_map_io is called first*/
-static void __init yl_9200_board_init(void)
+
+static void __init yl9200_board_init(void)
{
/* Serial */
at91_add_device_serial();
/* Ethernet */
- at91_add_device_eth(&yl_9200_eth_data);
+ at91_add_device_eth(&yl9200_eth_data);
/* USB Host */
- at91_add_device_usbh(&yl_9200_usbh_data);
+ at91_add_device_usbh(&yl9200_usbh_data);
/* USB Device */
- at91_add_device_udc(&yl_9200_udc_data);
- /* pullup_pin it is actually active low, but this is not needed, driver sets it up */
- /*at91_set_multi_drive(yl_9200_udc_data.pullup_pin, 0);*/
-
- /* Compact Flash */
- /*at91_add_device_cf(&yl_9200_cf_data);*/
-
+ at91_add_device_udc(&yl9200_udc_data);
/* I2C */
- at91_add_device_i2c(yl_9200_i2c_devices, ARRAY_SIZE(yl_9200_i2c_devices));
- /* SPI */
- /*TODO YL9200 we have 2 spi interfaces touch screen & CAN*/
- /* AT91_PIN_PA5, AT91_PIN_PA6 , are used on the max 485 NOT SPI*/
-
- /*touch screen and CAN*/
- at91_add_device_spi(yl_9200_spi_devices, ARRAY_SIZE(yl_9200_spi_devices));
-
- /*Basically the TS uses PB11 & PB10 , PB11 is configured by the SPI system BP10 IS NOT USED!!*/
- /* we need this incase the board is running without a touch screen*/
- #if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
- at91_init_device_ts(); /*init the touch screen device*/
- #endif
- /* DataFlash card */
- at91_add_device_mmc(0, &yl_9200_mmc_data);
+ at91_add_device_i2c(yl9200_i2c_devices, ARRAY_SIZE(yl9200_i2c_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &yl9200_mmc_data);
/* NAND */
- at91_add_device_nand(&yl_9200_nand_data);
+ at91_add_device_nand(&yl9200_nand_data);
/* NOR Flash */
- platform_device_register(&yl_9200_flash);
- /* LEDs. Note!! this does not include the led's we passed for the processor status */
- at91_gpio_leds(yl_9200_leds, ARRAY_SIZE(yl_9200_leds));
- /* VGA */
- /*this is self registered by including the s1d13xxx chip in the kernel build*/
- yl_9200_add_device_video();
+ platform_device_register(&yl9200_flash);
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+ /* SPI */
+ at91_add_device_spi(yl9200_spi_devices, ARRAY_SIZE(yl9200_spi_devices));
+ /* Touchscreen */
+ yl9200_add_device_ts();
+#endif
+ /* LEDs. */
+ at91_gpio_leds(yl9200_leds, ARRAY_SIZE(yl9200_leds));
/* Push Buttons */
- yl_9200_add_device_buttons();
- /*TODO fixup the Sounder */
-// yl_9200_add_device_sounder(yl_9200_sounder,ARRAY_SIZE(yl_9200_sounder));
-
+ yl9200_add_device_buttons();
+ /* VGA */
+ yl9200_add_device_video();
}
MACHINE_START(YL9200, "uCdragon YL-9200")
- /* Maintainer: S.Birtles*/
- .phys_io = AT91_BASE_SYS,
+ /* Maintainer: S.Birtles */
+ .phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
- .timer = &at91rm9200_timer,
- .map_io = yl_9200_map_io,
- .init_irq = yl_9200_init_irq,
- .init_machine = yl_9200_board_init,
+ .timer = &at91rm9200_timer,
+ .map_io = yl9200_map_io,
+ .init_irq = yl9200_init_irq,
+ .init_machine = yl9200_board_init,
MACHINE_END
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index a33dfe45072..464bdbbf74d 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -112,12 +112,34 @@ static void pmc_sys_mode(struct clk *clk, int is_on)
at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
}
+static void pmc_uckr_mode(struct clk *clk, int is_on)
+{
+ unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
+
+ if (is_on) {
+ is_on = AT91_PMC_LOCKU;
+ at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
+ } else
+ at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
+
+ do {
+ cpu_relax();
+ } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
+}
+
/* USB function clocks (PLLB must be 48 MHz) */
static struct clk udpck = {
.name = "udpck",
.parent = &pllb,
.mode = pmc_sys_mode,
};
+static struct clk utmi_clk = {
+ .name = "utmi_clk",
+ .parent = &main_clk,
+ .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */
+ .mode = pmc_uckr_mode,
+ .type = CLK_TYPE_PLL,
+};
static struct clk uhpck = {
.name = "uhpck",
.parent = &pllb,
@@ -361,7 +383,7 @@ static void __init init_programmable_clock(struct clk *clk)
static int at91_clk_show(struct seq_file *s, void *unused)
{
- u32 scsr, pcsr, sr;
+ u32 scsr, pcsr, uckr = 0, sr;
struct clk *clk;
seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
@@ -369,7 +391,10 @@ static int at91_clk_show(struct seq_file *s, void *unused)
seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR));
seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
- seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+ if (!cpu_is_at91sam9rl())
+ seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+ if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
+ seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
@@ -382,6 +407,8 @@ static int at91_clk_show(struct seq_file *s, void *unused)
state = (scsr & clk->pmc_mask) ? "on" : "off";
else if (clk->mode == pmc_periph_mode)
state = (pcsr & clk->pmc_mask) ? "on" : "off";
+ else if (clk->mode == pmc_uckr_mode)
+ state = (uckr & clk->pmc_mask) ? "on" : "off";
else if (clk->pmc_mask)
state = (sr & clk->pmc_mask) ? "on" : "off";
else if (clk == &clk32k || clk == &main_clk)
@@ -488,14 +515,19 @@ static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq)
/*
* PLL input between 1MHz and 32MHz per spec, but lower
* frequences seem necessary in some cases so allow 100K.
+ * Warning: some newer products need 2MHz min.
*/
input = main_freq / i;
+ if (cpu_is_at91sam9g20() && input < 2000000)
+ continue;
if (input < 100000)
continue;
if (input > 32000000)
continue;
mul1 = out_freq / input;
+ if (cpu_is_at91sam9g20() && mul > 63)
+ continue;
if (mul1 > 2048)
continue;
if (mul1 < 2)
@@ -555,7 +587,8 @@ int __init at91_clock_init(unsigned long main_clock)
/* report if PLLA is more than mildly overclocked */
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
- if (plla.rate_hz > 209000000)
+ if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000)
+ || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000))
pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
/*
@@ -570,7 +603,7 @@ int __init at91_clock_init(unsigned long main_clock)
uhpck.pmc_mask = AT91RM9200_PMC_UHP;
udpck.pmc_mask = AT91RM9200_PMC_UDP;
at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
- } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
+ } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
} else if (cpu_is_at91cap9()) {
@@ -582,6 +615,17 @@ int __init at91_clock_init(unsigned long main_clock)
uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
/*
+ * USB HS clock init
+ */
+ if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) {
+ /*
+ * multiplier is hard-wired to 40
+ * (obtain the USB High Speed 480 MHz when input is 12 MHz)
+ */
+ utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+ }
+
+ /*
* MCK and CPU derive from one of those primary clocks.
* For now, assume this parentage won't change.
*/
@@ -591,13 +635,21 @@ int __init at91_clock_init(unsigned long main_clock)
freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
if (cpu_is_at91rm9200())
mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
- else
- mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ else if (cpu_is_at91sam9g20()) {
+ mck.rate_hz = (mckr & AT91_PMC_MDIV) ?
+ freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
+ if (mckr & AT91_PMC_PDIV)
+ freq /= 2; /* processor clock division */
+ } else
+ mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
/* Register the PMC's standard clocks */
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
+ if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
+ list_add_tail(&utmi_clk.node, &clocks);
+
/* MCK and CPU clock are "always on" */
clk_enable(&mck);
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index aa863c15770..8ab4feb1ec5 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -202,7 +202,7 @@ static int at91_pm_verify_clocks(void)
pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
- } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
+ } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 9d7515c36bf..f62c35500bb 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -74,6 +74,7 @@ struct clk *clk_get(struct device *dev, const char *id)
return ERR_PTR(-ENOENT);
}
+EXPORT_SYMBOL(clk_get);
int clk_enable(struct clk *clk)
{
@@ -86,6 +87,7 @@ int clk_enable(struct clk *clk)
return 0;
}
+EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
@@ -96,15 +98,18 @@ void clk_disable(struct clk *clk)
__raw_writel(value & ~clk->enable_mask, clk->enable_reg);
}
}
+EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
+EXPORT_SYMBOL(clk_get_rate);
void clk_put(struct clk *clk)
{
}
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
index 0694ad6b647..32f8609e4f8 100644
--- a/arch/arm/mach-footbridge/Makefile
+++ b/arch/arm/mach-footbridge/Makefile
@@ -14,12 +14,10 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
-leds-$(CONFIG_ARCH_CO285) += ebsa285-leds.o
leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
-obj-$(CONFIG_ARCH_CO285) += co285.o dc21285-timer.o
obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c
deleted file mode 100644
index 4545576ad8d..00000000000
--- a/arch/arm/mach-footbridge/co285.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * linux/arch/arm/mach-footbridge/co285.c
- *
- * CO285 machine fixup
- */
-#include <linux/init.h>
-
-#include <asm/hardware/dec21285.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-
-static void __init
-fixup_coebsa285(struct machine_desc *desc, struct tag *tags,
- char **cmdline, struct meminfo *mi)
-{
- extern unsigned long boot_memory_end;
- extern char boot_command_line[];
-
- mi->nr_banks = 1;
- mi->bank[0].start = PHYS_OFFSET;
- mi->bank[0].size = boot_memory_end;
- mi->bank[0].node = 0;
-
- *cmdline = boot_command_line;
-}
-
-MACHINE_START(CO285, "co-EBSA285")
- /* Maintainer: Mark van Doesburg */
- .phys_io = DC21285_ARMCSR_BASE,
- .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc,
- .fixup = fixup_coebsa285,
- .map_io = footbridge_map_io,
- .init_irq = footbridge_init_irq,
- .timer = &footbridge_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index ef29fc34ce6..b08ab507c05 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -177,25 +177,6 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
#endif
};
-/*
- * The CO-ebsa285 mapping.
- */
-static struct map_desc co285_io_desc[] __initdata = {
-#ifdef CONFIG_ARCH_CO285
- {
- .virtual = PCIO_BASE,
- .pfn = __phys_to_pfn(DC21285_PCI_IO),
- .length = PCIO_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = PCIMEM_BASE,
- .pfn = __phys_to_pfn(DC21285_PCI_MEM),
- .length = PCIMEM_SIZE,
- .type = MT_DEVICE,
- },
-#endif
-};
-
void __init footbridge_map_io(void)
{
/*
@@ -208,8 +189,6 @@ void __init footbridge_map_io(void)
* Now, work out what we've got to map in addition on this
* platform.
*/
- if (machine_is_co285())
- iotable_init(co285_io_desc, ARRAY_SIZE(co285_io_desc));
if (footbridge_cfn_mode())
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
}
diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c
index a64e2222651..09c1fbc5187 100644
--- a/arch/arm/mach-footbridge/ebsa285-leds.c
+++ b/arch/arm/mach-footbridge/ebsa285-leds.c
@@ -128,7 +128,7 @@ static void ebsa285_leds_event(led_event_t evt)
static int __init leds_init(void)
{
- if (machine_is_ebsa285() || machine_is_co285())
+ if (machine_is_ebsa285())
leds_event = ebsa285_leds_event;
leds_event(led_start);
diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c
index 5d02e95dede..d5cfcda385d 100644
--- a/arch/arm/mach-footbridge/time.c
+++ b/arch/arm/mach-footbridge/time.c
@@ -115,8 +115,7 @@ static int set_isa_cmos_time(void)
void __init isa_rtc_init(void)
{
- if (machine_is_co285() ||
- machine_is_personal_server())
+ if (machine_is_personal_server())
/*
* Add-in 21285s shouldn't access the RTC
*/
diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c
index a59ff2987cb..ee1c6f06ff6 100644
--- a/arch/arm/mach-imx/dma.c
+++ b/arch/arm/mach-imx/dma.c
@@ -410,7 +410,6 @@ void imx_dma_free(imx_dmach_t dma_ch)
/**
* imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
- * @dma_ch: i.MX DMA channel number
* @name: the driver/caller own non-%NULL identification
* @prio: one of the hardware distinguished priority level:
* %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW
@@ -420,11 +419,9 @@ void imx_dma_free(imx_dmach_t dma_ch)
* in the higher and then even lower priority groups.
*
* Return value: If there is no free channel to allocate, -%ENODEV is returned.
- * Zero value indicates successful channel allocation.
+ * On successful allocation channel is returned.
*/
-int
-imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
- imx_dma_prio prio)
+imx_dmach_t imx_dma_request_by_prio(const char *name, imx_dma_prio prio)
{
int i;
int best;
@@ -444,15 +441,13 @@ imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
for (i = best; i < IMX_DMA_CHANNELS; i++) {
if (!imx_dma_request(i, name)) {
- *pdma_ch = i;
- return 0;
+ return i;
}
}
for (i = best - 1; i >= 0; i--) {
if (!imx_dma_request(i, name)) {
- *pdma_ch = i;
- return 0;
+ return i;
}
}
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
index 158daaf9e3b..6a5ef8d30b1 100644
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := clock.o core.o lm.o time.o
+obj-y := clock.o core.o lm.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
deleted file mode 100644
index 8508a0db3ea..00000000000
--- a/arch/arm/mach-integrator/time.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * linux/arch/arm/mach-integrator/time.c
- *
- * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/mc146818rtc.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/rtc.h>
-
-#include <asm/mach/time.h>
-
-#define RTC_DR (0)
-#define RTC_MR (4)
-#define RTC_STAT (8)
-#define RTC_EOI (8)
-#define RTC_LR (12)
-#define RTC_CR (16)
-#define RTC_CR_MIE (1 << 0)
-
-extern int (*set_rtc)(void);
-static void __iomem *rtc_base;
-
-static int integrator_set_rtc(void)
-{
- __raw_writel(xtime.tv_sec, rtc_base + RTC_LR);
- return 1;
-}
-
-static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm)
-{
- rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
- return 0;
-}
-
-static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm)
-{
- unsigned long time;
- int ret;
-
- /*
- * At the moment, we can only deal with non-wildcarded alarm times.
- */
- ret = rtc_valid_tm(&alrm->time);
- if (ret == 0)
- ret = rtc_tm_to_time(&alrm->time, &time);
- if (ret == 0)
- writel(time, rtc_base + RTC_MR);
- return ret;
-}
-
-static int integrator_rtc_read_time(struct rtc_time *tm)
-{
- rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
- return 0;
-}
-
-/*
- * Set the RTC time. Unfortunately, we can't accurately set
- * the point at which the counter updates.
- *
- * Also, since RTC_LR is transferred to RTC_CR on next rising
- * edge of the 1Hz clock, we must write the time one second
- * in advance.
- */
-static inline int integrator_rtc_set_time(struct rtc_time *tm)
-{
- unsigned long time;
- int ret;
-
- ret = rtc_tm_to_time(tm, &time);
- if (ret == 0)
- writel(time + 1, rtc_base + RTC_LR);
-
- return ret;
-}
-
-static struct rtc_ops rtc_ops = {
- .owner = THIS_MODULE,
- .read_time = integrator_rtc_read_time,
- .set_time = integrator_rtc_set_time,
- .read_alarm = integrator_rtc_read_alarm,
- .set_alarm = integrator_rtc_set_alarm,
-};
-
-static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id)
-{
- writel(0, rtc_base + RTC_EOI);
- return IRQ_HANDLED;
-}
-
-static int rtc_probe(struct amba_device *dev, void *id)
-{
- int ret;
-
- if (rtc_base)
- return -EBUSY;
-
- ret = amba_request_regions(dev, NULL);
- if (ret)
- goto out;
-
- rtc_base = ioremap(dev->res.start, SZ_4K);
- if (!rtc_base) {
- ret = -ENOMEM;
- goto res_out;
- }
-
- __raw_writel(0, rtc_base + RTC_CR);
- __raw_writel(0, rtc_base + RTC_EOI);
-
- xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);
-
- /* note that 'dev' is merely used for irq disambiguation;
- * it is not actually referenced in the irq handler
- */
- ret = request_irq(dev->irq[0], arm_rtc_interrupt, IRQF_DISABLED,
- "rtc-pl030", dev);
- if (ret)
- goto map_out;
-
- ret = register_rtc(&rtc_ops);
- if (ret)
- goto irq_out;
-
- set_rtc = integrator_set_rtc;
- return 0;
-
- irq_out:
- free_irq(dev->irq[0], dev);
- map_out:
- iounmap(rtc_base);
- rtc_base = NULL;
- res_out:
- amba_release_regions(dev);
- out:
- return ret;
-}
-
-static int rtc_remove(struct amba_device *dev)
-{
- set_rtc = NULL;
-
- writel(0, rtc_base + RTC_CR);
-
- free_irq(dev->irq[0], dev);
- unregister_rtc(&rtc_ops);
-
- iounmap(rtc_base);
- rtc_base = NULL;
- amba_release_regions(dev);
-
- return 0;
-}
-
-static struct timespec rtc_delta;
-
-static int rtc_suspend(struct amba_device *dev, pm_message_t state)
-{
- struct timespec rtc;
-
- rtc.tv_sec = readl(rtc_base + RTC_DR);
- rtc.tv_nsec = 0;
- save_time_delta(&rtc_delta, &rtc);
-
- return 0;
-}
-
-static int rtc_resume(struct amba_device *dev)
-{
- struct timespec rtc;
-
- rtc.tv_sec = readl(rtc_base + RTC_DR);
- rtc.tv_nsec = 0;
- restore_time_delta(&rtc_delta, &rtc);
-
- return 0;
-}
-
-static struct amba_id rtc_ids[] = {
- {
- .id = 0x00041030,
- .mask = 0x000fffff,
- },
- { 0, 0 },
-};
-
-static struct amba_driver rtc_driver = {
- .drv = {
- .name = "rtc-pl030",
- },
- .probe = rtc_probe,
- .remove = rtc_remove,
- .suspend = rtc_suspend,
- .resume = rtc_resume,
- .id_table = rtc_ids,
-};
-
-static int __init integrator_rtc_init(void)
-{
- return amba_driver_register(&rtc_driver);
-}
-
-static void __exit integrator_rtc_exit(void)
-{
- amba_driver_unregister(&rtc_driver);
-}
-
-module_init(integrator_rtc_init);
-module_exit(integrator_rtc_exit);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index e774447c059..db8b5fe06c0 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -125,6 +125,15 @@ config ARCH_IXDP4XX
depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
default y
+config MACH_FSG
+ bool
+ prompt "Freecom FSG-3"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Freecom's
+ FSG-3 device. For more information on this platform,
+ see http://www.nslu2-linux.org/wiki/FSG3/HomePage
+
#
# Certain registers and IRQs are only enabled if supporting IXP465 CPUs
#
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index c1956882c48..2e6bbf927a7 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -15,6 +15,7 @@ obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o
+obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o
obj-y += common.o
@@ -28,6 +29,7 @@ obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o
obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o
obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
+obj-$(CONFIG_MACH_FSG) += fsg-setup.o
obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c
new file mode 100644
index 00000000000..f19f3f6feda
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-pci.c
@@ -0,0 +1,71 @@
+/*
+ * arch/arch/mach-ixp4xx/fsg-pci.c
+ *
+ * FSG board-level PCI initialization
+ *
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init fsg_pci_preinit(void)
+{
+ set_irq_type(IRQ_FSG_PCI_INTA, IRQT_LOW);
+ set_irq_type(IRQ_FSG_PCI_INTB, IRQT_LOW);
+ set_irq_type(IRQ_FSG_PCI_INTC, IRQT_LOW);
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[FSG_PCI_IRQ_LINES] = {
+ IRQ_FSG_PCI_INTC,
+ IRQ_FSG_PCI_INTB,
+ IRQ_FSG_PCI_INTA,
+ };
+
+ int irq = -1;
+ slot = slot - 11;
+
+ if (slot >= 1 && slot <= FSG_PCI_MAX_DEV &&
+ pin >= 1 && pin <= FSG_PCI_IRQ_LINES)
+ irq = pci_irq_table[(slot - 1)];
+ printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
+ __func__, slot, pin, irq);
+
+ return irq;
+}
+
+struct hw_pci fsg_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = fsg_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = fsg_map_irq,
+};
+
+int __init fsg_pci_init(void)
+{
+ if (machine_is_fsg())
+ pci_common_init(&fsg_pci);
+ return 0;
+}
+
+subsys_initcall(fsg_pci_init);
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
new file mode 100644
index 00000000000..0db3a909ae6
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -0,0 +1,276 @@
+/*
+ * arch/arm/mach-ixp4xx/fsg-setup.c
+ *
+ * FSG board-setup
+ *
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ *
+ * based on ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * based on nslu2-power.c
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/if_ether.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/reboot.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+static struct flash_platform_data fsg_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource fsg_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device fsg_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsg_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &fsg_flash_resource,
+};
+
+static struct i2c_gpio_platform_data fsg_i2c_gpio_data = {
+ .sda_pin = FSG_SDA_PIN,
+ .scl_pin = FSG_SCL_PIN,
+};
+
+static struct platform_device fsg_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsg_i2c_gpio_data,
+ },
+};
+
+static struct i2c_board_info __initdata fsg_i2c_board_info [] = {
+ {
+ I2C_BOARD_INFO("rtc-isl1208", 0x6f),
+ },
+};
+
+static struct resource fsg_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port fsg_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device fsg_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = fsg_uart_data,
+ },
+ .num_resources = ARRAY_SIZE(fsg_uart_resources),
+ .resource = fsg_uart_resources,
+};
+
+static struct platform_device fsg_leds = {
+ .name = "fsg-led",
+ .id = -1,
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info fsg_plat_eth[] = {
+ {
+ .phy = 5,
+ .rxq = 3,
+ .txreadyq = 20,
+ }, {
+ .phy = 4,
+ .rxq = 4,
+ .txreadyq = 21,
+ }
+};
+
+static struct platform_device fsg_eth[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev = {
+ .platform_data = fsg_plat_eth,
+ },
+ }, {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEC,
+ .dev = {
+ .platform_data = fsg_plat_eth + 1,
+ },
+ }
+};
+
+static struct platform_device *fsg_devices[] __initdata = {
+ &fsg_i2c_gpio,
+ &fsg_flash,
+ &fsg_leds,
+ &fsg_eth[0],
+ &fsg_eth[1],
+};
+
+static irqreturn_t fsg_power_handler(int irq, void *dev_id)
+{
+ /* Signal init to do the ctrlaltdel action, this will bypass init if
+ * it hasn't started and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fsg_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset which does an emergency reboot. */
+ printk(KERN_INFO "Restarting system.\n");
+ machine_restart(NULL);
+
+ /* This should never be reached. */
+ return IRQ_HANDLED;
+}
+
+static void __init fsg_init(void)
+{
+ DECLARE_MAC_BUF(mac_buf);
+ uint8_t __iomem *f;
+ int i;
+
+ ixp4xx_sys_init();
+
+ fsg_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ fsg_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ /* Configure CS2 for operation, 8bit and writable */
+ *IXP4XX_EXP_CS2 = 0xbfff0002;
+
+ i2c_register_board_info(0, fsg_i2c_board_info,
+ ARRAY_SIZE(fsg_i2c_board_info));
+
+ /* This is only useful on a modified machine, but it is valuable
+ * to have it first in order to see debug messages, and so that
+ * it does *not* get removed if platform_add_devices fails!
+ */
+ (void)platform_device_register(&fsg_uart);
+
+ platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices));
+
+ if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "FSG reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(FSG_RB_GPIO));
+ }
+
+ if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "FSG power button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Power Button IRQ %d not available\n",
+ gpio_to_irq(FSG_SB_GPIO));
+ }
+
+ /*
+ * Map in a portion of the flash and read the MAC addresses.
+ * Since it is stored in BE in the flash itself, we need to
+ * byteswap it if we're in LE mode.
+ */
+ f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000);
+ if (f) {
+#ifdef __ARMEB__
+ for (i = 0; i < 6; i++) {
+ fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i);
+ fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i);
+ }
+#else
+
+ /*
+ Endian-swapped reads from unaligned addresses are
+ required to extract the two MACs from the big-endian
+ Redboot config area in flash.
+ */
+
+ fsg_plat_eth[0].hwaddr[0] = readb(f + 0x3C0421);
+ fsg_plat_eth[0].hwaddr[1] = readb(f + 0x3C0420);
+ fsg_plat_eth[0].hwaddr[2] = readb(f + 0x3C0427);
+ fsg_plat_eth[0].hwaddr[3] = readb(f + 0x3C0426);
+ fsg_plat_eth[0].hwaddr[4] = readb(f + 0x3C0425);
+ fsg_plat_eth[0].hwaddr[5] = readb(f + 0x3C0424);
+
+ fsg_plat_eth[1].hwaddr[0] = readb(f + 0x3C0439);
+ fsg_plat_eth[1].hwaddr[1] = readb(f + 0x3C043F);
+ fsg_plat_eth[1].hwaddr[2] = readb(f + 0x3C043E);
+ fsg_plat_eth[1].hwaddr[3] = readb(f + 0x3C043D);
+ fsg_plat_eth[1].hwaddr[4] = readb(f + 0x3C043C);
+ fsg_plat_eth[1].hwaddr[5] = readb(f + 0x3C0443);
+#endif
+ iounmap(f);
+ }
+ printk(KERN_INFO "FSG: Using MAC address %s for port 0\n",
+ print_mac(mac_buf, fsg_plat_eth[0].hwaddr));
+ printk(KERN_INFO "FSG: Using MAC address %s for port 1\n",
+ print_mac(mac_buf, fsg_plat_eth[1].hwaddr));
+
+}
+
+MACHINE_START(FSG, "Freecom FSG-3")
+ /* Maintainer: www.nslu2-linux.org */
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = fsg_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index c06f5254c0f..1bda8f5d754 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,9 @@
#
# Common support
-obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
+obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
+
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index bcb984f2300..3f39e0e79c9 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/clk.h>
@@ -202,7 +203,7 @@ static struct omap_board_config_kernel nokia770_config[] __initdata = {
#define AMPLIFIER_CTRL_GPIO 58
static struct clk *dspxor_ck;
-static DECLARE_MUTEX(audio_pwr_sem);
+static DEFINE_MUTEX(audio_pwr_lock);
/*
* audio_pwr_state
* +--+-------------------------+---------------------------------------+
@@ -218,7 +219,7 @@ static DECLARE_MUTEX(audio_pwr_sem);
static int audio_pwr_state = -1;
/*
- * audio_pwr_up / down should be called under audio_pwr_sem
+ * audio_pwr_up / down should be called under audio_pwr_lock
*/
static void nokia770_audio_pwr_up(void)
{
@@ -237,11 +238,11 @@ static void nokia770_audio_pwr_up(void)
static void codec_delayed_power_down(struct work_struct *work)
{
- down(&audio_pwr_sem);
+ mutex_lock(&audio_pwr_lock);
if (audio_pwr_state == -1)
aic23_power_down();
clk_disable(dspxor_ck);
- up(&audio_pwr_sem);
+ mutex_unlock(&audio_pwr_lock);
}
static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down);
@@ -258,19 +259,19 @@ static void nokia770_audio_pwr_down(void)
static int
nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage)
{
- down(&audio_pwr_sem);
+ mutex_lock(&audio_pwr_lock);
if (audio_pwr_state == -1)
nokia770_audio_pwr_up();
/* force audio_pwr_state = 0, even if it was 1. */
audio_pwr_state = 0;
- up(&audio_pwr_sem);
+ mutex_unlock(&audio_pwr_lock);
return 0;
}
static int
nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
{
- down(&audio_pwr_sem);
+ mutex_lock(&audio_pwr_lock);
switch (stage) {
case 1:
if (audio_pwr_state == 0)
@@ -283,7 +284,7 @@ nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
}
break;
}
- up(&audio_pwr_sem);
+ mutex_unlock(&audio_pwr_lock);
return 0;
}
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index a66505f58b1..845c66371ca 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -267,13 +267,17 @@ static struct i2c_board_info __initdata osk_i2c_board_info[] = {
static void __init osk_init_smc91x(void)
{
+ u32 l;
+
if ((gpio_request(0, "smc_irq")) < 0) {
printk("Error requesting gpio 0 for smc91x irq\n");
return;
}
/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
- EMIFS_CCS(1) |= 0x3;
+ l = omap_readl(EMIFS_CCS(1));
+ l |= 0x3;
+ omap_writel(l, EMIFS_CCS(1));
}
static void __init osk_init_cf(void)
@@ -526,20 +530,26 @@ static void __init osk_mistral_init(void) { }
static void __init osk_init(void)
{
+ u32 l;
+
/* Workaround for wrong CS3 (NOR flash) timing
* There are some U-Boot versions out there which configure
* wrong CS3 memory timings. This mainly leads to CRC
* or similar errors if you use NOR flash (e.g. with JFFS2)
*/
- if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
- EMIFS_CCS(3) = EMIFS_CS3_VAL;
+ l = omap_readl(EMIFS_CCS(3));
+ if (l != EMIFS_CS3_VAL)
+ omap_writel(EMIFS_CS3_VAL, EMIFS_CCS(3));
osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
osk_flash_resource.end += SZ_32M - 1;
platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
omap_board_config = osk_config;
omap_board_config_size = ARRAY_SIZE(osk_config);
- USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= (3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
/* irq for tps65010 chip */
/* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 30e18810904..0cf62ef5ecb 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -32,7 +32,7 @@
static void fpga_mask_irq(unsigned int irq)
{
- irq -= OMAP1510_IH_FPGA_BASE;
+ irq -= OMAP_FPGA_IRQ_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
@@ -65,7 +65,7 @@ static void fpga_ack_irq(unsigned int irq)
static void fpga_unmask_irq(unsigned int irq)
{
- irq -= OMAP1510_IH_FPGA_BASE;
+ irq -= OMAP_FPGA_IRQ_BASE;
if (irq < 8)
__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
@@ -95,8 +95,8 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
if (!stat)
return;
- for (fpga_irq = OMAP1510_IH_FPGA_BASE;
- (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
+ for (fpga_irq = OMAP_FPGA_IRQ_BASE;
+ (fpga_irq < OMAP_FPGA_IRQ_END) && stat;
fpga_irq++, stat >>= 1) {
if (stat & 1) {
d = irq_desc + fpga_irq;
@@ -151,7 +151,7 @@ void omap1510_fpga_init_irq(void)
__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
__raw_writeb(0, INNOVATOR_FPGA_IMR2);
- for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
+ for (i = OMAP_FPGA_IRQ_BASE; i < OMAP_FPGA_IRQ_END; i++) {
if (i == OMAP1510_INT_FPGA_TS) {
/*
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
new file mode 100644
index 00000000000..2d2c2522b04
--- /dev/null
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -0,0 +1,280 @@
+/*
+ * linux/arch/arm/mach-omap1/mcbsp.c
+ *
+ * Copyright (C) 2008 Instituto Nokia de Tecnologia
+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
+ *
+ * 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.
+ *
+ * Multichannel mode not supported.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/arch/dma.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/dsp_common.h>
+
+#define DPS_RSTCT2_PER_EN (1 << 0)
+#define DSP_RSTCT2_WD_PER_EN (1 << 1)
+
+struct mcbsp_internal_clk {
+ struct clk clk;
+ struct clk **childs;
+ int n_childs;
+};
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
+{
+ const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
+ int i;
+
+ mclk->n_childs = ARRAY_SIZE(clk_names);
+ mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
+ GFP_KERNEL);
+
+ for (i = 0; i < mclk->n_childs; i++) {
+ /* We fake a platform device to get correct device id */
+ struct platform_device pdev;
+
+ pdev.dev.bus = &platform_bus_type;
+ pdev.id = mclk->clk.id;
+ mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
+ if (IS_ERR(mclk->childs[i]))
+ printk(KERN_ERR "Could not get clock %s (%d).\n",
+ clk_names[i], mclk->clk.id);
+ }
+}
+
+static int omap_mcbsp_clk_enable(struct clk *clk)
+{
+ struct mcbsp_internal_clk *mclk = container_of(clk,
+ struct mcbsp_internal_clk, clk);
+ int i;
+
+ for (i = 0; i < mclk->n_childs; i++)
+ clk_enable(mclk->childs[i]);
+ return 0;
+}
+
+static void omap_mcbsp_clk_disable(struct clk *clk)
+{
+ struct mcbsp_internal_clk *mclk = container_of(clk,
+ struct mcbsp_internal_clk, clk);
+ int i;
+
+ for (i = 0; i < mclk->n_childs; i++)
+ clk_disable(mclk->childs[i]);
+}
+
+static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 1,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 3,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+};
+
+#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks)
+#else
+#define omap_mcbsp_clks_size 0
+static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
+static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
+{ }
+#endif
+
+static int omap1_mcbsp_check(unsigned int id)
+{
+ /* REVISIT: Check correctly for number of registered McBSPs */
+ if (cpu_is_omap730()) {
+ if (id > OMAP_MAX_MCBSP_COUNT - 2) {
+ printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
+ id + 1);
+ return -ENODEV;
+ }
+ return 0;
+ }
+
+ if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+ if (id > OMAP_MAX_MCBSP_COUNT - 1) {
+ printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
+ id + 1);
+ return -ENODEV;
+ }
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static void omap1_mcbsp_request(unsigned int id)
+{
+ /*
+ * On 1510, 1610 and 1710, McBSP1 and McBSP3
+ * are DSP public peripherals.
+ */
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
+ omap_dsp_request_mem();
+ /*
+ * DSP external peripheral reset
+ * FIXME: This should be moved to dsp code
+ */
+ __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
+ DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+ }
+}
+
+static void omap1_mcbsp_free(unsigned int id)
+{
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+ omap_dsp_release_mem();
+}
+
+static struct omap_mcbsp_ops omap1_mcbsp_ops = {
+ .check = omap1_mcbsp_check,
+ .request = omap1_mcbsp_request,
+ .free = omap1_mcbsp_free,
+};
+
+#ifdef CONFIG_ARCH_OMAP730
+static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
+ {
+ .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_730_McBSP1RX,
+ .tx_irq = INT_730_McBSP1TX,
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_730_McBSP2RX,
+ .tx_irq = INT_730_McBSP2TX,
+ .ops = &omap1_mcbsp_ops,
+ },
+};
+#define OMAP730_MCBSP_PDATA_SZ ARRAY_SIZE(omap730_mcbsp_pdata)
+#else
+#define omap730_mcbsp_pdata NULL
+#define OMAP730_MCBSP_PDATA_SZ 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
+ {
+ .virt_base = OMAP1510_MCBSP1_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_McBSP1RX,
+ .tx_irq = INT_McBSP1TX,
+ .ops = &omap1_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+ .rx_irq = INT_1510_SPI_RX,
+ .tx_irq = INT_1510_SPI_TX,
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .virt_base = OMAP1510_MCBSP3_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_McBSP3RX,
+ .tx_irq = INT_McBSP3TX,
+ .ops = &omap1_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+};
+#define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata)
+#else
+#define omap15xx_mcbsp_pdata NULL
+#define OMAP15XX_MCBSP_PDATA_SZ 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
+ {
+ .virt_base = OMAP1610_MCBSP1_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+ .rx_irq = INT_McBSP1RX,
+ .tx_irq = INT_McBSP1TX,
+ .ops = &omap1_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
+ .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+ .rx_irq = INT_1610_McBSP2_RX,
+ .tx_irq = INT_1610_McBSP2_TX,
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .virt_base = OMAP1610_MCBSP3_BASE,
+ .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+ .rx_irq = INT_McBSP3RX,
+ .tx_irq = INT_McBSP3TX,
+ .ops = &omap1_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+};
+#define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata)
+#else
+#define omap16xx_mcbsp_pdata NULL
+#define OMAP16XX_MCBSP_PDATA_SZ 0
+#endif
+
+int __init omap1_mcbsp_init(void)
+{
+ int i;
+
+ for (i = 0; i < omap_mcbsp_clks_size; i++) {
+ if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+ omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
+ clk_register(&omap_mcbsp_clks[i].clk);
+ }
+ }
+
+ if (cpu_is_omap730())
+ omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
+ OMAP730_MCBSP_PDATA_SZ);
+
+ if (cpu_is_omap15xx())
+ omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata,
+ OMAP15XX_MCBSP_PDATA_SZ);
+
+ if (cpu_is_omap16xx())
+ omap_mcbsp_register_board_cfg(omap16xx_mcbsp_pdata,
+ OMAP16XX_MCBSP_PDATA_SZ);
+
+ return omap_mcbsp_init();
+}
+
+arch_initcall(omap1_mcbsp_init);
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index e6c64e10b7e..742f79e73bd 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -116,13 +116,6 @@ void omap_pm_idle(void)
return;
}
- /*
- * Since an interrupt may set up a timer, we don't want to
- * reprogram the hardware timer with interrupts enabled.
- * Re-enable interrupts only after returning from idle.
- */
- timer_dyn_reprogram();
-
#ifdef CONFIG_OMAP_MPU_TIMER
#warning Enable 32kHz OS timer in order to allow sleep states in idle
use_idlect1 = use_idlect1 & ~(1 << 9);
diff --git a/arch/arm/plat-omap/sram-fn.S b/arch/arm/mach-omap1/sram.S
index 9e1813c77e0..126d252062d 100644
--- a/arch/arm/plat-omap/sram-fn.S
+++ b/arch/arm/mach-omap1/sram.S
@@ -18,7 +18,7 @@
/*
* Reprograms ULPD and CKCTL.
*/
-ENTRY(sram_reprogram_clock)
+ENTRY(omap1_sram_reprogram_clock)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
mov r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000
@@ -53,5 +53,5 @@ lock: ldrh r4, [r2], #0 @ read back dpll value
out:
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
-ENTRY(sram_reprogram_clock_sz)
- .word . - sram_reprogram_clock
+ENTRY(omap1_sram_reprogram_clock_sz)
+ .word . - omap1_sram_reprogram_clock
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 2feb6870b73..93ee990618e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,9 +3,15 @@
#
# Common support
-obj-y := irq.o id.o io.o sram-fn.o memory.o control.o prcm.o clock.o mux.o \
+obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
devices.o serial.o gpmc.o timer-gp.o
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+
+# Functions loaded to SRAM
+obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
+obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o
+
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index ab9fc57d25f..15675bce801 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -41,6 +41,24 @@
#define MAX_CLOCK_ENABLE_WAIT 100000
+/* DPLL rate rounding: minimum DPLL multiplier, divider values */
+#define DPLL_MIN_MULTIPLIER 1
+#define DPLL_MIN_DIVIDER 1
+
+/* Possible error results from _dpll_test_mult */
+#define DPLL_MULT_UNDERFLOW (1 << 0)
+
+/*
+ * Scale factor to mitigate roundoff errors in DPLL rate rounding.
+ * The higher the scale factor, the greater the risk of arithmetic overflow,
+ * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
+ * must be a power of DPLL_SCALE_BASE.
+ */
+#define DPLL_SCALE_FACTOR 64
+#define DPLL_SCALE_BASE 2
+#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
+ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
+
u8 cpu_mask;
/*-------------------------------------------------------------------------
@@ -95,7 +113,7 @@ u32 omap2_get_dpll_rate(struct clk *clk)
{
long long dpll_clk;
u32 dpll_mult, dpll_div, dpll;
- const struct dpll_data *dd;
+ struct dpll_data *dd;
dd = clk->dpll_data;
/* REVISIT: What do we return on error? */
@@ -603,7 +621,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
clk->rate = clk->parent->rate / new_div;
if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
- __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
+ prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
+ OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
wmb();
}
@@ -723,6 +742,184 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
return 0;
}
+/* DPLL rate rounding code */
+
+/**
+ * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
+ * @clk: struct clk * of the DPLL
+ * @tolerance: maximum rate error tolerance
+ *
+ * Set the maximum DPLL rate error tolerance for the rate rounding
+ * algorithm. The rate tolerance is an attempt to balance DPLL power
+ * saving (the least divider value "n") vs. rate fidelity (the least
+ * difference between the desired DPLL target rate and the rounded
+ * rate out of the algorithm). So, increasing the tolerance is likely
+ * to decrease DPLL power consumption and increase DPLL rate error.
+ * Returns -EINVAL if provided a null clock ptr or a clk that is not a
+ * DPLL; or 0 upon success.
+ */
+int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
+{
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ clk->dpll_data->rate_tolerance = tolerance;
+
+ return 0;
+}
+
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n)
+{
+ unsigned long long num;
+
+ num = (unsigned long long)parent_rate * m;
+ do_div(num, n);
+ return num;
+}
+
+/*
+ * _dpll_test_mult - test a DPLL multiplier value
+ * @m: pointer to the DPLL m (multiplier) value under test
+ * @n: current DPLL n (divider) value under test
+ * @new_rate: pointer to storage for the resulting rounded rate
+ * @target_rate: the desired DPLL rate
+ * @parent_rate: the DPLL's parent clock rate
+ *
+ * This code tests a DPLL multiplier value, ensuring that the
+ * resulting rate will not be higher than the target_rate, and that
+ * the multiplier value itself is valid for the DPLL. Initially, the
+ * integer pointed to by the m argument should be prescaled by
+ * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
+ * a non-scaled m upon return. This non-scaled m will result in a
+ * new_rate as close as possible to target_rate (but not greater than
+ * target_rate) given the current (parent_rate, n, prescaled m)
+ * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
+ * non-scaled m attempted to underflow, which can allow the calling
+ * function to bail out early; or 0 upon success.
+ */
+static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
+ unsigned long target_rate,
+ unsigned long parent_rate)
+{
+ int flags = 0, carry = 0;
+
+ /* Unscale m and round if necessary */
+ if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
+ carry = 1;
+ *m = (*m / DPLL_SCALE_FACTOR) + carry;
+
+ /*
+ * The new rate must be <= the target rate to avoid programming
+ * a rate that is impossible for the hardware to handle
+ */
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+ if (*new_rate > target_rate) {
+ (*m)--;
+ *new_rate = 0;
+ }
+
+ /* Guard against m underflow */
+ if (*m < DPLL_MIN_MULTIPLIER) {
+ *m = DPLL_MIN_MULTIPLIER;
+ *new_rate = 0;
+ flags = DPLL_MULT_UNDERFLOW;
+ }
+
+ if (*new_rate == 0)
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+
+ return flags;
+}
+
+/**
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
+ * @clk: struct clk * for a DPLL
+ * @target_rate: desired DPLL clock rate
+ *
+ * Given a DPLL, a desired target rate, and a rate tolerance, round
+ * the target rate to a possible, programmable rate for this DPLL.
+ * Rate tolerance is assumed to be set by the caller before this
+ * function is called. Attempts to select the minimum possible n
+ * within the tolerance to reduce power consumption. Stores the
+ * computed (m, n) in the DPLL's dpll_data structure so set_rate()
+ * will not need to call this (expensive) function again. Returns ~0
+ * if the target rate cannot be rounded, either because the rate is
+ * too low or because the rate tolerance is set too tightly; or the
+ * rounded rate upon success.
+ */
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ int m, n, r, e, scaled_max_m;
+ unsigned long scaled_rt_rp, new_rate;
+ int min_e = -1, min_e_m = -1, min_e_n = -1;
+
+ if (!clk || !clk->dpll_data)
+ return ~0;
+
+ pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
+ "%ld\n", clk->name, target_rate);
+
+ scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR);
+ scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR;
+
+ clk->dpll_data->last_rounded_rate = 0;
+
+ for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
+
+ /* Compute the scaled DPLL multiplier, based on the divider */
+ m = scaled_rt_rp * n;
+
+ /*
+ * Since we're counting n down, a m overflow means we can
+ * can immediately skip to the next n
+ */
+ if (m > scaled_max_m)
+ continue;
+
+ r = _dpll_test_mult(&m, n, &new_rate, target_rate,
+ clk->parent->rate);
+
+ e = target_rate - new_rate;
+ pr_debug("clock: n = %d: m = %d: rate error is %d "
+ "(new_rate = %ld)\n", n, m, e, new_rate);
+
+ if (min_e == -1 ||
+ min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) {
+ min_e = e;
+ min_e_m = m;
+ min_e_n = n;
+
+ pr_debug("clock: found new least error %d\n", min_e);
+ }
+
+ /*
+ * Since we're counting n down, a m underflow means we
+ * can bail out completely (since as n decreases in
+ * the next iteration, there's no way that m can
+ * increase beyond the current m)
+ */
+ if (r & DPLL_MULT_UNDERFLOW)
+ break;
+ }
+
+ if (min_e < 0) {
+ pr_debug("clock: error: target rate or tolerance too low\n");
+ return ~0;
+ }
+
+ clk->dpll_data->last_rounded_m = min_e_m;
+ clk->dpll_data->last_rounded_n = min_e_n;
+ clk->dpll_data->last_rounded_rate =
+ _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n);
+
+ pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
+ min_e, min_e_m, min_e_n);
+ pr_debug("clock: final rate: %ld (target rate: %ld)\n",
+ clk->dpll_data->last_rounded_rate, target_rate);
+
+ return clk->dpll_data->last_rounded_rate;
+}
+
/*-------------------------------------------------------------------------
* Omap2 clock reset and init functions
*-------------------------------------------------------------------------*/
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index d5980a9e09a..3cd37cb57c5 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -18,11 +18,16 @@
#include <asm/arch/clock.h>
+/* The maximum error between a target DPLL rate and the rounded rate in Hz */
+#define DEFAULT_DPLL_RATE_TOLERANCE 50000
+
int omap2_clk_enable(struct clk *clk);
void omap2_clk_disable(struct clk *clk);
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
+int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance);
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
#ifdef CONFIG_OMAP_RESET_CLOCKS
void omap2_clk_disable_unused(struct clk *clk);
@@ -42,6 +47,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
u32 omap2_get_dpll_rate(struct clk *clk);
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
+void omap2_clk_prepare_for_reboot(void);
extern u8 cpu_mask;
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index ece32d8acba..aa567876651 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -154,7 +154,7 @@ static void omap2_clk_fixed_disable(struct clk *clk)
* Uses the current prcm set to tell if a rate is valid.
* You can go slower, but not faster within a given rate set.
*/
-static u32 omap2_dpll_round_rate(unsigned long target_rate)
+long omap2_dpllcore_round_rate(unsigned long target_rate)
{
u32 high, low, core_clk_src;
@@ -183,14 +183,14 @@ static u32 omap2_dpll_round_rate(unsigned long target_rate)
}
-static void omap2_dpll_recalc(struct clk *clk)
+static void omap2_dpllcore_recalc(struct clk *clk)
{
clk->rate = omap2_get_dpll_rate_24xx(clk);
propagate_rate(clk);
}
-static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate)
+static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
{
u32 cur_rate, low, mult, div, valid_rate, done_rate;
u32 bypass = 0;
@@ -209,7 +209,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate)
} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
} else if (rate != cur_rate) {
- valid_rate = omap2_dpll_round_rate(rate);
+ valid_rate = omap2_dpllcore_round_rate(rate);
if (valid_rate != rate)
goto dpll_exit;
@@ -256,7 +256,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate)
omap2_init_memory_params(omap2_dll_force_needed());
omap2_reprogram_sdrc(done_rate, 0);
}
- omap2_dpll_recalc(&dpll_ck);
+ omap2_dpllcore_recalc(&dpll_ck);
ret = 0;
dpll_exit:
@@ -383,7 +383,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
local_irq_restore(flags);
}
- omap2_dpll_recalc(&dpll_ck);
+ omap2_dpllcore_recalc(&dpll_ck);
return 0;
}
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index 88081ed13f9..be4e25554e0 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -30,12 +30,12 @@ static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
static void omap2_sys_clk_recalc(struct clk *clk);
static void omap2_osc_clk_recalc(struct clk *clk);
static void omap2_sys_clk_recalc(struct clk *clk);
-static void omap2_dpll_recalc(struct clk *clk);
+static void omap2_dpllcore_recalc(struct clk *clk);
static int omap2_clk_fixed_enable(struct clk *clk);
static void omap2_clk_fixed_disable(struct clk *clk);
static int omap2_enable_osc_ck(struct clk *clk);
static void omap2_disable_osc_ck(struct clk *clk);
-static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate);
+static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
* xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
@@ -665,20 +665,27 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
* deal with this
*/
-static const struct dpll_data dpll_dd = {
+static struct dpll_data dpll_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.mult_mask = OMAP24XX_DPLL_MULT_MASK,
.div1_mask = OMAP24XX_DPLL_DIV_MASK,
+ .max_multiplier = 1024,
+ .max_divider = 16,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
static struct clk dpll_ck = {
.name = "dpll_ck",
.parent = &sys_ck, /* Can be func_32k also */
.dpll_data = &dpll_dd,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | ALWAYS_ENABLED,
- .recalc = &omap2_dpll_recalc,
- .set_rate = &omap2_reprogram_dpll,
+ .recalc = &omap2_dpllcore_recalc,
+ .set_rate = &omap2_reprogram_dpllcore,
};
static struct clk apll96_ck = {
@@ -1747,7 +1754,8 @@ static struct clk gpt12_fck = {
};
static struct clk mcbsp1_ick = {
- .name = "mcbsp1_ick",
+ .name = "mcbsp_ick",
+ .id = 1,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1756,7 +1764,8 @@ static struct clk mcbsp1_ick = {
};
static struct clk mcbsp1_fck = {
- .name = "mcbsp1_fck",
+ .name = "mcbsp_fck",
+ .id = 1,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1765,7 +1774,8 @@ static struct clk mcbsp1_fck = {
};
static struct clk mcbsp2_ick = {
- .name = "mcbsp2_ick",
+ .name = "mcbsp_ick",
+ .id = 2,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -1774,7 +1784,8 @@ static struct clk mcbsp2_ick = {
};
static struct clk mcbsp2_fck = {
- .name = "mcbsp2_fck",
+ .name = "mcbsp_fck",
+ .id = 2,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1783,7 +1794,8 @@ static struct clk mcbsp2_fck = {
};
static struct clk mcbsp3_ick = {
- .name = "mcbsp3_ick",
+ .name = "mcbsp_ick",
+ .id = 3,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1792,7 +1804,8 @@ static struct clk mcbsp3_ick = {
};
static struct clk mcbsp3_fck = {
- .name = "mcbsp3_fck",
+ .name = "mcbsp_fck",
+ .id = 3,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
@@ -1801,7 +1814,8 @@ static struct clk mcbsp3_fck = {
};
static struct clk mcbsp4_ick = {
- .name = "mcbsp4_ick",
+ .name = "mcbsp_ick",
+ .id = 4,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1810,7 +1824,8 @@ static struct clk mcbsp4_ick = {
};
static struct clk mcbsp4_fck = {
- .name = "mcbsp4_fck",
+ .name = "mcbsp_fck",
+ .id = 4,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
@@ -1819,7 +1834,8 @@ static struct clk mcbsp4_fck = {
};
static struct clk mcbsp5_ick = {
- .name = "mcbsp5_ick",
+ .name = "mcbsp_ick",
+ .id = 5,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
@@ -1828,7 +1844,8 @@ static struct clk mcbsp5_ick = {
};
static struct clk mcbsp5_fck = {
- .name = "mcbsp5_fck",
+ .name = "mcbsp_fck",
+ .id = 5,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index b42bdd6079a..4263099b1ad 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -1,10 +1,11 @@
/*
* OMAP3-specific clock framework functions
*
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
*
* Written by Paul Walmsley
+ * Testing and integration fixes by Jouni Högander
*
* Parts of this code are based on code written by
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
@@ -23,6 +24,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/limits.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
@@ -37,8 +39,11 @@
#include "cm.h"
#include "cm-regbits-34xx.h"
-/* CM_CLKEN_PLL*.EN* bit values */
-#define DPLL_LOCKED 0x7
+/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
+#define DPLL_AUTOIDLE_DISABLE 0x0
+#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1
+
+#define MAX_DPLL_WAIT_TRIES 1000000
/**
* omap3_dpll_recalc - recalculate DPLL rate
@@ -53,6 +58,290 @@ static void omap3_dpll_recalc(struct clk *clk)
propagate_rate(clk);
}
+/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
+static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
+{
+ const struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+
+ cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask),
+ dd->control_reg);
+}
+
+/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
+static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
+{
+ const struct dpll_data *dd;
+ int i = 0;
+ int ret = -EINVAL;
+ u32 idlest_mask;
+
+ dd = clk->dpll_data;
+
+ state <<= dd->idlest_bit;
+ idlest_mask = 1 << dd->idlest_bit;
+
+ while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) &&
+ i < MAX_DPLL_WAIT_TRIES) {
+ i++;
+ udelay(1);
+ }
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ printk(KERN_ERR "clock: %s failed transition to '%s'\n",
+ clk->name, (state) ? "locked" : "bypassed");
+ } else {
+ pr_debug("clock: %s transition to '%s' in %d loops\n",
+ clk->name, (state) ? "locked" : "bypassed", i);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
+
+/*
+ * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report
+ * readiness before returning. Will save and restore the DPLL's
+ * autoidle state across the enable, per the CDP code. If the DPLL
+ * locked successfully, return 0; if the DPLL did not lock in the time
+ * allotted, or DPLL3 was passed in, return -EINVAL.
+ */
+static int _omap3_noncore_dpll_lock(struct clk *clk)
+{
+ u8 ai;
+ int r;
+
+ if (clk == &dpll3_ck)
+ return -EINVAL;
+
+ pr_debug("clock: locking DPLL %s\n", clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOCKED);
+
+ if (ai) {
+ /*
+ * If no downstream clocks are enabled, CM_IDLEST bit
+ * may never become active, so don't wait for DPLL to lock.
+ */
+ r = 0;
+ omap3_dpll_allow_idle(clk);
+ } else {
+ r = _omap3_wait_dpll_status(clk, 1);
+ omap3_dpll_deny_idle(clk);
+ };
+
+ return r;
+}
+
+/*
+ * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power bypass mode. In
+ * bypass mode, the DPLL's rate is set equal to its parent clock's
+ * rate. Waits for the DPLL to report readiness before returning.
+ * Will save and restore the DPLL's autoidle state across the enable,
+ * per the CDP code. If the DPLL entered bypass mode successfully,
+ * return 0; if the DPLL did not enter bypass in the time allotted, or
+ * DPLL3 was passed in, or the DPLL does not support low-power bypass,
+ * return -EINVAL.
+ */
+static int _omap3_noncore_dpll_bypass(struct clk *clk)
+{
+ int r;
+ u8 ai;
+
+ if (clk == &dpll3_ck)
+ return -EINVAL;
+
+ if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
+ return -EINVAL;
+
+ pr_debug("clock: configuring DPLL %s for low-power bypass\n",
+ clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
+
+ r = _omap3_wait_dpll_status(clk, 0);
+
+ if (ai)
+ omap3_dpll_allow_idle(clk);
+ else
+ omap3_dpll_deny_idle(clk);
+
+ return r;
+}
+
+/*
+ * _omap3_noncore_dpll_stop - instruct a DPLL to stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop. Will save and
+ * restore the DPLL's autoidle state across the stop, per the CDP
+ * code. If DPLL3 was passed in, or the DPLL does not support
+ * low-power stop, return -EINVAL; otherwise, return 0.
+ */
+static int _omap3_noncore_dpll_stop(struct clk *clk)
+{
+ u8 ai;
+
+ if (clk == &dpll3_ck)
+ return -EINVAL;
+
+ if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
+ return -EINVAL;
+
+ pr_debug("clock: stopping DPLL %s\n", clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
+
+ if (ai)
+ omap3_dpll_allow_idle(clk);
+ else
+ omap3_dpll_deny_idle(clk);
+
+ return 0;
+}
+
+/**
+ * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
+ * The choice of modes depends on the DPLL's programmed rate: if it is
+ * the same as the DPLL's parent clock, it will enter bypass;
+ * otherwise, it will enter lock. This code will wait for the DPLL to
+ * indicate readiness before returning, unless the DPLL takes too long
+ * to enter the target state. Intended to be used as the struct clk's
+ * enable function. If DPLL3 was passed in, or the DPLL does not
+ * support low-power stop, or if the DPLL took too long to enter
+ * bypass or lock, return -EINVAL; otherwise, return 0.
+ */
+static int omap3_noncore_dpll_enable(struct clk *clk)
+{
+ int r;
+
+ if (clk == &dpll3_ck)
+ return -EINVAL;
+
+ if (clk->parent->rate == clk_get_rate(clk))
+ r = _omap3_noncore_dpll_bypass(clk);
+ else
+ r = _omap3_noncore_dpll_lock(clk);
+
+ return r;
+}
+
+/**
+ * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
+ * The choice of modes depends on the DPLL's programmed rate: if it is
+ * the same as the DPLL's parent clock, it will enter bypass;
+ * otherwise, it will enter lock. This code will wait for the DPLL to
+ * indicate readiness before returning, unless the DPLL takes too long
+ * to enter the target state. Intended to be used as the struct clk's
+ * enable function. If DPLL3 was passed in, or the DPLL does not
+ * support low-power stop, or if the DPLL took too long to enter
+ * bypass or lock, return -EINVAL; otherwise, return 0.
+ */
+static void omap3_noncore_dpll_disable(struct clk *clk)
+{
+ if (clk == &dpll3_ck)
+ return;
+
+ _omap3_noncore_dpll_stop(clk);
+}
+
+/**
+ * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
+ * @clk: struct clk * of the DPLL to read
+ *
+ * Return the DPLL's autoidle bits, shifted down to bit 0. Returns
+ * -EINVAL if passed a null pointer or if the struct clk does not
+ * appear to refer to a DPLL.
+ */
+static u32 omap3_dpll_autoidle_read(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+
+ v = cm_read_reg(dd->autoidle_reg);
+ v &= dd->autoidle_mask;
+ v >>= __ffs(dd->autoidle_mask);
+
+ return v;
+}
+
+/**
+ * omap3_dpll_allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control. This automatic idle mode
+ * switching takes effect only when the DPLL is locked, at least on
+ * OMAP3430. The DPLL will enter low-power stop when its downstream
+ * clocks are gated. No return value.
+ */
+static void omap3_dpll_allow_idle(struct clk *clk)
+{
+ const struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ /*
+ * REVISIT: CORE DPLL can optionally enter low-power bypass
+ * by writing 0x5 instead of 0x1. Add some mechanism to
+ * optionally enter this mode.
+ */
+ cm_rmw_reg_bits(dd->autoidle_mask,
+ DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask),
+ dd->autoidle_reg);
+}
+
+/**
+ * omap3_dpll_deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control. No return value.
+ */
+static void omap3_dpll_deny_idle(struct clk *clk)
+{
+ const struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ cm_rmw_reg_bits(dd->autoidle_mask,
+ DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask),
+ dd->autoidle_reg);
+}
+
+/* Clock control for DPLL outputs */
+
/**
* omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
* @clk: DPLL output struct clk
@@ -89,6 +378,8 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
propagate_rate(clk);
}
+/* Common clock code */
+
/*
* As it is structured now, this will prevent an OMAP2/3 multiboot
* kernel from compiling. This will need further attention.
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index c9c5972a2e2..05757eb032b 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -1,14 +1,19 @@
/*
* OMAP3 clock framework
*
- * Virtual clocks are introduced as a convenient tools.
- * They are sources for other clocks and not supposed
- * to be requested from drivers directly.
- *
* Copyright (C) 2007-2008 Texas Instruments, Inc.
* Copyright (C) 2007-2008 Nokia Corporation
*
* Written by Paul Walmsley
+ * With many device clock fixes by Kevin Hilman and Jouni Högander
+ * DPLL bypass clock support added by Roman Tereshonkov
+ *
+ */
+
+/*
+ * Virtual clocks are introduced as convenient tools.
+ * They are sources for other clocks and not supposed
+ * to be requested from drivers directly.
*/
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
@@ -24,6 +29,15 @@
static void omap3_dpll_recalc(struct clk *clk);
static void omap3_clkoutx2_recalc(struct clk *clk);
+static void omap3_dpll_allow_idle(struct clk *clk);
+static void omap3_dpll_deny_idle(struct clk *clk);
+static u32 omap3_dpll_autoidle_read(struct clk *clk);
+static int omap3_noncore_dpll_enable(struct clk *clk);
+static void omap3_noncore_dpll_disable(struct clk *clk);
+
+/* Maximum DPLL multiplier, divider values for OMAP3 */
+#define OMAP3_MAX_DPLL_MULT 2048
+#define OMAP3_MAX_DPLL_DIV 128
/*
* DPLL1 supplies clock to the MPU.
@@ -33,6 +47,11 @@ static void omap3_clkoutx2_recalc(struct clk *clk);
* DPLL5 supplies other peripheral clocks (USBHOST, USIM).
*/
+/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
+#define DPLL_LOW_POWER_STOP 0x1
+#define DPLL_LOW_POWER_BYPASS 0x5
+#define DPLL_LOCKED 0x7
+
/* PRM CLOCKS */
/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
@@ -240,15 +259,23 @@ static const struct clksel_rate div16_dpll_rates[] = {
/* DPLL1 */
/* MPU clock source */
/* Type: DPLL */
-static const struct dpll_data dpll1_dd = {
+static struct dpll_data dpll1_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
.mult_mask = OMAP3430_MPU_DPLL_MULT_MASK,
.div1_mask = OMAP3430_MPU_DPLL_DIV_MASK,
.control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
.enable_mask = OMAP3430_EN_MPU_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
.recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
.recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+ .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+ .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll1_ck = {
@@ -256,6 +283,7 @@ static struct clk dpll1_ck = {
.parent = &sys_ck,
.dpll_data = &dpll1_dd,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .round_rate = &omap2_dpll_round_rate,
.recalc = &omap3_dpll_recalc,
};
@@ -297,22 +325,34 @@ static struct clk dpll1_x2m2_ck = {
/* IVA2 clock source */
/* Type: DPLL */
-static const struct dpll_data dpll2_dd = {
+static struct dpll_data dpll2_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
.mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK,
.div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK,
.control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
.enable_mask = OMAP3430_EN_IVA2_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
+ (1 << DPLL_LOW_POWER_BYPASS),
.auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
.recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
.recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+ .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
+ .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll2_ck = {
.name = "dpll2_ck",
.parent = &sys_ck,
.dpll_data = &dpll2_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+ .enable = &omap3_noncore_dpll_enable,
+ .disable = &omap3_noncore_dpll_disable,
+ .round_rate = &omap2_dpll_round_rate,
.recalc = &omap3_dpll_recalc,
};
@@ -338,10 +378,12 @@ static struct clk dpll2_m2_ck = {
.recalc = &omap2_clksel_recalc,
};
-/* DPLL3 */
-/* Source clock for all interfaces and for some device fclks */
-/* Type: DPLL */
-static const struct dpll_data dpll3_dd = {
+/*
+ * DPLL3
+ * Source clock for all interfaces and for some device fclks
+ * REVISIT: Also supports fast relock bypass - not included below
+ */
+static struct dpll_data dpll3_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.mult_mask = OMAP3430_CORE_DPLL_MULT_MASK,
.div1_mask = OMAP3430_CORE_DPLL_DIV_MASK,
@@ -350,6 +392,11 @@ static const struct dpll_data dpll3_dd = {
.auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
.recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
.recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+ .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll3_ck = {
@@ -357,6 +404,7 @@ static struct clk dpll3_ck = {
.parent = &sys_ck,
.dpll_data = &dpll3_dd,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .round_rate = &omap2_dpll_round_rate,
.recalc = &omap3_dpll_recalc,
};
@@ -439,7 +487,7 @@ static struct clk core_ck = {
.name = "core_ck",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK,
+ .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = core_ck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -456,7 +504,7 @@ static struct clk dpll3_m2x2_ck = {
.name = "dpll3_m2x2_ck",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK,
+ .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = dpll3_m2x2_ck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -503,7 +551,7 @@ static struct clk emu_core_alwon_ck = {
.parent = &dpll3_m3x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK,
+ .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = emu_core_alwon_ck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -513,22 +561,33 @@ static struct clk emu_core_alwon_ck = {
/* DPLL4 */
/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
/* Type: DPLL */
-static const struct dpll_data dpll4_dd = {
+static struct dpll_data dpll4_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
.mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
.div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
.control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
.auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
.recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
.recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+ .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+ .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll4_ck = {
.name = "dpll4_ck",
.parent = &sys_ck,
.dpll_data = &dpll4_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+ .enable = &omap3_noncore_dpll_enable,
+ .disable = &omap3_noncore_dpll_disable,
+ .round_rate = &omap2_dpll_round_rate,
.recalc = &omap3_dpll_recalc,
};
@@ -584,7 +643,7 @@ static struct clk omap_96m_alwon_fck = {
.parent = &dpll4_m2x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK,
+ .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = omap_96m_alwon_fck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -610,7 +669,7 @@ static struct clk cm_96m_fck = {
.parent = &dpll4_m2x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK,
+ .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = cm_96m_fck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -652,7 +711,7 @@ static struct clk virt_omap_54m_fck = {
.parent = &dpll4_m3x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK,
+ .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = virt_omap_54m_fck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
@@ -804,23 +863,33 @@ static struct clk emu_per_alwon_ck = {
/* Supplies 120MHz clock, USIM source clock */
/* Type: DPLL */
/* 3430ES2 only */
-static const struct dpll_data dpll5_dd = {
+static struct dpll_data dpll5_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
.mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
.div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
.control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
.enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
.auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
.recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
.recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
+ .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+ .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll5_ck = {
.name = "dpll5_ck",
.parent = &sys_ck,
.dpll_data = &dpll5_dd,
- .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
- ALWAYS_ENABLED,
+ .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES,
+ .enable = &omap3_noncore_dpll_enable,
+ .disable = &omap3_noncore_dpll_disable,
+ .round_rate = &omap2_dpll_round_rate,
.recalc = &omap3_dpll_recalc,
};
@@ -1365,7 +1434,8 @@ static const struct clksel mcbsp_15_clksel[] = {
};
static struct clk mcbsp5_fck = {
- .name = "mcbsp5_fck",
+ .name = "mcbsp_fck",
+ .id = 5,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
@@ -1377,7 +1447,8 @@ static struct clk mcbsp5_fck = {
};
static struct clk mcbsp1_fck = {
- .name = "mcbsp1_fck",
+ .name = "mcbsp_fck",
+ .id = 1,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
@@ -1789,7 +1860,8 @@ static struct clk gpt10_ick = {
};
static struct clk mcbsp5_ick = {
- .name = "mcbsp5_ick",
+ .name = "mcbsp_ick",
+ .id = 5,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
@@ -1798,7 +1870,8 @@ static struct clk mcbsp5_ick = {
};
static struct clk mcbsp1_ick = {
- .name = "mcbsp1_ick",
+ .name = "mcbsp_ick",
+ .id = 1,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
@@ -1935,7 +2008,7 @@ static struct clk dss1_alwon_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_DSS1_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK,
+ .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = dss1_alwon_fck_clksel,
.flags = CLOCK_IN_OMAP343X,
.recalc = &omap2_clksel_recalc,
@@ -1991,7 +2064,7 @@ static struct clk cam_mclk = {
.parent = &dpll4_m5x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK,
+ .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = cam_mclk_clksel,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
@@ -2541,7 +2614,8 @@ static struct clk gpt2_ick = {
};
static struct clk mcbsp2_ick = {
- .name = "mcbsp2_ick",
+ .name = "mcbsp_ick",
+ .id = 2,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
@@ -2550,7 +2624,8 @@ static struct clk mcbsp2_ick = {
};
static struct clk mcbsp3_ick = {
- .name = "mcbsp3_ick",
+ .name = "mcbsp_ick",
+ .id = 3,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
@@ -2559,7 +2634,8 @@ static struct clk mcbsp3_ick = {
};
static struct clk mcbsp4_ick = {
- .name = "mcbsp4_ick",
+ .name = "mcbsp_ick",
+ .id = 4,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
@@ -2574,7 +2650,8 @@ static const struct clksel mcbsp_234_clksel[] = {
};
static struct clk mcbsp2_fck = {
- .name = "mcbsp2_fck",
+ .name = "mcbsp_fck",
+ .id = 2,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
@@ -2586,7 +2663,8 @@ static struct clk mcbsp2_fck = {
};
static struct clk mcbsp3_fck = {
- .name = "mcbsp3_fck",
+ .name = "mcbsp_fck",
+ .id = 3,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
@@ -2598,7 +2676,8 @@ static struct clk mcbsp3_fck = {
};
static struct clk mcbsp4_fck = {
- .name = "mcbsp4_fck",
+ .name = "mcbsp_fck",
+ .id = 4,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 3c38395f644..ee4c0ca1a70 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -72,7 +72,8 @@
#define OMAP3430_ST_IVA2 (1 << 0)
/* CM_IDLEST_PLL_IVA2 */
-#define OMAP3430_ST_IVA2_CLK (1 << 0)
+#define OMAP3430_ST_IVA2_CLK_SHIFT 0
+#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0)
/* CM_AUTOIDLE_PLL_IVA2 */
#define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0
@@ -115,10 +116,7 @@
#define OMAP3430_ST_MPU (1 << 0)
/* CM_IDLEST_PLL_MPU */
-#define OMAP3430_ST_MPU_CLK (1 << 0)
-#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0)
-
-/* CM_IDLEST_PLL_MPU */
+#define OMAP3430_ST_MPU_CLK_SHIFT 0
#define OMAP3430_ST_MPU_CLK_MASK (1 << 0)
/* CM_AUTOIDLE_PLL_MPU */
@@ -408,8 +406,10 @@
#define OMAP3430_ST_12M_CLK (1 << 4)
#define OMAP3430_ST_48M_CLK (1 << 3)
#define OMAP3430_ST_96M_CLK (1 << 2)
-#define OMAP3430_ST_PERIPH_CLK (1 << 1)
-#define OMAP3430_ST_CORE_CLK (1 << 0)
+#define OMAP3430_ST_PERIPH_CLK_SHIFT 1
+#define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1)
+#define OMAP3430_ST_CORE_CLK_SHIFT 0
+#define OMAP3430_ST_CORE_CLK_MASK (1 << 0)
/* CM_IDLEST2_CKGEN */
#define OMAP3430ES2_ST_120M_CLK_SHIFT 1
@@ -423,6 +423,10 @@
#define OMAP3430_AUTO_CORE_DPLL_SHIFT 0
#define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0)
+/* CM_AUTOIDLE2_PLL */
+#define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0
+#define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0)
+
/* CM_CLKSEL1_PLL */
/* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 8489f3029fe..87a44c715aa 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -81,6 +81,7 @@
#define OMAP3430ES2_CM_FCLKEN3 0x0008
#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
+#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
@@ -96,15 +97,21 @@
/* Clock management domain register get/set */
#ifndef __ASSEMBLER__
-static inline void cm_write_mod_reg(u32 val, s16 module, s16 idx)
+
+extern u32 cm_read_mod_reg(s16 module, u16 idx);
+extern void cm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+
+static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
{
- __raw_writel(val, OMAP_CM_REGADDR(module, idx));
+ return cm_rmw_mod_reg_bits(bits, bits, module, idx);
}
-static inline u32 cm_read_mod_reg(s16 module, s16 idx)
+static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
{
- return __raw_readl(OMAP_CM_REGADDR(module, idx));
+ return cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
}
+
#endif
/* CM register bits shared between 24XX and 3430 */
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index a5d86a49c21..51f70300996 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -13,22 +13,21 @@
#undef DEBUG
#include <linux/kernel.h>
+#include <linux/io.h>
-#include <asm/io.h>
-
+#include <asm/arch/common.h>
#include <asm/arch/control.h>
-static u32 omap2_ctrl_base;
+static void __iomem *omap2_ctrl_base;
-#define OMAP_CTRL_REGADDR(reg) (void __iomem *)IO_ADDRESS(omap2_ctrl_base \
- + (reg))
+#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
-void omap_ctrl_base_set(u32 base)
+void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
{
- omap2_ctrl_base = base;
+ omap2_ctrl_base = omap2_globals->ctrl;
}
-u32 omap_ctrl_base_get(void)
+void __iomem *omap_ctrl_base_get(void)
{
return omap2_ctrl_base;
}
@@ -50,25 +49,16 @@ u32 omap_ctrl_readl(u16 offset)
void omap_ctrl_writeb(u8 val, u16 offset)
{
- pr_debug("omap_ctrl_writeb: writing 0x%0x to 0x%0x\n", val,
- (u32)OMAP_CTRL_REGADDR(offset));
-
__raw_writeb(val, OMAP_CTRL_REGADDR(offset));
}
void omap_ctrl_writew(u16 val, u16 offset)
{
- pr_debug("omap_ctrl_writew: writing 0x%0x to 0x%0x\n", val,
- (u32)OMAP_CTRL_REGADDR(offset));
-
__raw_writew(val, OMAP_CTRL_REGADDR(offset));
}
void omap_ctrl_writel(u32 val, u16 offset)
{
- pr_debug("omap_ctrl_writel: writing 0x%0x to 0x%0x\n", val,
- (u32)OMAP_CTRL_REGADDR(offset));
-
__raw_writel(val, OMAP_CTRL_REGADDR(offset));
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 02cede295e8..dbf68dc50ae 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -42,7 +42,7 @@
#define GPMC_STATUS 0x54
#define GPMC_PREFETCH_CONFIG1 0x1e0
#define GPMC_PREFETCH_CONFIG2 0x1e4
-#define GPMC_PREFETCH_CONTROL 0x1e8
+#define GPMC_PREFETCH_CONTROL 0x1ec
#define GPMC_PREFETCH_STATUS 0x1f0
#define GPMC_ECC_CONFIG 0x1f4
#define GPMC_ECC_CONTROL 0x1f8
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 4dfd878d796..dff4b16cead 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -17,16 +17,23 @@
#include <asm/io.h>
-#if defined(CONFIG_ARCH_OMAP2420)
-#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
-#endif
+#include <asm/arch/control.h>
+#include <asm/arch/cpu.h>
-#if defined(CONFIG_ARCH_OMAP2430)
-#define OMAP24XX_TAP_BASE io_p2v(0x4900A000)
+#if defined(CONFIG_ARCH_OMAP2420)
+#define TAP_BASE io_p2v(0x48014000)
+#elif defined(CONFIG_ARCH_OMAP2430)
+#define TAP_BASE io_p2v(0x4900A000)
+#elif defined(CONFIG_ARCH_OMAP34XX)
+#define TAP_BASE io_p2v(0x4830A000)
#endif
#define OMAP_TAP_IDCODE 0x0204
+#if defined(CONFIG_ARCH_OMAP34XX)
+#define OMAP_TAP_PROD_ID 0x0210
+#else
#define OMAP_TAP_PROD_ID 0x0208
+#endif
#define OMAP_TAP_DIE_ID_0 0x0218
#define OMAP_TAP_DIE_ID_1 0x021C
@@ -56,9 +63,134 @@ static struct omap_id omap_ids[] __initdata = {
{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
};
+static struct omap_chip_id omap_chip;
+
+/**
+ * omap_chip_is - test whether currently running OMAP matches a chip type
+ * @oc: omap_chip_t to test against
+ *
+ * Test whether the currently-running OMAP chip matches the supplied
+ * chip type 'oc'. Returns 1 upon a match; 0 upon failure.
+ */
+int omap_chip_is(struct omap_chip_id oci)
+{
+ return (oci.oc & omap_chip.oc) ? 1 : 0;
+}
+EXPORT_SYMBOL(omap_chip_is);
+
static u32 __init read_tap_reg(int reg)
{
- return __raw_readl(OMAP24XX_TAP_BASE + reg);
+ unsigned int regval = 0;
+ u32 cpuid;
+
+ /* Reading the IDCODE register on 3430 ES1 results in a
+ * data abort as the register is not exposed on the OCP
+ * Hence reading the Cortex Rev
+ */
+ cpuid = read_cpuid(CPUID_ID);
+
+ /* If the processor type is Cortex-A8 and the revision is 0x0
+ * it means its Cortex r0p0 which is 3430 ES1
+ */
+ if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) {
+ switch (reg) {
+ case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break;
+ /* Making DevType as 0xF in ES1 to differ from ES2 */
+ case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break;
+ case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break;
+ case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break;
+ case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break;
+ case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break;
+ }
+ } else
+ regval = __raw_readl(TAP_BASE + reg);
+
+ return regval;
+
+}
+
+/*
+ * _set_system_rev - set the system_rev global based on current OMAP chip type
+ *
+ * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx()
+ * macros.
+ */
+static void __init _set_system_rev(u32 type, u8 rev)
+{
+ u32 i, ctrl_status;
+
+ /*
+ * system_rev encoding is as follows
+ * system_rev & 0xff000000 -> Omap Class (24xx/34xx)
+ * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x)
+ * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430)
+ * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 )
+ * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD )
+ * system_rev & 0x000000c0 -> IDCODE revision[6:7]
+ * system_rev & 0x0000003f -> sys_boot[0:5]
+ */
+ /* Embedding the ES revision info in type field */
+ system_rev = type;
+ /* Also add IDCODE revision info only two lower bits */
+ system_rev |= ((rev & 0x3) << 6);
+
+ /* Add in the device type and sys_boot fields (see above) */
+ if (cpu_is_omap24xx()) {
+ i = OMAP24XX_CONTROL_STATUS;
+ } else if (cpu_is_omap343x()) {
+ i = OMAP343X_CONTROL_STATUS;
+ } else {
+ printk(KERN_ERR "id: unknown CPU type\n");
+ BUG();
+ }
+ ctrl_status = omap_ctrl_readl(i);
+ system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK |
+ OMAP2_SYSBOOT_4_MASK |
+ OMAP2_SYSBOOT_3_MASK |
+ OMAP2_SYSBOOT_2_MASK |
+ OMAP2_SYSBOOT_1_MASK |
+ OMAP2_SYSBOOT_0_MASK));
+ system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK);
+}
+
+
+/*
+ * _set_omap_chip - set the omap_chip global based on OMAP chip type
+ *
+ * Build the omap_chip bits. This variable is used by powerdomain and
+ * clockdomain code to indicate whether structures are applicable for
+ * the current OMAP chip type by ANDing it against a 'platform' bitfield
+ * in the structure.
+ */
+static void __init _set_omap_chip(void)
+{
+ if (cpu_is_omap343x()) {
+
+ omap_chip.oc = CHIP_IS_OMAP3430;
+ if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0))
+ omap_chip.oc |= CHIP_IS_OMAP3430ES1;
+ else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0))
+ omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+
+ } else if (cpu_is_omap243x()) {
+
+ /* Currently only supports 2430ES2.1 and 2430-all */
+ omap_chip.oc |= CHIP_IS_OMAP2430;
+
+ } else if (cpu_is_omap242x()) {
+
+ /* Currently only supports 2420ES2.1.1 and 2420-all */
+ omap_chip.oc |= CHIP_IS_OMAP2420;
+
+ } else {
+
+ /* Current CPU not supported by this code. */
+ printk(KERN_WARNING "OMAP chip type code does not yet support "
+ "this CPU type.\n");
+ WARN_ON(1);
+
+ }
+
}
void __init omap2_check_revision(void)
@@ -76,21 +208,31 @@ void __init omap2_check_revision(void)
rev = (idcode >> 28) & 0x0f;
dev_type = (prod_id >> 16) & 0x0f;
-#ifdef DEBUG
- printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
- idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
- printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_0));
- printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
- read_tap_reg(OMAP_TAP_DIE_ID_1),
- (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
- printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_2));
- printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_3));
- printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
- prod_id, dev_type);
-#endif
+ pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
+ idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
+ pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_0));
+ pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_1),
+ (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
+ pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_2));
+ pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n",
+ read_tap_reg(OMAP_TAP_DIE_ID_3));
+ pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
+ prod_id, dev_type);
+
+ /*
+ * Detection for 34xx ES2.0 and above can be done with just
+ * hawkeye and rev. See TRM 1.5.2 Device Identification.
+ * Note that rev cannot be used directly as ES1.0 uses value 0.
+ */
+ if (hawkeye == 0xb7ae) {
+ system_rev = 0x34300000 | ((1 + rev) << 12);
+ pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev);
+ _set_omap_chip();
+ return;
+ }
/* Check hawkeye ids */
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
@@ -114,16 +256,15 @@ void __init omap2_check_revision(void)
omap_ids[i].type >> 16);
j = i;
}
- system_rev = omap_ids[j].type;
- system_rev |= rev << 8;
+ _set_system_rev(omap_ids[j].type, rev);
- /* Add the cpu class info (24xx) */
- system_rev |= 0x24;
+ _set_omap_chip();
pr_info("OMAP%04x", system_rev >> 16);
if ((system_rev >> 8) & 0x0f)
- printk("%x", (system_rev >> 8) & 0x0f);
- printk("\n");
+ pr_info("ES%x", (system_rev >> 12) & 0xf);
+ pr_info("\n");
+
}
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
new file mode 100644
index 00000000000..17cf199d113
--- /dev/null
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -0,0 +1,208 @@
+/*
+ * linux/arch/arm/mach-omap2/mcbsp.c
+ *
+ * Copyright (C) 2008 Instituto Nokia de Tecnologia
+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
+ *
+ * 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.
+ *
+ * Multichannel mode not supported.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/arch/dma.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mcbsp.h>
+
+struct mcbsp_internal_clk {
+ struct clk clk;
+ struct clk **childs;
+ int n_childs;
+};
+
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
+{
+ const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
+ int i;
+
+ mclk->n_childs = ARRAY_SIZE(clk_names);
+ mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
+ GFP_KERNEL);
+
+ for (i = 0; i < mclk->n_childs; i++) {
+ /* We fake a platform device to get correct device id */
+ struct platform_device pdev;
+
+ pdev.dev.bus = &platform_bus_type;
+ pdev.id = mclk->clk.id;
+ mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
+ if (IS_ERR(mclk->childs[i]))
+ printk(KERN_ERR "Could not get clock %s (%d).\n",
+ clk_names[i], mclk->clk.id);
+ }
+}
+
+static int omap_mcbsp_clk_enable(struct clk *clk)
+{
+ struct mcbsp_internal_clk *mclk = container_of(clk,
+ struct mcbsp_internal_clk, clk);
+ int i;
+
+ for (i = 0; i < mclk->n_childs; i++)
+ clk_enable(mclk->childs[i]);
+ return 0;
+}
+
+static void omap_mcbsp_clk_disable(struct clk *clk)
+{
+ struct mcbsp_internal_clk *mclk = container_of(clk,
+ struct mcbsp_internal_clk, clk);
+ int i;
+
+ for (i = 0; i < mclk->n_childs; i++)
+ clk_disable(mclk->childs[i]);
+}
+
+static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 1,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 2,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+};
+
+#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks)
+#else
+#define omap_mcbsp_clks_size 0
+static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
+static inline void omap_mcbsp_clk_init(struct clk *clk)
+{ }
+#endif
+
+static void omap2_mcbsp2_mux_setup(void)
+{
+ omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
+ omap_cfg_reg(R14_24XX_MCBSP2_FSX);
+ omap_cfg_reg(W15_24XX_MCBSP2_DR);
+ omap_cfg_reg(V15_24XX_MCBSP2_DX);
+ omap_cfg_reg(V14_24XX_GPIO117);
+ /*
+ * TODO: Need to add MUX settings for OMAP 2430 SDP
+ */
+}
+
+static void omap2_mcbsp_request(unsigned int id)
+{
+ if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
+ omap2_mcbsp2_mux_setup();
+}
+
+static int omap2_mcbsp_check(unsigned int id)
+{
+ if (id > OMAP_MAX_MCBSP_COUNT - 1) {
+ printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static struct omap_mcbsp_ops omap2_mcbsp_ops = {
+ .request = omap2_mcbsp_request,
+ .check = omap2_mcbsp_check,
+};
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
+ {
+ .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
+ .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
+ .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+};
+#define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata)
+#else
+#define omap24xx_mcbsp_pdata NULL
+#define OMAP24XX_MCBSP_PDATA_SZ 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
+ {
+ .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE),
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
+ .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE),
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
+ .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+};
+#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
+#else
+#define omap34xx_mcbsp_pdata NULL
+#define OMAP34XX_MCBSP_PDATA_SZ 0
+#endif
+
+int __init omap2_mcbsp_init(void)
+{
+ int i;
+
+ for (i = 0; i < omap_mcbsp_clks_size; i++) {
+ /* Once we call clk_get inside init, we do not register it */
+ omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
+ clk_register(&omap_mcbsp_clks[i].clk);
+ }
+
+ if (cpu_is_omap24xx())
+ omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata,
+ OMAP24XX_MCBSP_PDATA_SZ);
+
+ if (cpu_is_omap34xx())
+ omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
+ OMAP34XX_MCBSP_PDATA_SZ);
+
+ return omap_mcbsp_init();
+}
+arch_initcall(omap2_mcbsp_init);
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
index 12479081881..73cadb2c75c 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/memory.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
+#include <asm/arch/common.h>
#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
@@ -32,8 +33,8 @@
#include "memory.h"
#include "sdrc.h"
-unsigned long omap2_sdrc_base;
-unsigned long omap2_sms_base;
+void __iomem *omap2_sdrc_base;
+void __iomem *omap2_sms_base;
static struct memory_timings mem_timings;
static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
@@ -154,6 +155,12 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
}
+void __init omap2_set_globals_memory(struct omap_globals *omap2_globals)
+{
+ omap2_sdrc_base = omap2_globals->sdrc;
+ omap2_sms_base = omap2_globals->sms;
+}
+
/* turn on smart idle modes for SDRAM scheduler and controller */
void __init omap2_init_memory(void)
{
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 930770012a7..8f98b20f30a 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -236,7 +236,7 @@ void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg)
warn = (orig != reg);
if (debug || warn)
printk(KERN_WARNING
- "MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n",
+ "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n",
cfg->name, omap_ctrl_base_get() + cfg->mux_reg,
orig, reg);
}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index aad781dcf1b..d6c9de82ca0 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -57,13 +57,6 @@ void omap2_pm_idle(void)
return;
}
- /*
- * Since an interrupt may set up a timer, we don't want to
- * reprogram the hardware timer with interrupts enabled.
- * Re-enable interrupts only after returning from idle.
- */
- timer_dyn_reprogram();
-
omap2_sram_idle();
local_fiq_enable();
local_irq_enable();
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index cacb34086e3..54c32f48213 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -32,6 +32,7 @@
/* Chip-specific module offsets */
+#define OMAP24XX_GR_MOD OCP_MOD
#define OMAP24XX_DSP_MOD 0x800
#define OMAP2430_MDM_MOD 0xc00
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index b12f423b859..fd92a80f38f 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -16,16 +16,21 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/clk.h>
+#include <linux/io.h>
-#include <asm/io.h>
+#include <asm/arch/common.h>
+#include <asm/arch/prcm.h>
+#include "clock.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
-extern void omap2_clk_prepare_for_reboot(void);
+static void __iomem *prm_base;
+static void __iomem *cm_base;
u32 omap_prcm_get_reset_sources(void)
{
+ /* XXX This presumably needs modification for 34XX */
return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f;
}
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
@@ -33,11 +38,90 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources);
/* Resets clock rates and reboots the system. Only called from system.h */
void omap_prcm_arch_reset(char mode)
{
- u32 wkup;
+ s16 prcm_offs;
omap2_clk_prepare_for_reboot();
- if (cpu_is_omap24xx()) {
- wkup = prm_read_mod_reg(WKUP_MOD, RM_RSTCTRL) | OMAP_RST_DPLL3;
- prm_write_mod_reg(wkup, WKUP_MOD, RM_RSTCTRL);
- }
+ if (cpu_is_omap24xx())
+ prcm_offs = WKUP_MOD;
+ else if (cpu_is_omap34xx())
+ prcm_offs = OMAP3430_GR_MOD;
+ else
+ WARN_ON(1);
+
+ prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL);
+}
+
+static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
+{
+ BUG_ON(!base);
+ return __raw_readl(base + module + reg);
+}
+
+static inline void __omap_prcm_write(u32 value, void __iomem *base,
+ s16 module, u16 reg)
+{
+ BUG_ON(!base);
+ __raw_writel(value, base + module + reg);
+}
+
+/* Read a register in a PRM module */
+u32 prm_read_mod_reg(s16 module, u16 idx)
+{
+ return __omap_prcm_read(prm_base, module, idx);
+}
+EXPORT_SYMBOL(prm_read_mod_reg);
+
+/* Write into a register in a PRM module */
+void prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __omap_prcm_write(val, prm_base, module, idx);
+}
+EXPORT_SYMBOL(prm_write_mod_reg);
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = prm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ prm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+EXPORT_SYMBOL(prm_rmw_mod_reg_bits);
+
+/* Read a register in a CM module */
+u32 cm_read_mod_reg(s16 module, u16 idx)
+{
+ return __omap_prcm_read(cm_base, module, idx);
+}
+EXPORT_SYMBOL(cm_read_mod_reg);
+
+/* Write into a register in a CM module */
+void cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __omap_prcm_write(val, cm_base, module, idx);
+}
+EXPORT_SYMBOL(cm_write_mod_reg);
+
+/* Read-modify-write a register in a CM module. Caller must lock */
+u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = cm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ cm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+EXPORT_SYMBOL(cm_rmw_mod_reg_bits);
+
+void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
+{
+ prm_base = omap2_globals->prm;
+ cm_base = omap2_globals->cm;
}
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 618f8111658..bbf41fc8e9a 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -38,13 +38,29 @@
*
*/
+/* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */
+#define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050
+#define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080
+
+/* 242x GR_MOD registers, use these only for assembly code */
+#define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \
+ OMAP24XX_PRCM_VOLTCTRL_OFFSET)
+#define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \
+ OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET)
+
+/* 243x GR_MOD registers, use these only for assembly code */
+#define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \
+ OMAP24XX_PRCM_VOLTCTRL_OFFSET)
+#define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \
+ OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET)
+
+/* These will disappear */
#define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000)
#define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010)
#define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018)
#define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c)
-#define OMAP24XX_PRCM_VOLTCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0050)
#define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054)
#define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060)
#define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070)
@@ -150,15 +166,19 @@
#ifndef __ASSEMBLER__
/* Power/reset management domain register get/set */
+extern u32 prm_read_mod_reg(s16 module, u16 idx);
+extern void prm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
-static inline void prm_write_mod_reg(u32 val, s16 module, s16 idx)
+/* Read-modify-write bits in a PRM register (by domain) */
+static inline u32 prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
{
- __raw_writel(val, OMAP_PRM_REGADDR(module, idx));
+ return prm_rmw_mod_reg_bits(bits, bits, module, idx);
}
-static inline u32 prm_read_mod_reg(s16 module, s16 idx)
+static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
{
- return __raw_readl(OMAP_PRM_REGADDR(module, idx));
+ return prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
}
#endif
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index d7f23bc9550..1b1fe4f6e03 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -18,13 +18,11 @@
#include <asm/arch/sdrc.h>
#ifndef __ASSEMBLER__
-extern unsigned long omap2_sdrc_base;
-extern unsigned long omap2_sms_base;
+extern void __iomem *omap2_sdrc_base;
+extern void __iomem *omap2_sms_base;
-#define OMAP_SDRC_REGADDR(reg) \
- (void __iomem *)IO_ADDRESS(omap2_sdrc_base + (reg))
-#define OMAP_SMS_REGADDR(reg) \
- (void __iomem *)IO_ADDRESS(omap2_sms_base + (reg))
+#define OMAP_SDRC_REGADDR(reg) (omap2_sdrc_base + (reg))
+#define OMAP_SMS_REGADDR(reg) (omap2_sms_base + (reg))
/* SDRC global register get/set */
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram242x.S
index 4a9e4914071..4c274510f3e 100644
--- a/arch/arm/mach-omap2/sram-fn.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap2/sram-fn.S
+ * linux/arch/arm/mach-omap2/sram242x.S
*
* Omap2 specific functions that need to be run in internal SRAM
*
@@ -27,22 +27,20 @@
#include <asm/arch/io.h>
#include <asm/hardware.h>
-#include "sdrc.h"
#include "prm.h"
#include "cm.h"
-
-#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+#include "sdrc.h"
.text
-ENTRY(sram_ddr_init)
+ENTRY(omap242x_sram_ddr_init)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
mov r12, r2 @ capture CS1 vs CS0
mov r8, r3 @ capture force parameter
/* frequency shift down */
- ldr r2, cm_clksel2_pll @ get address of dpllout reg
+ ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg
mov r3, #0x1 @ value for 1x operation
str r3, [r2] @ go to L1-freq operation
@@ -51,7 +49,7 @@ ENTRY(sram_ddr_init)
bl voltage_shift @ go drop voltage
/* dll lock mode */
- ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl
ldr r10, [r11] @ get current val
cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
@@ -102,7 +100,7 @@ i_dll_delay:
* wait for it to finish, use 32k sync counter, 1tick=31uS.
*/
voltage_shift:
- ldr r4, prcm_voltctrl @ get addr of volt ctrl.
+ ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl.
ldr r5, [r4] @ get value.
ldr r6, prcm_mask_val @ get value of mask
and r5, r5, r6 @ apply mask to clear bits
@@ -112,7 +110,7 @@ voltage_shift:
orr r5, r5, r3 @ build value for force
str r5, [r4] @ Force transition to L1
- ldr r3, timer_32ksynct_cr @ get addr of counter
+ ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter
ldr r5, [r3] @ get value
add r5, r5, #0x3 @ give it at most 93uS
volt_delay:
@@ -121,32 +119,31 @@ volt_delay:
bhi volt_delay @ not yet->branch
mov pc, lr @ back to caller.
-/* relative load constants */
-cm_clksel2_pll:
+omap242x_sdi_cm_clksel2_pll:
.word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
-sdrc_dlla_ctrl:
+omap242x_sdi_sdrc_dlla_ctrl:
.word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
-prcm_voltctrl:
- .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50)
+omap242x_sdi_prcm_voltctrl:
+ .word OMAP242X_PRCM_VOLTCTRL
prcm_mask_val:
.word 0xFFFF3FFC
-timer_32ksynct_cr:
- .word TIMER_32KSYNCT_CR_V
-ENTRY(sram_ddr_init_sz)
- .word . - sram_ddr_init
+omap242x_sdi_timer_32ksynct_cr:
+ .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010)
+ENTRY(omap242x_sram_ddr_init_sz)
+ .word . - omap242x_sram_ddr_init
/*
* Reprograms memory timings.
* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
*/
-ENTRY(sram_reprogram_sdrc)
+ENTRY(omap242x_sram_reprogram_sdrc)
stmfd sp!, {r0 - r10, lr} @ save registers on stack
mov r3, #0x0 @ clear for mrc call
mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
nop
nop
- ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg
+ ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg
ldr r5, [r6] @ get value
mov r5, r5, lsr #8 @ isolate rfr field and drop burst
@@ -160,7 +157,7 @@ ENTRY(sram_reprogram_sdrc)
movne r5, r5, lsl #1 @ mult by 2 if to full
mov r5, r5, lsl #8 @ put rfr field back into place
add r5, r5, #0x1 @ turn on burst of 1
- ldr r4, ddr_cm_clksel2_pll @ get address of out reg
+ ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg
ldr r3, [r4] @ get curr value
orr r3, r3, #0x3
bic r3, r3, #0x3 @ clear lower bits
@@ -181,7 +178,7 @@ ENTRY(sram_reprogram_sdrc)
bne freq_out @ leave if SDR, no DLL function
/* With DDR, we need to take care of the DLL for the frequency change */
- ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl
str r1, [r2] @ write out new SDRC_DLLA_CTRL
add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
str r1, [r2] @ commit to SDRC_DLLB_CTRL
@@ -197,7 +194,7 @@ freq_out:
* wait for it to finish, use 32k sync counter, 1tick=31uS.
*/
voltage_shift_c:
- ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl
+ ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl
ldr r8, [r10] @ get value
ldr r7, ddr_prcm_mask_val @ get value of mask
and r8, r8, r7 @ apply mask to clear bits
@@ -207,7 +204,7 @@ voltage_shift_c:
orr r8, r8, r7 @ build value for force
str r8, [r10] @ Force transition to L1
- ldr r10, ddr_timer_32ksynct @ get addr of counter
+ ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter
ldr r8, [r10] @ get value
add r8, r8, #0x2 @ give it at most 62uS (min 31+)
volt_delay_c:
@@ -216,39 +213,39 @@ volt_delay_c:
bhi volt_delay_c @ not yet->branch
mov pc, lr @ back to caller
-ddr_cm_clksel2_pll:
+omap242x_srs_cm_clksel2_pll:
.word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
-ddr_sdrc_dlla_ctrl:
+omap242x_srs_sdrc_dlla_ctrl:
.word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
-ddr_sdrc_rfr_ctrl:
+omap242x_srs_sdrc_rfr_ctrl:
.word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
-ddr_prcm_voltctrl:
- .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50)
+omap242x_srs_prcm_voltctrl:
+ .word OMAP242X_PRCM_VOLTCTRL
ddr_prcm_mask_val:
.word 0xFFFF3FFC
-ddr_timer_32ksynct:
- .word TIMER_32KSYNCT_CR_V
+omap242x_srs_timer_32ksynct:
+ .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010)
-ENTRY(sram_reprogram_sdrc_sz)
- .word . - sram_reprogram_sdrc
+ENTRY(omap242x_sram_reprogram_sdrc_sz)
+ .word . - omap242x_sram_reprogram_sdrc
/*
* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
*/
-ENTRY(sram_set_prcm)
+ENTRY(omap242x_sram_set_prcm)
stmfd sp!, {r0-r12, lr} @ regs to stack
adr r4, pbegin @ addr of preload start
adr r8, pend @ addr of preload end
mcrr p15, 1, r8, r4, c12 @ preload into icache
pbegin:
/* move into fast relock bypass */
- ldr r8, pll_ctl @ get addr
+ ldr r8, omap242x_ssp_pll_ctl @ get addr
ldr r5, [r8] @ get val
mvn r6, #0x3 @ clear mask
and r5, r5, r6 @ clear field
orr r7, r5, #0x2 @ fast relock val
str r7, [r8] @ go to fast relock
- ldr r4, pll_stat @ addr of stat
+ ldr r4, omap242x_ssp_pll_stat @ addr of stat
block:
/* wait for bypass */
ldr r8, [r4] @ stat value
@@ -257,10 +254,10 @@ block:
bne block @ loop if not
/* set new dpll dividers _after_ in bypass */
- ldr r4, pll_div @ get addr
+ ldr r4, omap242x_ssp_pll_div @ get addr
str r0, [r4] @ set dpll ctrl val
- ldr r4, set_config @ get addr
+ ldr r4, omap242x_ssp_set_config @ get addr
mov r8, #1 @ valid cfg msk
str r8, [r4] @ make dividers take
@@ -274,8 +271,8 @@ wait_a_bit:
beq pend @ jump over dpll relock
/* relock DPLL with new vals */
- ldr r5, pll_stat @ get addr
- ldr r4, pll_ctl @ get addr
+ ldr r5, omap242x_ssp_pll_stat @ get addr
+ ldr r4, omap242x_ssp_pll_ctl @ get addr
orr r8, r7, #0x3 @ val for lock dpll
str r8, [r4] @ set val
mov r0, #1000 @ dead spin a bit
@@ -289,9 +286,9 @@ wait_lock:
bne wait_lock @ wait if not
pend:
/* update memory timings & briefly lock dll */
- ldr r4, sdrc_rfr @ get addr
+ ldr r4, omap242x_ssp_sdrc_rfr @ get addr
str r1, [r4] @ update refresh timing
- ldr r11, dlla_ctrl @ get addr of DLLA ctrl
+ ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl
ldr r10, [r11] @ get current val
mvn r9, #0x4 @ mask to get clear bit2
and r10, r10, r9 @ clear bit2 for lock mode
@@ -307,18 +304,18 @@ wait_dll_lock:
nop
ldmfd sp!, {r0-r12, pc} @ restore regs and return
-set_config:
- .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x80)
-pll_ctl:
- .word OMAP2420_CM_REGADDR(PLL_MOD, CM_FCLKEN1)
-pll_stat:
- .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST1)
-pll_div:
- .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL)
-sdrc_rfr:
+omap242x_ssp_set_config:
+ .word OMAP242X_PRCM_CLKCFG_CTRL
+omap242x_ssp_pll_ctl:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN)
+omap242x_ssp_pll_stat:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST)
+omap242x_ssp_pll_div:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap242x_ssp_sdrc_rfr:
.word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
-dlla_ctrl:
+omap242x_ssp_dlla_ctrl:
.word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
-ENTRY(sram_set_prcm_sz)
- .word . - sram_set_prcm
+ENTRY(omap242x_sram_set_prcm_sz)
+ .word . - omap242x_sram_set_prcm
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
new file mode 100644
index 00000000000..a3fa48dc08c
--- /dev/null
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -0,0 +1,321 @@
+/*
+ * linux/arch/arm/mach-omap2/sram243x.S
+ *
+ * Omap2 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/hardware.h>
+
+#include "prm.h"
+#include "cm.h"
+#include "sdrc.h"
+
+ .text
+
+ENTRY(omap243x_sram_ddr_init)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ mov r12, r2 @ capture CS1 vs CS0
+ mov r8, r3 @ capture force parameter
+
+ /* frequency shift down */
+ ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg
+ mov r3, #0x1 @ value for 1x operation
+ str r3, [r2] @ go to L1-freq operation
+
+ /* voltage shift down */
+ mov r9, #0x1 @ set up for L1 voltage call
+ bl voltage_shift @ go drop voltage
+
+ /* dll lock mode */
+ ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r10, [r11] @ get current val
+ cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
+ addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode.
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
+ str r10, [r11] @ commit to DLLA_CTRL
+ bl i_dll_wait @ wait for dll to lock
+
+ /* get dll value */
+ add r11, r11, #0x4 @ get addr of status reg
+ ldr r10, [r11] @ get locked value
+
+ /* voltage shift up */
+ mov r9, #0x0 @ shift back to L0-voltage
+ bl voltage_shift @ go raise voltage
+
+ /* frequency shift up */
+ mov r3, #0x2 @ value for 2x operation
+ str r3, [r2] @ go to L0-freq operation
+
+ /* reset entry mode for dllctrl */
+ sub r11, r11, #0x4 @ move from status to ctrl
+ cmp r12, #0x1 @ normalize if cs1 based
+ subeq r11, r11, #0x8 @ possibly back to DLLA
+ cmp r8, #0x1 @ if forced unlock exit
+ orreq r1, r1, #0x4 @ make sure exit with unlocked value
+ str r1, [r11] @ restore DLLA_CTRL high value
+ add r11, r11, #0x8 @ move to DLLB_CTRL addr
+ str r1, [r11] @ set value DLLB_CTRL
+ bl i_dll_wait @ wait for possible lock
+
+ /* set up for return, DDR should be good */
+ str r10, [r0] @ write dll_status and return counter
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+ /* ensure the DLL has relocked */
+i_dll_wait:
+ mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
+i_dll_delay:
+ subs r4, r4, #0x1
+ bne i_dll_delay
+ mov pc, lr
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift:
+ ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl.
+ ldr r5, [r4] @ get value.
+ ldr r6, prcm_mask_val @ get value of mask
+ and r5, r5, r6 @ apply mask to clear bits
+ orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
+ str r5, [r4] @ set up for change.
+ mov r3, #0x4000 @ get val for force
+ orr r5, r5, r3 @ build value for force
+ str r5, [r4] @ Force transition to L1
+
+ ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter
+ ldr r5, [r3] @ get value
+ add r5, r5, #0x3 @ give it at most 93uS
+volt_delay:
+ ldr r7, [r3] @ get timer value
+ cmp r5, r7 @ time up?
+ bhi volt_delay @ not yet->branch
+ mov pc, lr @ back to caller.
+
+omap243x_sdi_cm_clksel2_pll:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap243x_sdi_sdrc_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap243x_sdi_prcm_voltctrl:
+ .word OMAP243X_PRCM_VOLTCTRL
+prcm_mask_val:
+ .word 0xFFFF3FFC
+omap243x_sdi_timer_32ksynct_cr:
+ .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010)
+ENTRY(omap243x_sram_ddr_init_sz)
+ .word . - omap243x_sram_ddr_init
+
+/*
+ * Reprograms memory timings.
+ * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
+ * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
+ */
+ENTRY(omap243x_sram_reprogram_sdrc)
+ stmfd sp!, {r0 - r10, lr} @ save registers on stack
+ mov r3, #0x0 @ clear for mrc call
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
+ nop
+ nop
+ ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg
+ ldr r5, [r6] @ get value
+ mov r5, r5, lsr #8 @ isolate rfr field and drop burst
+
+ cmp r0, #0x1 @ going to half speed?
+ movne r9, #0x0 @ if up set flag up for pre up, hi volt
+
+ blne voltage_shift_c @ adjust voltage
+
+ cmp r0, #0x1 @ going to half speed (post branch link)
+ moveq r5, r5, lsr #1 @ divide by 2 if to half
+ movne r5, r5, lsl #1 @ mult by 2 if to full
+ mov r5, r5, lsl #8 @ put rfr field back into place
+ add r5, r5, #0x1 @ turn on burst of 1
+ ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg
+ ldr r3, [r4] @ get curr value
+ orr r3, r3, #0x3
+ bic r3, r3, #0x3 @ clear lower bits
+ orr r3, r3, r0 @ new state value
+ str r3, [r4] @ set new state (pll/x, x=1 or 2)
+ nop
+ nop
+
+ moveq r9, #0x1 @ if speed down, post down, drop volt
+ bleq voltage_shift_c
+
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier
+ str r5, [r6] @ set new RFR_1 value
+ add r6, r6, #0x30 @ get RFR_2 addr
+ str r5, [r6] @ set RFR_2
+ nop
+ cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
+ bne freq_out @ leave if SDR, no DLL function
+
+ /* With DDR, we need to take care of the DLL for the frequency change */
+ ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl
+ str r1, [r2] @ write out new SDRC_DLLA_CTRL
+ add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
+ str r1, [r2] @ commit to SDRC_DLLB_CTRL
+ mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
+dll_wait:
+ subs r1, r1, #0x1
+ bne dll_wait
+freq_out:
+ ldmfd sp!, {r0 - r10, pc} @ restore regs and return
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift_c:
+ ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl
+ ldr r8, [r10] @ get value
+ ldr r7, ddr_prcm_mask_val @ get value of mask
+ and r8, r8, r7 @ apply mask to clear bits
+ orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
+ str r8, [r10] @ set up for change.
+ mov r7, #0x4000 @ get val for force
+ orr r8, r8, r7 @ build value for force
+ str r8, [r10] @ Force transition to L1
+
+ ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter
+ ldr r8, [r10] @ get value
+ add r8, r8, #0x2 @ give it at most 62uS (min 31+)
+volt_delay_c:
+ ldr r7, [r10] @ get timer value
+ cmp r8, r7 @ time up?
+ bhi volt_delay_c @ not yet->branch
+ mov pc, lr @ back to caller
+
+omap243x_srs_cm_clksel2_pll:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap243x_srs_sdrc_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap243x_srs_sdrc_rfr_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap243x_srs_prcm_voltctrl:
+ .word OMAP243X_PRCM_VOLTCTRL
+ddr_prcm_mask_val:
+ .word 0xFFFF3FFC
+omap243x_srs_timer_32ksynct:
+ .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010)
+
+ENTRY(omap243x_sram_reprogram_sdrc_sz)
+ .word . - omap243x_sram_reprogram_sdrc
+
+/*
+ * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
+ */
+ENTRY(omap243x_sram_set_prcm)
+ stmfd sp!, {r0-r12, lr} @ regs to stack
+ adr r4, pbegin @ addr of preload start
+ adr r8, pend @ addr of preload end
+ mcrr p15, 1, r8, r4, c12 @ preload into icache
+pbegin:
+ /* move into fast relock bypass */
+ ldr r8, omap243x_ssp_pll_ctl @ get addr
+ ldr r5, [r8] @ get val
+ mvn r6, #0x3 @ clear mask
+ and r5, r5, r6 @ clear field
+ orr r7, r5, #0x2 @ fast relock val
+ str r7, [r8] @ go to fast relock
+ ldr r4, omap243x_ssp_pll_stat @ addr of stat
+block:
+ /* wait for bypass */
+ ldr r8, [r4] @ stat value
+ and r8, r8, #0x3 @ mask for stat
+ cmp r8, #0x1 @ there yet
+ bne block @ loop if not
+
+ /* set new dpll dividers _after_ in bypass */
+ ldr r4, omap243x_ssp_pll_div @ get addr
+ str r0, [r4] @ set dpll ctrl val
+
+ ldr r4, omap243x_ssp_set_config @ get addr
+ mov r8, #1 @ valid cfg msk
+ str r8, [r4] @ make dividers take
+
+ mov r4, #100 @ dead spin a bit
+wait_a_bit:
+ subs r4, r4, #1 @ dec loop
+ bne wait_a_bit @ delay done?
+
+ /* check if staying in bypass */
+ cmp r2, #0x1 @ stay in bypass?
+ beq pend @ jump over dpll relock
+
+ /* relock DPLL with new vals */
+ ldr r5, omap243x_ssp_pll_stat @ get addr
+ ldr r4, omap243x_ssp_pll_ctl @ get addr
+ orr r8, r7, #0x3 @ val for lock dpll
+ str r8, [r4] @ set val
+ mov r0, #1000 @ dead spin a bit
+wait_more:
+ subs r0, r0, #1 @ dec loop
+ bne wait_more @ delay done?
+wait_lock:
+ ldr r8, [r5] @ get lock val
+ and r8, r8, #3 @ isolate field
+ cmp r8, #2 @ locked?
+ bne wait_lock @ wait if not
+pend:
+ /* update memory timings & briefly lock dll */
+ ldr r4, omap243x_ssp_sdrc_rfr @ get addr
+ str r1, [r4] @ update refresh timing
+ ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl
+ ldr r10, [r11] @ get current val
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ str r10, [r11] @ commit to DLLA_CTRL
+ add r11, r11, #0x8 @ move to dllb
+ str r10, [r11] @ hit DLLB also
+
+ mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
+wait_dll_lock:
+ subs r4, r4, #0x1
+ bne wait_dll_lock
+ nop
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+omap243x_ssp_set_config:
+ .word OMAP243X_PRCM_CLKCFG_CTRL
+omap243x_ssp_pll_ctl:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN)
+omap243x_ssp_pll_stat:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST)
+omap243x_ssp_pll_div:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap243x_ssp_sdrc_rfr:
+ .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap243x_ssp_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+
+ENTRY(omap243x_sram_set_prcm_sz)
+ .word . - omap243x_sram_set_prcm
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 78d05f203ff..557603f9931 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -59,8 +59,7 @@ static struct irqaction omap2_gp_timer_irq = {
static int omap2_gp_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
- omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles);
- omap_dm_timer_start(gptimer);
+ omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);
return 0;
}
@@ -77,8 +76,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
period -= 1;
- omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period);
- omap_dm_timer_start(gptimer);
+ omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
break;
case CLOCK_EVT_MODE_ONESHOT:
break;
@@ -172,8 +170,7 @@ static void __init omap2_gp_clocksource_init(void)
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
tick_period = (tick_rate / HZ) - 1;
- omap_dm_timer_set_load(gpt, 1, 0);
- omap_dm_timer_start(gpt);
+ omap_dm_timer_set_load_start(gpt, 1, 0);
clocksource_gpt.mult =
clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift);
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 3e57428affe..8e813ed5751 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -74,6 +74,8 @@ static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
+ trace_hardirqs_off();
+
/*
* the primary core may have used a "cross call" soft interrupt
* to get this processor out of WFI in the BootMonitor - make
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index cd3dc0834b3..99fdc736698 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -37,6 +37,17 @@ config S3C2410_CLOCK
help
Clock code for the S3C2410, and similar processors
+config SIMTEC_NOR
+ bool
+ help
+ Internal node to specify machine has simtec NOR mapping
+
+config MACH_BAST_IDE
+ bool
+ select HAVE_PATA_PLATFORM
+ help
+ Internal node for machines with an BAST style IDE
+ interface
menu "S3C2410 Machines"
@@ -61,15 +72,18 @@ config PM_H1940
Internal node for H1940 and related PM
config MACH_N30
- bool "Acer N30"
+ bool "Acer N30 family"
select CPU_S3C2410
help
- Say Y here if you are using the Acer N30
+ Say Y here if you want suppt for the Acer N30, Acer N35,
+ Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
select CPU_S3C2410
select PM_SIMTEC if PM
+ select SIMTEC_NOR
+ select MACH_BAST_IDE
select ISA
help
Say Y here if you are using the Simtec Electronics EB2410ITX
@@ -107,6 +121,8 @@ config MACH_TCT_HAMMER
config MACH_VR1000
bool "Thorcom VR1000"
select PM_SIMTEC if PM
+ select SIMTEC_NOR
+ select MACH_BAST_IDE
select CPU_S3C2410
help
Say Y here if you are using the Thorcom VR1000 board.
@@ -118,4 +134,3 @@ config MACH_QT2410
Say Y here if you are using the Armzone QT2410
endmenu
-
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index cabc13ce09e..00f31f8c4e7 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -30,3 +30,11 @@ obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
+
+# Common bits of machine support
+
+obj-$(CONFIG_SIMTEC_NOR) += nor-simtec.o
+
+# machine additions
+
+obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o
diff --git a/arch/arm/mach-s3c2410/bast-ide.c b/arch/arm/mach-s3c2410/bast-ide.c
new file mode 100644
index 00000000000..df95fe37cdc
--- /dev/null
+++ b/arch/arm/mach-s3c2410/bast-ide.c
@@ -0,0 +1,112 @@
+/* linux/arch/arm/mach-s3c2410/bast-ide.c
+ *
+ * Copyright 2007 Simtec Electronics
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/map.h>
+#include <asm/arch/bast-map.h>
+#include <asm/arch/bast-irq.h>
+
+/* IDE ports */
+
+static struct pata_platform_info bast_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+#define IDE_CS S3C2410_CS5
+
+static struct resource bast_ide0_resource[] = {
+ [0] = {
+ .start = IDE_CS + BAST_PA_IDEPRI,
+ .end = IDE_CS + BAST_PA_IDEPRI + (8 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20) ,
+ .end = IDE_CS + BAST_PA_IDEPRIAUX + (7 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_IDE0,
+ .end = IRQ_IDE0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bast_device_ide0 = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_ide0_resource),
+ .resource = bast_ide0_resource,
+ .dev = {
+ .platform_data = &bast_ide_platdata,
+ .coherent_dma_mask = ~0,
+ }
+
+};
+
+static struct resource bast_ide1_resource[] = {
+ [0] = {
+ .start = IDE_CS + BAST_PA_IDESEC,
+ .end = IDE_CS + BAST_PA_IDESEC + (8 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20),
+ .end = IDE_CS + BAST_PA_IDESECAUX + (7 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_IDE1,
+ .end = IRQ_IDE1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bast_device_ide1 = {
+ .name = "pata_platform",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bast_ide1_resource),
+ .resource = bast_ide1_resource,
+ .dev = {
+ .platform_data = &bast_ide_platdata,
+ .coherent_dma_mask = ~0,
+ }
+};
+
+static struct platform_device *bast_ide_devices[] __initdata = {
+ &bast_device_ide0,
+ &bast_device_ide1,
+};
+
+static __init int bast_ide_init(void)
+{
+ if (machine_is_bast() || machine_is_vr1000())
+ return platform_add_devices(bast_ide_devices,
+ ARRAY_SIZE(bast_ide_devices));
+
+ return 0;
+}
+
+fs_initcall(bast_ide_init);
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 27f63d5d3a7..965f2712970 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/mach-bast.c
*
- * Copyright (c) 2003-2005 Simtec Electronics
+ * Copyright (c) 2003-2005,2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* http://www.simtec.co.uk/products/EB2410ITX/
@@ -20,6 +20,8 @@
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/dm9000.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
#include <net/ax88796.h>
@@ -56,7 +58,9 @@
#include <asm/plat-s3c24xx/clock.h>
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>
+
#include "usb-simtec.h"
+#include "nor-simtec.h"
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
@@ -134,37 +138,21 @@ static struct map_desc bast_iodesc[] __initdata = {
{ VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
- { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C2(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* slow, word */
{ VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
- { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C3(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, byte */
{ VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
- { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C4(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, word */
{ VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
- { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C5(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
@@ -218,23 +206,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
}
};
-/* NOR Flash on BAST board */
-
-static struct resource bast_nor_resource[] = {
- [0] = {
- .start = S3C2410_CS1 + 0x4000000,
- .end = S3C2410_CS1 + 0x4000000 + (32*1024*1024) - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device bast_device_nor = {
- .name = "bast-nor",
- .id = -1,
- .num_resources = ARRAY_SIZE(bast_nor_resource),
- .resource = bast_nor_resource,
-};
-
/* NAND Flash on BAST board */
#ifdef CONFIG_PM
@@ -374,7 +345,7 @@ static struct resource bast_dm9k_resource[] = {
[2] = {
.start = IRQ_DM9000,
.end = IRQ_DM9000,
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
}
};
@@ -564,6 +535,18 @@ static struct s3c2410fb_mach_info __initdata bast_fb_info = {
.default_display = 1,
};
+/* I2C devices fitted. */
+
+static struct i2c_board_info bast_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ }, {
+ I2C_BOARD_INFO("simtec-pmu", 0x6b),
+ }, {
+ I2C_BOARD_INFO("ch7013", 0x75),
+ },
+};
+
/* Standard BAST devices */
static struct platform_device *bast_devices[] __initdata = {
@@ -573,7 +556,6 @@ static struct platform_device *bast_devices[] __initdata = {
&s3c_device_i2c,
&s3c_device_rtc,
&s3c_device_nand,
- &bast_device_nor,
&bast_device_dm9k,
&bast_device_asix,
&bast_device_axpp,
@@ -622,6 +604,11 @@ static void __init bast_init(void)
s3c24xx_fb_set_platdata(&bast_fb_info);
platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
+
+ i2c_register_board_info(0, bast_i2c_devs,
+ ARRAY_SIZE(bast_i2c_devs));
+
+ nor_simtec_init();
}
MACHINE_START(BAST, "Simtec-BAST")
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 621f548da61..43c2e915c5b 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -1,9 +1,10 @@
-/* linux/arch/arm/mach-s3c2410/mach-n30.c
+/* Machine specific code for the Acer n30, Acer N35, Navman PiN 570,
+ * Yakumo AlphaX and Airis NC05 PDAs.
*
* Copyright (c) 2003-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * Copyright (c) 2005 Christer Weinigel <christer@weinigel.se>
+ * Copyright (c) 2005-2008 Christer Weinigel <christer@weinigel.se>
*
* There is a wiki with more information about the n30 port at
* http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
@@ -11,36 +12,42 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
-*/
+ */
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
+
#include <linux/delay.h>
-#include <linux/serial_core.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/kthread.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
+#include <linux/serial_core.h>
+#include <linux/timer.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/fb.h>
+#include <asm/arch/leds-gpio.h>
#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
#include <asm/plat-s3c/iic.h>
+#include <asm/plat-s3c/regs-serial.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/udc.h>
static struct map_desc n30_iodesc[] __initdata = {
/* nothing here yet */
@@ -64,7 +71,8 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = {
.ulcon = 0x43,
.ufcon = 0x51,
},
- /* The BlueTooth controller is connected to port 2 */
+ /* On the N30 the bluetooth controller is connected here.
+ * On the N35 and variants the GPS receiver is connected here. */
[2] = {
.hwport = 2,
.flags = 0,
@@ -74,13 +82,260 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = {
},
};
+static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+ switch (cmd) {
+ case S3C2410_UDC_P_ENABLE :
+ s3c2410_gpio_setpin(S3C2410_GPB3, 1);
+ break;
+ case S3C2410_UDC_P_DISABLE :
+ s3c2410_gpio_setpin(S3C2410_GPB3, 0);
+ break;
+ case S3C2410_UDC_P_RESET :
+ break;
+ default:
+ break;
+ }
+}
+
+static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
+ .udc_command = n30_udc_pullup,
+ .vbus_pin = S3C2410_GPG1,
+ .vbus_pin_inverted = 0,
+};
+
+static struct gpio_keys_button n30_buttons[] = {
+ {
+ .gpio = S3C2410_GPF0,
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG9,
+ .code = KEY_UP,
+ .desc = "Thumbwheel Up",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG8,
+ .code = KEY_DOWN,
+ .desc = "Thumbwheel Down",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG7,
+ .code = KEY_ENTER,
+ .desc = "Thumbwheel Press",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF7,
+ .code = KEY_HOMEPAGE,
+ .desc = "Home",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF6,
+ .code = KEY_CALENDAR,
+ .desc = "Calendar",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF5,
+ .code = KEY_ADDRESSBOOK,
+ .desc = "Contacts",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF4,
+ .code = KEY_MAIL,
+ .desc = "Mail",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data n30_button_data = {
+ .buttons = n30_buttons,
+ .nbuttons = ARRAY_SIZE(n30_buttons),
+};
+
+static struct platform_device n30_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &n30_button_data,
+ }
+};
+
+static struct gpio_keys_button n35_buttons[] = {
+ {
+ .gpio = S3C2410_GPF0,
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG9,
+ .code = KEY_UP,
+ .desc = "Joystick Up",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG8,
+ .code = KEY_DOWN,
+ .desc = "Joystick Down",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG6,
+ .code = KEY_DOWN,
+ .desc = "Joystick Left",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG5,
+ .code = KEY_DOWN,
+ .desc = "Joystick Right",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG7,
+ .code = KEY_ENTER,
+ .desc = "Joystick Press",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF7,
+ .code = KEY_HOMEPAGE,
+ .desc = "Home",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF6,
+ .code = KEY_CALENDAR,
+ .desc = "Calendar",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF5,
+ .code = KEY_ADDRESSBOOK,
+ .desc = "Contacts",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF4,
+ .code = KEY_MAIL,
+ .desc = "Mail",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF3,
+ .code = SW_RADIO,
+ .desc = "GPS Antenna",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG2,
+ .code = SW_HEADPHONE_INSERT,
+ .desc = "Headphone",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data n35_button_data = {
+ .buttons = n35_buttons,
+ .nbuttons = ARRAY_SIZE(n35_buttons),
+};
+
+static struct platform_device n35_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &n35_button_data,
+ }
+};
+
+/* This is the bluetooth LED on the device. */
+static struct s3c24xx_led_platdata n30_blue_led_pdata = {
+ .name = "blue_led",
+ .gpio = S3C2410_GPG6,
+ .def_trigger = "",
+};
+
+/* This LED is driven by the battery microcontroller, and is blinking
+ * red, blinking green or solid green when the battery is low,
+ * charging or full respectively. By driving GPD9 low, it's possible
+ * to force the LED to blink red, so call that warning LED. */
+static struct s3c24xx_led_platdata n30_warning_led_pdata = {
+ .name = "warning_led",
+ .flags = S3C24XX_LEDF_ACTLOW,
+ .gpio = S3C2410_GPD9,
+ .def_trigger = "",
+};
+
+static struct platform_device n30_blue_led = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &n30_blue_led_pdata,
+ },
+};
+
+static struct platform_device n30_warning_led = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &n30_warning_led_pdata,
+ },
+};
+
+static struct s3c2410fb_display n30_display __initdata = {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 170000,
+
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 3,
+ .right_margin = 40,
+ .hsync_len = 40,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .vsync_len = 2,
+
+ .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
+};
+
+static struct s3c2410fb_mach_info n30_fb_info __initdata = {
+ .displays = &n30_display,
+ .num_displays = 1,
+ .default_display = 0,
+ .lpcsel = 0x06,
+};
+
static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c,
+ &s3c_device_iis,
&s3c_device_usb,
+ &s3c_device_usbgadget,
+ &n30_button_device,
+ &n30_blue_led,
+ &n30_warning_led,
+};
+
+static struct platform_device *n35_devices[] __initdata = {
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_usbgadget,
+ &n35_button_device,
};
static struct s3c2410_platform_i2c n30_i2ccfg = {
@@ -90,9 +345,148 @@ static struct s3c2410_platform_i2c n30_i2ccfg = {
.max_freq = 10*1000,
};
+/* Lots of hardcoded stuff, but it sets up the hardware in a useful
+ * state so that we can boot Linux directly from flash. */
+static void __init n30_hwinit(void)
+{
+ /* GPA0-11 special functions -- unknown what they do
+ * GPA12 N30 special function -- unknown what it does
+ * N35/PiN output -- unknown what it does
+ *
+ * A12 is nGCS1 on the N30 and an output on the N35/PiN. I
+ * don't think it does anything useful on the N30, so I ought
+ * to make it an output there too since it always driven to 0
+ * as far as I can tell. */
+ if (machine_is_n30())
+ __raw_writel(0x007fffff, S3C2410_GPACON);
+ if (machine_is_n35())
+ __raw_writel(0x007fefff, S3C2410_GPACON);
+ __raw_writel(0x00000000, S3C2410_GPADAT);
+
+ /* GPB0 TOUT0 backlight level
+ * GPB1 output 1=backlight on
+ * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled
+ * GPB3 output USB D+ pull up 0=disabled, 1=enabled
+ * GPB4 N30 output -- unknown function
+ * N30/PiN GPS control 0=GPS enabled, 1=GPS disabled
+ * GPB5 output -- unknown function
+ * GPB6 input -- unknown function
+ * GPB7 output -- unknown function
+ * GPB8 output -- probably LCD driver enable
+ * GPB9 output -- probably LCD VSYNC driver enable
+ * GPB10 output -- probably LCD HSYNC driver enable
+ */
+ __raw_writel(0x00154556, S3C2410_GPBCON);
+ __raw_writel(0x00000750, S3C2410_GPBDAT);
+ __raw_writel(0x00000073, S3C2410_GPBUP);
+
+ /* GPC0 input RS232 DCD/DSR/RI
+ * GPC1 LCD
+ * GPC2 output RS232 DTR?
+ * GPC3 input RS232 DCD/DSR/RI
+ * GPC4 LCD
+ * GPC5 output 0=NAND write enabled, 1=NAND write protect
+ * GPC6 input -- unknown function
+ * GPC7 input charger status 0=charger connected
+ * this input can be triggered by power on the USB device
+ * port too, but will go back to disconnected soon after.
+ * GPC8 N30/N35 output -- unknown function, always driven to 1
+ * PiN input -- unknown function, always read as 1
+ * Make it an input with a pull up for all models.
+ * GPC9-15 LCD
+ */
+ __raw_writel(0xaaa80618, S3C2410_GPCCON);
+ __raw_writel(0x0000014c, S3C2410_GPCDAT);
+ __raw_writel(0x0000fef2, S3C2410_GPCUP);
+
+ /* GPD0 input -- unknown function
+ * GPD1-D7 LCD
+ * GPD8 N30 output -- unknown function
+ * N35/PiN output 1=GPS LED on
+ * GPD9 output 0=power led blinks red, 1=normal power led function
+ * GPD10 output -- unknown function
+ * GPD11-15 LCD drivers
+ */
+ __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
+ __raw_writel(0x00000601, S3C2410_GPDDAT);
+ __raw_writel(0x0000fbfe, S3C2410_GPDUP);
+
+ /* GPE0-4 I2S audio bus
+ * GPE5-10 SD/MMC bus
+ * E11-13 outputs -- unknown function, probably power management
+ * E14-15 I2C bus connected to the battery controller
+ */
+ __raw_writel(0xa56aaaaa, S3C2410_GPECON);
+ __raw_writel(0x0000efc5, S3C2410_GPEDAT);
+ __raw_writel(0x0000f81f, S3C2410_GPEUP);
+
+ /* GPF0 input 0=power button pressed
+ * GPF1 input SD/MMC switch 0=card present
+ * GPF2 N30 1=reset button pressed (inverted compared to the rest)
+ * N35/PiN 0=reset button pressed
+ * GPF3 N30/PiN input -- unknown function
+ * N35 input GPS antenna position, 0=antenna closed, 1=open
+ * GPF4 input 0=button 4 pressed
+ * GPF5 input 0=button 3 pressed
+ * GPF6 input 0=button 2 pressed
+ * GPF7 input 0=button 1 pressed
+ */
+ __raw_writel(0x0000aaaa, S3C2410_GPFCON);
+ __raw_writel(0x00000000, S3C2410_GPFDAT);
+ __raw_writel(0x000000ff, S3C2410_GPFUP);
+
+ /* GPG0 input RS232 DCD/DSR/RI
+ * GPG1 input 1=USB gadget port has power from a host
+ * GPG2 N30 input -- unknown function
+ * N35/PiN input 0=headphones plugged in, 1=not plugged in
+ * GPG3 N30 output -- unknown function
+ * N35/PiN input with unknown function
+ * GPG4 N30 output 0=MMC enabled, 1=MMC disabled
+ * GPG5 N30 output 0=BlueTooth chip disabled, 1=enabled
+ * N35/PiN input joystick right
+ * GPG6 N30 output 0=blue led on, 1=off
+ * N35/PiN input joystick left
+ * GPG7 input 0=thumbwheel pressed
+ * GPG8 input 0=thumbwheel down
+ * GPG9 input 0=thumbwheel up
+ * GPG10 input SD/MMC write protect switch
+ * GPG11 N30 input -- unknown function
+ * N35 output 0=GPS antenna powered, 1=not powered
+ * PiN output -- unknown function
+ * GPG12-15 touch screen functions
+ *
+ * The pullups differ between the models, so enable all
+ * pullups that are enabled on any of the models.
+ */
+ if (machine_is_n30())
+ __raw_writel(0xff0a956a, S3C2410_GPGCON);
+ if (machine_is_n35())
+ __raw_writel(0xff4aa92a, S3C2410_GPGCON);
+ __raw_writel(0x0000e800, S3C2410_GPGDAT);
+ __raw_writel(0x0000f86f, S3C2410_GPGUP);
+
+ /* GPH0/1/2/3 RS232 serial port
+ * GPH4/5 IrDA serial port
+ * GPH6/7 N30 BlueTooth serial port
+ * N35/PiN GPS receiver
+ * GPH8 input -- unknown function
+ * GPH9 CLKOUT0 HCLK -- unknown use
+ * GPH10 CLKOUT1 FCLK -- unknown use
+ *
+ * The pull ups for H6/H7 are enabled on N30 but not on the
+ * N35/PiN. I suppose is useful for a budget model of the N30
+ * with no bluetooh. It doesn't hurt to have the pull ups
+ * enabled on the N35, so leave them enabled for all models.
+ */
+ __raw_writel(0x0028aaaa, S3C2410_GPHCON);
+ __raw_writel(0x000005ef, S3C2410_GPHDAT);
+ __raw_writel(0x0000063f, S3C2410_GPHUP);
+}
+
static void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
+ n30_hwinit();
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
}
@@ -106,7 +500,9 @@ static void __init n30_init_irq(void)
static void __init n30_init(void)
{
+ s3c24xx_fb_set_platdata(&n30_fb_info);
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
+ s3c24xx_udc_set_platdata(&n30_udc_cfg);
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
@@ -115,7 +511,32 @@ static void __init n30_init(void)
S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1, 0x0);
- platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
+ if (machine_is_n30()) {
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
+ }
+
+ if (machine_is_n35()) {
+ /* Turn off suspend and switch the selectable USB port
+ * to USB device mode. Turn on suspend for the host
+ * port since it is not connected on the N35.
+ *
+ * Actually, the host port is available at some pads
+ * on the back of the device, so it would actually be
+ * possible to add a USB device inside the N35 if you
+ * are willing to do some hardware modifications. */
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1,
+ S3C2410_MISCCR_USBSUSPND1);
+
+ platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
+ }
}
MACHINE_START(N30, "Acer-N30")
@@ -131,9 +552,14 @@ MACHINE_START(N30, "Acer-N30")
.map_io = n30_map_io,
MACHINE_END
-/*
- Local variables:
- compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.."
- c-basic-offset: 8
- End:
-*/
+MACHINE_START(N35, "Acer-N35")
+ /* Maintainer: Christer Weinigel <christer@weinigel.se>
+ */
+ .phys_io = S3C2410_PA_UART,
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .timer = &s3c24xx_timer,
+ .init_machine = n30_init,
+ .init_irq = n30_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 4c4b5c4207c..9a0965ac5e1 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
*
- * Copyright (c) 2003-2005 Simtec Electronics
+ * Copyright (c) 2003-2005,2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Machine support for Thorcom VR1000 board. Designed for Thorcom by
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/dm9000.h>
+#include <linux/i2c.h>
#include <linux/serial.h>
#include <linux/tty.h>
@@ -46,7 +47,9 @@
#include <asm/plat-s3c24xx/clock.h>
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>
+
#include "usb-simtec.h"
+#include "nor-simtec.h"
/* macros for virtual address mods for the io space entries */
#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
@@ -97,34 +100,6 @@ static struct map_desc vr1000_iodesc[] __initdata = {
.length = SZ_1M,
.type = MT_DEVICE,
},
-
- /* peripheral space... one for each of fast/slow/byte/16bit */
- /* note, ide is only decoded in word space, even though some registers
- * are only 8bit */
-
- /* slow, byte */
- { VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
-
- /* slow, word */
- { VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
-
- /* fast, byte */
- { VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
-
- /* fast, word */
- { VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
- { VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
- { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
- { VA_C5(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
@@ -230,23 +205,6 @@ static struct platform_device serial_device = {
},
};
-/* MTD NOR Flash */
-
-static struct resource vr1000_nor_resource[] = {
- [0] = {
- .start = S3C2410_CS1 + 0x4000000,
- .end = S3C2410_CS1 + 0x4000000 + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device vr1000_nor = {
- .name = "bast-nor",
- .id = -1,
- .num_resources = ARRAY_SIZE(vr1000_nor_resource),
- .resource = vr1000_nor_resource,
-};
-
/* DM9000 ethernet devices */
static struct resource vr1000_dm9k0_resource[] = {
@@ -263,7 +221,7 @@ static struct resource vr1000_dm9k0_resource[] = {
[2] = {
.start = IRQ_VR1000_DM9000A,
.end = IRQ_VR1000_DM9000A,
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
}
};
@@ -282,7 +240,7 @@ static struct resource vr1000_dm9k1_resource[] = {
[2] = {
.start = IRQ_VR1000_DM9000N,
.end = IRQ_VR1000_DM9000N,
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
}
};
@@ -358,6 +316,18 @@ static struct platform_device vr1000_led3 = {
},
};
+/* I2C devices. */
+
+static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ }, {
+ I2C_BOARD_INFO("tmp101", 0x48),
+ }, {
+ I2C_BOARD_INFO("m41st87", 0x68),
+ },
+};
+
/* devices for this board */
static struct platform_device *vr1000_devices[] __initdata = {
@@ -367,7 +337,6 @@ static struct platform_device *vr1000_devices[] __initdata = {
&s3c_device_i2c,
&s3c_device_adc,
&serial_device,
- &vr1000_nor,
&vr1000_dm9k0,
&vr1000_dm9k1,
&vr1000_led1,
@@ -416,6 +385,11 @@ static void __init vr1000_map_io(void)
static void __init vr1000_init(void)
{
platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
+
+ i2c_register_board_info(0, vr1000_i2c_devs,
+ ARRAY_SIZE(vr1000_i2c_devs));
+
+ nor_simtec_init();
}
MACHINE_START(VR1000, "Thorcom-VR1000")
diff --git a/arch/arm/mach-s3c2410/nor-simtec.c b/arch/arm/mach-s3c2410/nor-simtec.c
new file mode 100644
index 00000000000..f44e21b9c3b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/nor-simtec.c
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec NOR mapping
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/map.h>
+#include <asm/arch/bast-map.h>
+#include <asm/arch/bast-cpld.h>
+
+
+static void simtec_nor_vpp(struct map_info *map, int vpp)
+{
+ unsigned int val;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ val = __raw_readb(BAST_VA_CTRL3);
+
+ printk(KERN_DEBUG "%s(%d)\n", __func__, vpp);
+
+ if (vpp)
+ val |= BAST_CPLD_CTRL3_ROMWEN;
+ else
+ val &= ~BAST_CPLD_CTRL3_ROMWEN;
+
+ __raw_writeb(val, BAST_VA_CTRL3);
+ local_irq_restore(flags);
+}
+
+struct physmap_flash_data simtec_nor_pdata = {
+ .width = 2,
+ .set_vpp = simtec_nor_vpp,
+ .nr_parts = 0,
+};
+
+static struct resource simtec_nor_resource[] = {
+ [0] = {
+ .start = S3C2410_CS1 + 0x4000000,
+ .end = S3C2410_CS1 + 0x4000000 + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device simtec_device_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(simtec_nor_resource),
+ .resource = simtec_nor_resource,
+ .dev = {
+ .platform_data = &simtec_nor_pdata,
+ },
+};
+
+void __init nor_simtec_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&simtec_device_nor);
+ if (ret < 0)
+ printk(KERN_ERR "failed to register physmap-flash device\n");
+ else
+ simtec_nor_vpp(NULL, 1);
+}
diff --git a/arch/arm/mach-s3c2410/nor-simtec.h b/arch/arm/mach-s3c2410/nor-simtec.h
new file mode 100644
index 00000000000..f619c1e0d0c
--- /dev/null
+++ b/arch/arm/mach-s3c2410/nor-simtec.h
@@ -0,0 +1,14 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec NOR mapping
+ *
+ * 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.
+*/
+
+extern void nor_simtec_init(void);
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 0b43431d4b7..c59a9d2ee9a 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -34,6 +34,16 @@ config S3C2412_PM
menu "S3C2412 Machines"
+config MACH_JIVE
+ bool "Logitech Jive"
+ select CPU_S3C2412
+ help
+ Say Y here if you are using the Logitech Jive.
+
+config MACH_JIVE_SHOW_BOOTLOADER
+ bool "Allow access to bootloader partitions in MTD"
+ depends on MACH_JIVE && EXPERIMENTAL
+
config MACH_SMDK2413
bool "SMDK2413"
select CPU_S3C2412
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index 267f3348301..20918d5dc6a 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
# Machine support
+obj-$(CONFIG_MACH_JIVE) += mach-jive.o
obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 2697a65ba72..1157b5a1626 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -631,6 +631,17 @@ static struct clk_init clks_src[] __initdata = {
.bit = S3C2412_CLKSRC_USBCLK_HCLK,
.src_0 = &clk_usysclk,
.src_1 = &clk_h,
+ /* here we assume OM[4] select xtal */
+ }, {
+ .clk = &clk_erefclk,
+ .bit = S3C2412_CLKSRC_EREFCLK_EXTCLK,
+ .src_0 = &clk_xtal,
+ .src_1 = &clk_ext,
+ }, {
+ .clk = &clk_urefclk,
+ .bit = S3C2412_CLKSRC_UREFCLK_EXTCLK,
+ .src_0 = &clk_xtal,
+ .src_1 = &clk_ext,
},
};
@@ -666,8 +677,6 @@ static void __init s3c2412_clk_initparents(void)
static struct clk *clks[] __initdata = {
&clk_ext,
&clk_usb_bus,
- &clk_erefclk,
- &clk_urefclk,
&clk_mrefclk,
&clk_armclk,
};
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
new file mode 100644
index 00000000000..7f592471348
--- /dev/null
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -0,0 +1,687 @@
+/* linux/arch/arm/mach-s3c2410/mach-jive.c
+ *
+ * Copyright 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <video/ili9320.h>
+
+#include <linux/spi/spi.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/plat-s3c/nand.h>
+#include <asm/plat-s3c/iic.h>
+
+#include <asm/arch/regs-power.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/spi-gpio.h>
+#include <asm/arch/fb.h>
+
+#include <asm/mach-types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/udc.h>
+
+static struct map_desc jive_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg jive_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+/* Jive flash assignment
+ *
+ * 0x00000000-0x00028000 : uboot
+ * 0x00028000-0x0002c000 : uboot env
+ * 0x0002c000-0x00030000 : spare
+ * 0x00030000-0x00200000 : zimage A
+ * 0x00200000-0x01600000 : cramfs A
+ * 0x01600000-0x017d0000 : zimage B
+ * 0x017d0000-0x02bd0000 : cramfs B
+ * 0x02bd0000-0x03fd0000 : yaffs
+ */
+static struct mtd_partition jive_imageA_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+ /* Don't allow access to the bootloader from linux */
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (160 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* spare */
+ {
+ .name = "spare",
+ .offset = (176 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+#endif
+
+ /* booted images */
+ {
+ .name = "kernel (ro)",
+ .offset = (192 * SZ_1K),
+ .size = (SZ_2M) - (192 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "root (ro)",
+ .offset = (SZ_2M),
+ .size = (20 * SZ_1M),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* yaffs */
+ {
+ .name = "yaffs",
+ .offset = (44 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+
+ /* bootloader environment */
+ {
+ .name = "env",
+ .offset = (160 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+
+ /* upgrade images */
+ {
+ .name = "zimage",
+ .offset = (22 * SZ_1M),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ }, {
+ .name = "cramfs",
+ .offset = (24 * SZ_1M) - (192*SZ_1K),
+ .size = (20 * SZ_1M),
+ },
+};
+
+static struct mtd_partition jive_imageB_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+ /* Don't allow access to the bootloader from linux */
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (160 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* spare */
+ {
+ .name = "spare",
+ .offset = (176 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+#endif
+
+ /* booted images */
+ {
+ .name = "kernel (ro)",
+ .offset = (22 * SZ_1M),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "root (ro)",
+ .offset = (24 * SZ_1M) - (192 * SZ_1K),
+ .size = (20 * SZ_1M),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* yaffs */
+ {
+ .name = "yaffs",
+ .offset = (44 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+
+ /* bootloader environment */
+ {
+ .name = "env",
+ .offset = (160 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+
+ /* upgrade images */
+ {
+ .name = "zimage",
+ .offset = (192 * SZ_1K),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ }, {
+ .name = "cramfs",
+ .offset = (2 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+};
+
+static struct s3c2410_nand_set jive_nand_sets[] = {
+ [0] = {
+ .name = "flash",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(jive_imageA_nand_part),
+ .partitions = jive_imageA_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand jive_nand_info = {
+ /* set taken from osiris nand timings, possibly still conservative */
+ .tacls = 30,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .sets = jive_nand_sets,
+ .nr_sets = ARRAY_SIZE(jive_nand_sets),
+};
+
+static int __init jive_mtdset(char *options)
+{
+ struct s3c2410_nand_set *nand = &jive_nand_sets[0];
+ unsigned long set;
+
+ if (options == NULL || options[0] == '\0')
+ return 0;
+
+ if (strict_strtoul(options, 10, &set)) {
+ printk(KERN_ERR "failed to parse mtdset=%s\n", options);
+ return 0;
+ }
+
+ switch (set) {
+ case 1:
+ nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
+ nand->partitions = jive_imageB_nand_part;
+ case 0:
+ /* this is already setup in the nand info */
+ break;
+ default:
+ printk(KERN_ERR "Unknown mtd set %ld specified,"
+ "using default.", set);
+ }
+
+ return 0;
+}
+
+/* parse the mtdset= option given to the kernel command line */
+__setup("mtdset=", jive_mtdset);
+
+/* LCD timing and setup */
+
+#define LCD_XRES (240)
+#define LCD_YRES (320)
+#define LCD_LEFT_MARGIN (12)
+#define LCD_RIGHT_MARGIN (12)
+#define LCD_LOWER_MARGIN (12)
+#define LCD_UPPER_MARGIN (12)
+#define LCD_VSYNC (2)
+#define LCD_HSYNC (2)
+
+#define LCD_REFRESH (60)
+
+#define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
+#define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
+
+struct s3c2410fb_display jive_vgg2432a4_display[] = {
+ [0] = {
+ .width = LCD_XRES,
+ .height = LCD_YRES,
+ .xres = LCD_XRES,
+ .yres = LCD_YRES,
+ .left_margin = LCD_LEFT_MARGIN,
+ .right_margin = LCD_RIGHT_MARGIN,
+ .upper_margin = LCD_UPPER_MARGIN,
+ .lower_margin = LCD_LOWER_MARGIN,
+ .hsync_len = LCD_HSYNC,
+ .vsync_len = LCD_VSYNC,
+
+ .pixclock = (1000000000000LL /
+ (LCD_REFRESH * LCD_HTOT * LCD_VTOT)),
+
+ .bpp = 16,
+ .type = (S3C2410_LCDCON1_TFT16BPP |
+ S3C2410_LCDCON1_TFT),
+
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_INVVDEN |
+ S3C2410_LCDCON5_PWREN),
+ },
+};
+
+/* todo - put into gpio header */
+
+#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
+#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
+
+struct s3c2410fb_mach_info jive_lcd_config = {
+ .displays = jive_vgg2432a4_display,
+ .num_displays = ARRAY_SIZE(jive_vgg2432a4_display),
+ .default_display = 0,
+
+ /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
+ * and disable the pull down resistors on pins we are using for LCD
+ * data. */
+
+ .gpcup = (0xf << 1) | (0x3f << 10),
+
+ .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE |
+ S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
+ S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 |
+ S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 |
+ S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7),
+
+ .gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) |
+ S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) |
+ S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
+ S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
+ S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
+
+ .gpdup = (0x3f << 2) | (0x3f << 10),
+
+ .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 |
+ S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 |
+ S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 |
+ S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
+ S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
+ S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
+
+ .gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) |
+ S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) |
+ S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) |
+ S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
+ S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
+ S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
+};
+
+/* ILI9320 support. */
+
+static void jive_lcm_reset(unsigned int set)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __func__, set);
+
+ s3c2410_gpio_setpin(S3C2410_GPG13, set);
+ s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPIO_OUTPUT);
+}
+
+#undef LCD_UPPER_MARGIN
+#define LCD_UPPER_MARGIN 2
+
+static struct ili9320_platdata jive_lcm_config = {
+ .hsize = LCD_XRES,
+ .vsize = LCD_YRES,
+
+ .reset = jive_lcm_reset,
+ .suspend = ILI9320_SUSPEND_DEEP,
+
+ .entry_mode = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
+ .display2 = (ILI9320_DISPLAY2_FP(LCD_UPPER_MARGIN) |
+ ILI9320_DISPLAY2_BP(LCD_LOWER_MARGIN)),
+ .display3 = 0x0,
+ .display4 = 0x0,
+ .rgb_if1 = (ILI9320_RGBIF1_RIM_RGB18 |
+ ILI9320_RGBIF1_RM | ILI9320_RGBIF1_CLK_RGBIF),
+ .rgb_if2 = ILI9320_RGBIF2_DPL,
+ .interface2 = 0x0,
+ .interface3 = 0x3,
+ .interface4 = (ILI9320_INTERFACE4_RTNE(16) |
+ ILI9320_INTERFACE4_DIVE(1)),
+ .interface5 = 0x0,
+ .interface6 = 0x0,
+};
+
+/* LCD SPI support */
+
+static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
+{
+ s3c2410_gpio_setpin(S3C2410_GPB7, cs ? 0 : 1);
+}
+
+static struct s3c2410_spigpio_info jive_lcd_spi = {
+ .bus_num = 0,
+ .pin_clk = S3C2410_GPG8,
+ .pin_mosi = S3C2410_GPB8,
+ .chip_select = jive_lcd_spi_chipselect,
+};
+
+static struct platform_device jive_device_lcdspi = {
+ .name = "s3c24xx-spi-gpio",
+ .id = 1,
+ .num_resources = 0,
+ .dev.platform_data = &jive_lcd_spi,
+};
+
+/* WM8750 audio code SPI definition */
+
+static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
+{
+ s3c2410_gpio_setpin(S3C2410_GPH10, cs ? 0 : 1);
+}
+
+static struct s3c2410_spigpio_info jive_wm8750_spi = {
+ .bus_num = 2,
+ .pin_clk = S3C2410_GPB4,
+ .pin_mosi = S3C2410_GPB9,
+ .chip_select = jive_wm8750_chipselect,
+};
+
+static struct platform_device jive_device_wm8750 = {
+ .name = "s3c24xx-spi-gpio",
+ .id = 2,
+ .num_resources = 0,
+ .dev.platform_data = &jive_wm8750_spi,
+};
+
+/* JIVE SPI devices. */
+
+static struct spi_board_info __initdata jive_spi_devs[] = {
+ [0] = {
+ .modalias = "VGG2432A4",
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_3, /* CPOL=1, CPHA=1 */
+ .max_speed_hz = 100000,
+ .platform_data = &jive_lcm_config,
+ }, {
+ .modalias = "WM8750",
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */
+ .max_speed_hz = 100000,
+ },
+};
+
+/* I2C bus and device configuration. */
+
+static struct s3c2410_platform_i2c jive_i2c_cfg = {
+ .max_freq = 80 * 1000,
+ .bus_freq = 50 * 1000,
+ .flags = S3C_IICFLG_FILTER,
+ .sda_delay = 2,
+};
+
+static struct i2c_board_info jive_i2c_devs[] = {
+ [0] = {
+ I2C_BOARD_INFO("lis302dl", 0x1c),
+ .irq = IRQ_EINT14,
+ },
+};
+
+/* The platform devices being used. */
+
+static struct platform_device *jive_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &s3c_device_i2c,
+ &s3c_device_lcd,
+ &jive_device_lcdspi,
+ &jive_device_wm8750,
+ &s3c_device_nand,
+ &s3c_device_usbgadget,
+};
+
+static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
+ .vbus_pin = S3C2410_GPG1, /* detect is on GPG1 */
+};
+
+/* Jive power management device */
+
+#ifdef CONFIG_PM
+static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
+{
+ /* Write the magic value u-boot uses to check for resume into
+ * the INFORM0 register, and ensure INFORM1 is set to the
+ * correct address to resume from. */
+
+ __raw_writel(0x2BED, S3C2412_INFORM0);
+ __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1);
+
+ return 0;
+}
+
+static int jive_pm_resume(struct sys_device *sd)
+{
+ __raw_writel(0x0, S3C2412_INFORM0);
+ return 0;
+}
+
+#else
+#define jive_pm_suspend NULL
+#define jive_pm_resume NULL
+#endif
+
+static struct sysdev_class jive_pm_sysclass = {
+ .name = "jive-pm",
+ .suspend = jive_pm_suspend,
+ .resume = jive_pm_resume,
+};
+
+static struct sys_device jive_pm_sysdev = {
+ .cls = &jive_pm_sysclass,
+};
+
+static void __init jive_map_io(void)
+{
+ s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+}
+
+static void jive_power_off(void)
+{
+ printk(KERN_INFO "powering system down...\n");
+
+ s3c2410_gpio_setpin(S3C2410_GPC5, 1);
+ s3c2410_gpio_cfgpin(S3C2410_GPC5, S3C2410_GPIO_OUTPUT);
+}
+
+static void __init jive_machine_init(void)
+{
+ /* register system devices for managing low level suspend */
+
+ sysdev_class_register(&jive_pm_sysclass);
+ sysdev_register(&jive_pm_sysdev);
+
+ /* write our sleep configurations for the IO. Pull down all unused
+ * IO, ensure that we have turned off all peripherals we do not
+ * need, and configure the ones we do need. */
+
+ /* Port B sleep */
+
+ __raw_writel(S3C2412_SLPCON_IN(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_HIGH(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_HIGH(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
+
+ /* Port C sleep */
+
+ __raw_writel(S3C2412_SLPCON_PULL(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_PULL(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_LOW(6) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_PULL(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_PULL(10) |
+ S3C2412_SLPCON_PULL(11) |
+ S3C2412_SLPCON_PULL(12) |
+ S3C2412_SLPCON_PULL(13) |
+ S3C2412_SLPCON_PULL(14) |
+ S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
+
+ /* Port D sleep */
+
+ __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
+
+ /* Port F sleep */
+
+ __raw_writel(S3C2412_SLPCON_LOW(0) |
+ S3C2412_SLPCON_LOW(1) |
+ S3C2412_SLPCON_LOW(2) |
+ S3C2412_SLPCON_EINT(3) |
+ S3C2412_SLPCON_EINT(4) |
+ S3C2412_SLPCON_EINT(5) |
+ S3C2412_SLPCON_EINT(6) |
+ S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
+
+ /* Port G sleep */
+
+ __raw_writel(S3C2412_SLPCON_IN(0) |
+ S3C2412_SLPCON_IN(1) |
+ S3C2412_SLPCON_IN(2) |
+ S3C2412_SLPCON_IN(3) |
+ S3C2412_SLPCON_IN(4) |
+ S3C2412_SLPCON_IN(5) |
+ S3C2412_SLPCON_IN(6) |
+ S3C2412_SLPCON_IN(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_IN(10) |
+ S3C2412_SLPCON_PULL(11) |
+ S3C2412_SLPCON_PULL(12) |
+ S3C2412_SLPCON_PULL(13) |
+ S3C2412_SLPCON_IN(14) |
+ S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
+
+ /* Port H sleep */
+
+ __raw_writel(S3C2412_SLPCON_PULL(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_PULL(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_IN(7) |
+ S3C2412_SLPCON_IN(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
+
+ /* initialise the power management now we've setup everything. */
+
+ s3c2410_pm_init();
+
+ s3c_device_nand.dev.platform_data = &jive_nand_info;
+
+ /* initialise the spi */
+
+ s3c2410_gpio_setpin(S3C2410_GPG13, 0);
+ s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPIO_OUTPUT);
+
+ s3c2410_gpio_setpin(S3C2410_GPB7, 1);
+ s3c2410_gpio_cfgpin(S3C2410_GPB7, S3C2410_GPIO_OUTPUT);
+
+ s3c2410_gpio_setpin(S3C2410_GPB6, 0);
+ s3c2410_gpio_cfgpin(S3C2410_GPB6, S3C2410_GPIO_OUTPUT);
+
+ s3c2410_gpio_setpin(S3C2410_GPG8, 1);
+ s3c2410_gpio_cfgpin(S3C2410_GPG8, S3C2410_GPIO_OUTPUT);
+
+ /* initialise the WM8750 spi */
+
+ s3c2410_gpio_setpin(S3C2410_GPH10, 1);
+ s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPIO_OUTPUT);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ s3c24xx_udc_set_platdata(&jive_udc_cfg);
+ s3c24xx_fb_set_platdata(&jive_lcd_config);
+
+ spi_register_board_info(jive_spi_devs, ARRAY_SIZE(jive_spi_devs));
+
+ s3c_device_i2c.dev.platform_data = &jive_i2c_cfg;
+ i2c_register_board_info(0, jive_i2c_devs, ARRAY_SIZE(jive_i2c_devs));
+
+ pm_power_off = jive_power_off;
+
+ platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
+}
+
+MACHINE_START(JIVE, "JIVE")
+ /* Maintainer: Ben Dooks <ben@fluff.org> */
+ .phys_io = S3C2410_PA_UART,
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = jive_map_io,
+ .init_machine = jive_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index f1915bd61d1..25de042ab99 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -29,6 +29,7 @@ config MACH_ANUBIS
bool "Simtec Electronics ANUBIS"
select CPU_S3C2440
select PM_SIMTEC if PM
+ select HAVE_PATA_PLATFORM
help
Say Y here if you are using the Simtec Electronics ANUBIS
development system
@@ -67,6 +68,11 @@ config SMDK2440_CPU2440
default y if ARCH_S3C2440
select CPU_S3C2440
+config MACH_AT2440EVB
+ bool "Avantech AT2440EVB development board"
+ select CPU_S3C2440
+ help
+ Say Y here if you are using the AT2440EVB development board
endmenu
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index c81ed6248dc..0b4440e79b9 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 47258915a2f..09af8b23500 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2440/mach-anubis.c
*
- * Copyright (c) 2003-2005 Simtec Electronics
+ * Copyright (c) 2003-2005,2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
@@ -17,6 +17,8 @@
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
#include <linux/sm501.h>
#include <linux/sm501-regs.h>
@@ -241,14 +243,18 @@ static struct s3c2410_platform_nand anubis_nand_info = {
/* IDE channels */
+struct pata_platform_info anubis_ide_platdata = {
+ .ioport_shift = 5,
+};
+
static struct resource anubis_ide0_resource[] = {
{
.start = S3C2410_CS3,
.end = S3C2410_CS3 + (8*32) - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = S3C2410_CS3 + (1<<26),
- .end = S3C2410_CS3 + (1<<26) + (8*32) - 1,
+ .start = S3C2410_CS3 + (1<<26) + (6*32),
+ .end = S3C2410_CS3 + (1<<26) + (7*32) - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_IDE0,
@@ -258,10 +264,14 @@ static struct resource anubis_ide0_resource[] = {
};
static struct platform_device anubis_device_ide0 = {
- .name = "simtec-ide",
+ .name = "pata_platform",
.id = 0,
.num_resources = ARRAY_SIZE(anubis_ide0_resource),
.resource = anubis_ide0_resource,
+ .dev = {
+ .platform_data = &anubis_ide_platdata,
+ .coherent_dma_mask = ~0,
+ },
};
static struct resource anubis_ide1_resource[] = {
@@ -270,8 +280,8 @@ static struct resource anubis_ide1_resource[] = {
.end = S3C2410_CS4 + (8*32) - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = S3C2410_CS4 + (1<<26),
- .end = S3C2410_CS4 + (1<<26) + (8*32) - 1,
+ .start = S3C2410_CS4 + (1<<26) + (6*32),
+ .end = S3C2410_CS4 + (1<<26) + (7*32) - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_IDE0,
@@ -280,12 +290,15 @@ static struct resource anubis_ide1_resource[] = {
},
};
-
static struct platform_device anubis_device_ide1 = {
- .name = "simtec-ide",
+ .name = "pata_platform",
.id = 1,
.num_resources = ARRAY_SIZE(anubis_ide1_resource),
.resource = anubis_ide1_resource,
+ .dev = {
+ .platform_data = &anubis_ide_platdata,
+ .coherent_dma_mask = ~0,
+ },
};
/* Asix AX88796 10/100 ethernet controller */
@@ -409,6 +422,15 @@ static struct clk *anubis_clocks[] = {
&s3c24xx_uclk,
};
+/* I2C devices. */
+
+static struct i2c_board_info anubis_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tps65011", 0x48),
+ .irq = IRQ_EINT20,
+ }
+};
+
static void __init anubis_map_io(void)
{
/* initialise the clocks */
@@ -448,6 +470,9 @@ static void __init anubis_map_io(void)
static void __init anubis_init(void)
{
platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
+
+ i2c_register_board_info(0, anubis_i2c_devs,
+ ARRAY_SIZE(anubis_i2c_devs));
}
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
new file mode 100644
index 00000000000..f5e3c7f2763
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -0,0 +1,198 @@
+/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c
+ *
+ * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
+ * Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
+ * and modifications by SBZ <sbz@spgui.org> and
+ * Weibing <http://weibing.blogbus.com>
+ *
+ * For product information, visit http://www.arm9e.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/dm9000.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/plat-s3c/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct map_desc at2440evb_iodesc[] __initdata = {
+ /* Nothing here */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+
+static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = at2440evb_serial_clocks,
+ .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = at2440evb_serial_clocks,
+ .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ },
+};
+
+/* NAND Flash on AT2440EVB board */
+
+static struct mtd_partition at2440evb_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_256K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "Kernel",
+ .size = SZ_2M,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "Root",
+ .offset = SZ_256K + SZ_2M,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct s3c2410_nand_set at2440evb_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(at2440evb_default_nand_part),
+ .partitions = at2440evb_default_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand at2440evb_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(at2440evb_nand_sets),
+ .sets = at2440evb_nand_sets,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource at2440evb_dm9k_resource[] = {
+ [0] = {
+ .start = S3C2410_CS3,
+ .end = S3C2410_CS3 + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C2410_CS3 + 4,
+ .end = S3C2410_CS3 + 7,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = IRQ_EINT7,
+ .end = IRQ_EINT7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data at2440evb_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device at2440evb_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(at2440evb_dm9k_resource),
+ .resource = at2440evb_dm9k_resource,
+ .dev = {
+ .platform_data = &at2440evb_dm9k_pdata,
+ },
+};
+
+static struct platform_device *at2440evb_devices[] __initdata = {
+ &s3c_device_usb,
+ &s3c_device_wdt,
+ &s3c_device_adc,
+ &s3c_device_i2c,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &at2440evb_device_eth,
+};
+
+static void __init at2440evb_map_io(void)
+{
+ s3c_device_nand.dev.platform_data = &at2440evb_nand_info;
+
+ s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
+ s3c24xx_init_clocks(16934400);
+ s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+}
+
+static void __init at2440evb_init(void)
+{
+ platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices));
+}
+
+
+MACHINE_START(AT2440EVB, "AT2440EVB")
+ .phys_io = S3C2410_PA_UART,
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = at2440evb_map_io,
+ .init_machine = at2440evb_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 8a8acdbd072..af996b0e91e 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2440/mach-osiris.c
*
- * Copyright (c) 2005 Simtec Electronics
+ * Copyright (c) 2005,2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
@@ -19,6 +19,7 @@
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/clk.h>
+#include <linux/i2c.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -322,6 +323,15 @@ static struct sys_device osiris_pm_sysdev = {
.cls = &osiris_pm_sysclass,
};
+/* I2C devices fitted. */
+
+static struct i2c_board_info osiris_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tps65011", 0x48),
+ .irq = IRQ_EINT20,
+ },
+};
+
/* Standard Osiris devices */
static struct platform_device *osiris_devices[] __initdata = {
@@ -388,6 +398,9 @@ static void __init osiris_init(void)
sysdev_class_register(&osiris_pm_sysclass);
sysdev_register(&osiris_pm_sysdev);
+ i2c_register_board_info(0, osiris_i2c_devs,
+ ARRAY_SIZE(osiris_i2c_devs));
+
platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
};
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index b42f956738d..17f064fabda 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -81,7 +81,7 @@ static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
else
clkcon &= ~clocks;
- __raw_writel(clkcon, S3C2443_HCLKCON);
+ __raw_writel(clkcon, S3C2443_PCLKCON);
return 0;
}
@@ -221,7 +221,6 @@ static struct clk clk_mdivclk = {
.get_rate = s3c2443_getrate_mdivclk,
};
-
static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
{
unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
@@ -249,6 +248,46 @@ static struct clk clk_msysclk = {
.set_parent = s3c2443_setparent_msysclk,
};
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
+static struct clk clk_armdiv = {
+ .name = "armdiv",
+ .id = -1,
+ .parent = &clk_msysclk,
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, either from
+ * armdiv or from hclk.
+ */
+
+static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long clkdiv0;
+
+ clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+ if (parent == &clk_armdiv)
+ clkdiv0 &= ~S3C2443_CLKDIV0_DVS;
+ else if (parent == &clk_h)
+ clkdiv0 |= S3C2443_CLKDIV0_DVS;
+ else
+ return -EINVAL;
+
+ __raw_writel(clkdiv0, S3C2443_CLKDIV0);
+ return 0;
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .set_parent = s3c2443_setparent_armclk,
+};
/* esysclk
*
@@ -639,6 +678,29 @@ static struct clk clk_display = {
.round_rate = s3c2443_roundrate_clksrc256,
};
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+ clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+ clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+ return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+ .name = "prediv",
+ .id = -1,
+ .parent = &clk_msysclk,
+ .get_rate = s3c2443_prediv_getrate,
+};
+
/* standard clock definitions */
static struct clk init_clocks_disable[] = {
@@ -887,6 +949,15 @@ static void __init s3c2443_clk_initparents(void)
}
clk_init_set_parent(&clk_msysclk, parent);
+
+ /* arm */
+
+ if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS)
+ parent = &clk_h;
+ else
+ parent = &clk_armdiv;
+
+ clk_init_set_parent(&clk_arm, parent);
}
/* armdiv divisor table */
@@ -909,10 +980,9 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
}
-static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
{
- clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
- clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+ clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
return clkcon0 + 1;
}
@@ -936,6 +1006,9 @@ static struct clk *clks[] __initdata = {
&clk_hsspi,
&clk_hsmmc_div,
&clk_hsmmc,
+ &clk_armdiv,
+ &clk_arm,
+ &clk_prediv,
};
void __init s3c2443_init_clocks(int xtal)
@@ -951,10 +1024,16 @@ void __init s3c2443_init_clocks(int xtal)
int ret;
int ptr;
+ /* s3c2443 parents h and p clocks from prediv */
+ clk_h.parent = &clk_prediv;
+ clk_p.parent = &clk_prediv;
+
pll = s3c2443_get_mpll(mpllcon, xtal);
+ clk_msysclk.rate = pll;
fclk = pll / s3c2443_fclk_div(clkdiv0);
- hclk = fclk / s3c2443_get_prediv(clkdiv0);
+ hclk = s3c2443_prediv_getrate(&clk_prediv);
+ hclk = hclk / s3c2443_get_hdiv(clkdiv0);
hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 236603bbafd..a2c8b006d71 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -180,8 +180,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
- default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
+ depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
+ default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_PABRT_NOIFAR
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 44558d5f931..fbfa2605844 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -144,13 +144,17 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
page = pfn_to_page(pfn);
mapping = page_mapping(page);
if (mapping) {
+#ifndef CONFIG_SMP
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
if (dirty)
__flush_dcache_page(mapping, page);
+#endif
if (cache_is_vivt())
make_coherent(mapping, vma, addr, pfn);
+ else if (vma->vm_flags & VM_EXEC)
+ __flush_icache_all();
}
}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 9df507d36e0..029ee65fda2 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -199,6 +199,8 @@ void flush_dcache_page(struct page *page)
__flush_dcache_page(mapping, page);
if (mapping && cache_is_vivt())
__flush_dcache_aliases(mapping, page);
+ else if (mapping)
+ __flush_icache_all();
}
}
EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c
index eda43608341..640e498c12e 100644
--- a/arch/arm/plat-iop/gpio.c
+++ b/arch/arm/plat-iop/gpio.c
@@ -11,6 +11,10 @@
*/
#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
#include <asm/hardware/iop3xx.h>
void gpio_line_config(int line, int direction)
@@ -46,3 +50,42 @@ void gpio_line_set(int line, int value)
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_line_set);
+
+static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ gpio_line_config(gpio, GPIO_IN);
+ return 0;
+}
+
+static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+{
+ gpio_line_set(gpio, level);
+ gpio_line_config(gpio, GPIO_OUT);
+ return 0;
+}
+
+static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ return gpio_line_get(gpio);
+}
+
+static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+ gpio_line_set(gpio, value);
+}
+
+static struct gpio_chip iop3xx_chip = {
+ .label = "iop3xx",
+ .direction_input = iop3xx_gpio_direction_input,
+ .get = iop3xx_gpio_get_value,
+ .direction_output = iop3xx_gpio_direction_output,
+ .set = iop3xx_gpio_set_value,
+ .base = 0,
+ .ngpio = IOP3XX_N_GPIOS,
+};
+
+static int __init iop3xx_gpio_setup(void)
+{
+ return gpiochip_add(&iop3xx_chip);
+}
+arch_initcall(iop3xx_gpio_setup);
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index bc639a30d6d..2c4051cc79a 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o \
+obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
usb.o fb.o
obj-m :=
obj-n :=
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 2db5580048d..c2e741de020 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/plat-omap/clock.c
*
- * Copyright (C) 2004 - 2005 Nokia corporation
+ * Copyright (C) 2004 - 2008 Nokia corporation
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
*
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
@@ -22,6 +22,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
#include <asm/io.h>
@@ -33,41 +34,6 @@ static DEFINE_SPINLOCK(clockfw_lock);
static struct clk_functions *arch_clock;
-#ifdef CONFIG_PM_DEBUG
-
-static void print_parents(struct clk *clk)
-{
- struct clk *p;
- int printed = 0;
-
- list_for_each_entry(p, &clocks, node) {
- if (p->parent == clk && p->usecount) {
- if (!clk->usecount && !printed) {
- printk("MISMATCH: %s\n", clk->name);
- printed = 1;
- }
- printk("\t%-15s\n", p->name);
- }
- }
-}
-
-void clk_print_usecounts(void)
-{
- unsigned long flags;
- struct clk *p;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- list_for_each_entry(p, &clocks, node) {
- if (p->usecount)
- printk("%-15s: %d\n", p->name, p->usecount);
- print_parents(p);
-
- }
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-
-#endif
-
/*-------------------------------------------------------------------------
* Standard clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/
@@ -446,3 +412,93 @@ int __init clk_init(struct clk_functions * custom_clocks)
return 0;
}
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+static struct dentry *clk_debugfs_root;
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ int err;
+ struct dentry *d, *child;
+ struct clk *pa = c->parent;
+ char s[255];
+ char *p = s;
+
+ p += sprintf(p, "%s", c->name);
+ if (c->id != 0)
+ sprintf(p, ":%d", c->id);
+ d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+ if (IS_ERR(d))
+ return PTR_ERR(d);
+ c->dent = d;
+
+ d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
+ if (IS_ERR(d)) {
+ err = PTR_ERR(d);
+ goto err_out;
+ }
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (IS_ERR(d)) {
+ err = PTR_ERR(d);
+ goto err_out;
+ }
+ d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ if (IS_ERR(d)) {
+ err = PTR_ERR(d);
+ goto err_out;
+ }
+ return 0;
+
+err_out:
+ d = c->dent;
+ list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(c->dent);
+ return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (IS_ERR(d))
+ return PTR_ERR(d);
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clocks, node) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */
+ return err;
+}
+late_initcall(clk_debugfs_init);
+
+#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index bd1cef2c3c1..8d04929a3c7 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -26,6 +26,7 @@
#include <asm/io.h>
#include <asm/setup.h>
+#include <asm/arch/common.h>
#include <asm/arch/board.h>
#include <asm/arch/control.h>
#include <asm/arch/mux.h>
@@ -241,30 +242,70 @@ arch_initcall(omap_init_clocksource_32k);
/* Global address base setup code */
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+
+static struct omap_globals *omap2_globals;
+
+static void __init __omap2_set_globals(void)
+{
+ omap2_set_globals_memory(omap2_globals);
+ omap2_set_globals_control(omap2_globals);
+ omap2_set_globals_prcm(omap2_globals);
+}
+
+#endif
+
#if defined(CONFIG_ARCH_OMAP2420)
+
+static struct omap_globals omap242x_globals = {
+ .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000),
+ .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
+ .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
+ .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
+ .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
+ .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
+};
+
void __init omap2_set_globals_242x(void)
{
- omap2_sdrc_base = OMAP2420_SDRC_BASE;
- omap2_sms_base = OMAP2420_SMS_BASE;
- omap_ctrl_base_set(OMAP2420_CTRL_BASE);
+ omap2_globals = &omap242x_globals;
+ __omap2_set_globals();
}
#endif
#if defined(CONFIG_ARCH_OMAP2430)
+
+static struct omap_globals omap243x_globals = {
+ .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000),
+ .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
+ .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
+ .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
+ .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
+ .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
+};
+
void __init omap2_set_globals_243x(void)
{
- omap2_sdrc_base = OMAP243X_SDRC_BASE;
- omap2_sms_base = OMAP243X_SMS_BASE;
- omap_ctrl_base_set(OMAP243X_CTRL_BASE);
+ omap2_globals = &omap243x_globals;
+ __omap2_set_globals();
}
#endif
#if defined(CONFIG_ARCH_OMAP3430)
+
+static struct omap_globals omap343x_globals = {
+ .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000),
+ .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
+ .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
+ .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
+ .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
+ .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
+};
+
void __init omap2_set_globals_343x(void)
{
- omap2_sdrc_base = OMAP343X_SDRC_BASE;
- omap2_sms_base = OMAP343X_SMS_BASE;
- omap_ctrl_base_set(OMAP343X_CTRL_BASE);
+ omap2_globals = &omap343x_globals;
+ __omap2_set_globals();
}
#endif
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 4a53f9ba6c4..81002b722da 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,6 +24,7 @@
#include <asm/arch/mux.h>
#include <asm/arch/gpio.h>
#include <asm/arch/menelaus.h>
+#include <asm/arch/mcbsp.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
@@ -145,6 +146,53 @@ static inline void omap_init_kp(void) {}
#endif
/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
+
+static struct platform_device **omap_mcbsp_devices;
+
+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
+ int size)
+{
+ int i;
+
+ if (size > OMAP_MAX_MCBSP_COUNT) {
+ printk(KERN_WARNING "Registered too many McBSPs platform_data."
+ " Using maximum (%d) available.\n",
+ OMAP_MAX_MCBSP_COUNT);
+ size = OMAP_MAX_MCBSP_COUNT;
+ }
+
+ omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
+ GFP_KERNEL);
+ if (!omap_mcbsp_devices) {
+ printk(KERN_ERR "Could not register McBSP devices\n");
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ struct platform_device *new_mcbsp;
+ int ret;
+
+ new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
+ if (!new_mcbsp)
+ continue;
+ new_mcbsp->dev.platform_data = &config[i];
+ ret = platform_device_add(new_mcbsp);
+ if (ret) {
+ platform_device_put(new_mcbsp);
+ continue;
+ }
+ omap_mcbsp_devices[i] = new_mcbsp;
+ }
+}
+
+#else
+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
+ int size)
+{ }
+#endif
+
+/*-------------------------------------------------------------------------*/
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c00eda588cd..fac8e994f58 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/plat-omap/dma.c
*
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003 - 2008 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
@@ -25,11 +25,11 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/dma.h>
-#include <asm/io.h>
#include <asm/arch/tc.h>
@@ -43,13 +43,13 @@ enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED,
enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
#endif
-#define OMAP_DMA_ACTIVE 0x01
-#define OMAP_DMA_CCR_EN (1 << 7)
+#define OMAP_DMA_ACTIVE 0x01
+#define OMAP_DMA_CCR_EN (1 << 7)
#define OMAP2_DMA_CSR_CLEAR_MASK 0xffe
-#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
-static int enable_1510_mode = 0;
+static int enable_1510_mode;
struct omap_dma_lch {
int next_lch;
@@ -57,7 +57,7 @@ struct omap_dma_lch {
u16 saved_csr;
u16 enabled_irqs;
const char *dev_name;
- void (* callback)(int lch, u16 ch_status, void *data);
+ void (*callback)(int lch, u16 ch_status, void *data);
void *data;
#ifndef CONFIG_ARCH_OMAP1
@@ -72,7 +72,6 @@ struct omap_dma_lch {
long flags;
};
-#ifndef CONFIG_ARCH_OMAP1
struct dma_link_info {
int *linked_dmach_q;
int no_of_lchs_linked;
@@ -86,7 +85,9 @@ struct dma_link_info {
};
-static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT];
+static struct dma_link_info *dma_linked_lch;
+
+#ifndef CONFIG_ARCH_OMAP1
/* Chain handling macros */
#define OMAP_DMA_CHAIN_QINIT(chain_id) \
@@ -119,12 +120,15 @@ static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT];
dma_linked_lch[chain_id].q_count++; \
} while (0)
#endif
+
+static int dma_lch_count;
static int dma_chan_count;
static spinlock_t dma_chan_lock;
-static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
+static struct omap_dma_lch *dma_chan;
+static void __iomem *omap_dma_base;
-static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
+static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
@@ -139,6 +143,24 @@ static inline void omap_enable_channel_irq(int lch);
#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
__func__);
+#define dma_read(reg) \
+({ \
+ u32 __val; \
+ if (cpu_class_is_omap1()) \
+ __val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \
+ else \
+ __val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \
+ __val; \
+})
+
+#define dma_write(val, reg) \
+({ \
+ if (cpu_class_is_omap1()) \
+ __raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \
+ else \
+ __raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \
+})
+
#ifdef CONFIG_ARCH_OMAP15XX
/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
int omap_dma_in_1510_mode(void)
@@ -173,13 +195,14 @@ static inline void set_gdma_dev(int req, int dev)
#define set_gdma_dev(req, dev) do {} while (0)
#endif
+/* Omap1 only */
static void clear_lch_regs(int lch)
{
int i;
- u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
+ void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch);
for (i = 0; i < 0x2c; i += 2)
- omap_writew(0, lch_base + i);
+ __raw_writew(0, lch_base + i);
}
void omap_set_dma_priority(int lch, int dst_port, int priority)
@@ -212,33 +235,49 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
}
if (cpu_class_is_omap2()) {
+ u32 ccr;
+
+ ccr = dma_read(CCR(lch));
if (priority)
- OMAP_DMA_CCR_REG(lch) |= (1 << 6);
+ ccr |= (1 << 6);
else
- OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
+ ccr &= ~(1 << 6);
+ dma_write(ccr, CCR(lch));
}
}
+EXPORT_SYMBOL(omap_set_dma_priority);
void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
int frame_count, int sync_mode,
int dma_trigger, int src_or_dst_synch)
{
- OMAP_DMA_CSDP_REG(lch) &= ~0x03;
- OMAP_DMA_CSDP_REG(lch) |= data_type;
+ u32 l;
+
+ l = dma_read(CSDP(lch));
+ l &= ~0x03;
+ l |= data_type;
+ dma_write(l, CSDP(lch));
if (cpu_class_is_omap1()) {
- OMAP_DMA_CCR_REG(lch) &= ~(1 << 5);
+ u16 ccr;
+
+ ccr = dma_read(CCR(lch));
+ ccr &= ~(1 << 5);
if (sync_mode == OMAP_DMA_SYNC_FRAME)
- OMAP_DMA_CCR_REG(lch) |= 1 << 5;
+ ccr |= 1 << 5;
+ dma_write(ccr, CCR(lch));
- OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2);
+ ccr = dma_read(CCR2(lch));
+ ccr &= ~(1 << 2);
if (sync_mode == OMAP_DMA_SYNC_BLOCK)
- OMAP1_DMA_CCR2_REG(lch) |= 1 << 2;
+ ccr |= 1 << 2;
+ dma_write(ccr, CCR2(lch));
}
if (cpu_class_is_omap2() && dma_trigger) {
- u32 val = OMAP_DMA_CCR_REG(lch);
+ u32 val;
+ val = dma_read(CCR(lch));
val &= ~(3 << 19);
if (dma_trigger > 63)
val |= 1 << 20;
@@ -263,12 +302,13 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
else
val &= ~(1 << 24); /* dest synch */
- OMAP_DMA_CCR_REG(lch) = val;
+ dma_write(val, CCR(lch));
}
- OMAP_DMA_CEN_REG(lch) = elem_count;
- OMAP_DMA_CFN_REG(lch) = frame_count;
+ dma_write(elem_count, CEN(lch));
+ dma_write(frame_count, CFN(lch));
}
+EXPORT_SYMBOL(omap_set_dma_transfer_params);
void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
{
@@ -281,7 +321,9 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
return;
}
- w = OMAP1_DMA_CCR2_REG(lch) & ~0x03;
+ w = dma_read(CCR2(lch));
+ w &= ~0x03;
+
switch (mode) {
case OMAP_DMA_CONSTANT_FILL:
w |= 0x01;
@@ -294,52 +336,81 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- OMAP1_DMA_CCR2_REG(lch) = w;
+ dma_write(w, CCR2(lch));
- w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f;
+ w = dma_read(LCH_CTRL(lch));
+ w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
- OMAP1_DMA_COLOR_L_REG(lch) = (u16)color;
- OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16);
+ dma_write((u16)color, COLOR_L(lch));
+ dma_write((u16)(color >> 16), COLOR_U(lch));
w |= 1; /* Channel type G */
}
- OMAP1_DMA_LCH_CTRL_REG(lch) = w;
+ dma_write(w, LCH_CTRL(lch));
}
+EXPORT_SYMBOL(omap_set_dma_color_mode);
void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
{
if (cpu_class_is_omap2()) {
- OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
- OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
+ u32 csdp;
+
+ csdp = dma_read(CSDP(lch));
+ csdp &= ~(0x3 << 16);
+ csdp |= (mode << 16);
+ dma_write(csdp, CSDP(lch));
+ }
+}
+EXPORT_SYMBOL(omap_set_dma_write_mode);
+
+void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
+{
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
+ u32 l;
+
+ l = dma_read(LCH_CTRL(lch));
+ l &= ~0x7;
+ l |= mode;
+ dma_write(l, LCH_CTRL(lch));
}
}
+EXPORT_SYMBOL(omap_set_dma_channel_mode);
/* Note that src_port is only for omap1 */
void omap_set_dma_src_params(int lch, int src_port, int src_amode,
unsigned long src_start,
int src_ei, int src_fi)
{
+ u32 l;
+
if (cpu_class_is_omap1()) {
- OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2);
- OMAP_DMA_CSDP_REG(lch) |= src_port << 2;
+ u16 w;
+
+ w = dma_read(CSDP(lch));
+ w &= ~(0x1f << 2);
+ w |= src_port << 2;
+ dma_write(w, CSDP(lch));
}
- OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12);
- OMAP_DMA_CCR_REG(lch) |= src_amode << 12;
+ l = dma_read(CCR(lch));
+ l &= ~(0x03 << 12);
+ l |= src_amode << 12;
+ dma_write(l, CCR(lch));
if (cpu_class_is_omap1()) {
- OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16;
- OMAP1_DMA_CSSA_L_REG(lch) = src_start;
+ dma_write(src_start >> 16, CSSA_U(lch));
+ dma_write((u16)src_start, CSSA_L(lch));
}
if (cpu_class_is_omap2())
- OMAP2_DMA_CSSA_REG(lch) = src_start;
+ dma_write(src_start, CSSA(lch));
- OMAP_DMA_CSEI_REG(lch) = src_ei;
- OMAP_DMA_CSFI_REG(lch) = src_fi;
+ dma_write(src_ei, CSEI(lch));
+ dma_write(src_fi, CSFI(lch));
}
+EXPORT_SYMBOL(omap_set_dma_src_params);
-void omap_set_dma_params(int lch, struct omap_dma_channel_params * params)
+void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
{
omap_set_dma_transfer_params(lch, params->data_type,
params->elem_count, params->frame_count,
@@ -356,28 +427,37 @@ void omap_set_dma_params(int lch, struct omap_dma_channel_params * params)
omap_dma_set_prio_lch(lch, params->read_prio,
params->write_prio);
}
+EXPORT_SYMBOL(omap_set_dma_params);
void omap_set_dma_src_index(int lch, int eidx, int fidx)
{
- if (cpu_class_is_omap2()) {
- REVISIT_24XX();
+ if (cpu_class_is_omap2())
return;
- }
- OMAP_DMA_CSEI_REG(lch) = eidx;
- OMAP_DMA_CSFI_REG(lch) = fidx;
+
+ dma_write(eidx, CSEI(lch));
+ dma_write(fidx, CSFI(lch));
}
+EXPORT_SYMBOL(omap_set_dma_src_index);
void omap_set_dma_src_data_pack(int lch, int enable)
{
- OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6);
+ u32 l;
+
+ l = dma_read(CSDP(lch));
+ l &= ~(1 << 6);
if (enable)
- OMAP_DMA_CSDP_REG(lch) |= (1 << 6);
+ l |= (1 << 6);
+ dma_write(l, CSDP(lch));
}
+EXPORT_SYMBOL(omap_set_dma_src_data_pack);
void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
unsigned int burst = 0;
- OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
+ u32 l;
+
+ l = dma_read(CSDP(lch));
+ l &= ~(0x03 << 7);
switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS:
@@ -408,55 +488,73 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
default:
BUG();
}
- OMAP_DMA_CSDP_REG(lch) |= (burst << 7);
+
+ l |= (burst << 7);
+ dma_write(l, CSDP(lch));
}
+EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
/* Note that dest_port is only for OMAP1 */
void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
unsigned long dest_start,
int dst_ei, int dst_fi)
{
+ u32 l;
+
if (cpu_class_is_omap1()) {
- OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9);
- OMAP_DMA_CSDP_REG(lch) |= dest_port << 9;
+ l = dma_read(CSDP(lch));
+ l &= ~(0x1f << 9);
+ l |= dest_port << 9;
+ dma_write(l, CSDP(lch));
}
- OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14);
- OMAP_DMA_CCR_REG(lch) |= dest_amode << 14;
+ l = dma_read(CCR(lch));
+ l &= ~(0x03 << 14);
+ l |= dest_amode << 14;
+ dma_write(l, CCR(lch));
if (cpu_class_is_omap1()) {
- OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16;
- OMAP1_DMA_CDSA_L_REG(lch) = dest_start;
+ dma_write(dest_start >> 16, CDSA_U(lch));
+ dma_write(dest_start, CDSA_L(lch));
}
if (cpu_class_is_omap2())
- OMAP2_DMA_CDSA_REG(lch) = dest_start;
+ dma_write(dest_start, CDSA(lch));
- OMAP_DMA_CDEI_REG(lch) = dst_ei;
- OMAP_DMA_CDFI_REG(lch) = dst_fi;
+ dma_write(dst_ei, CDEI(lch));
+ dma_write(dst_fi, CDFI(lch));
}
+EXPORT_SYMBOL(omap_set_dma_dest_params);
void omap_set_dma_dest_index(int lch, int eidx, int fidx)
{
- if (cpu_class_is_omap2()) {
- REVISIT_24XX();
+ if (cpu_class_is_omap2())
return;
- }
- OMAP_DMA_CDEI_REG(lch) = eidx;
- OMAP_DMA_CDFI_REG(lch) = fidx;
+
+ dma_write(eidx, CDEI(lch));
+ dma_write(fidx, CDFI(lch));
}
+EXPORT_SYMBOL(omap_set_dma_dest_index);
void omap_set_dma_dest_data_pack(int lch, int enable)
{
- OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13);
+ u32 l;
+
+ l = dma_read(CSDP(lch));
+ l &= ~(1 << 13);
if (enable)
- OMAP_DMA_CSDP_REG(lch) |= 1 << 13;
+ l |= 1 << 13;
+ dma_write(l, CSDP(lch));
}
+EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
unsigned int burst = 0;
- OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
+ u32 l;
+
+ l = dma_read(CSDP(lch));
+ l &= ~(0x03 << 14);
switch (burst_mode) {
case OMAP_DMA_DATA_BURST_DIS:
@@ -486,8 +584,10 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
BUG();
return;
}
- OMAP_DMA_CSDP_REG(lch) |= (burst << 14);
+ l |= (burst << 14);
+ dma_write(l, CSDP(lch));
}
+EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
static inline void omap_enable_channel_irq(int lch)
{
@@ -495,64 +595,74 @@ static inline void omap_enable_channel_irq(int lch)
/* Clear CSR */
if (cpu_class_is_omap1())
- status = OMAP_DMA_CSR_REG(lch);
+ status = dma_read(CSR(lch));
else if (cpu_class_is_omap2())
- OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
+ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
/* Enable some nice interrupts. */
- OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
-
- dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+ dma_write(dma_chan[lch].enabled_irqs, CICR(lch));
}
static void omap_disable_channel_irq(int lch)
{
if (cpu_class_is_omap2())
- OMAP_DMA_CICR_REG(lch) = 0;
+ dma_write(0, CICR(lch));
}
void omap_enable_dma_irq(int lch, u16 bits)
{
dma_chan[lch].enabled_irqs |= bits;
}
+EXPORT_SYMBOL(omap_enable_dma_irq);
void omap_disable_dma_irq(int lch, u16 bits)
{
dma_chan[lch].enabled_irqs &= ~bits;
}
+EXPORT_SYMBOL(omap_disable_dma_irq);
static inline void enable_lnk(int lch)
{
+ u32 l;
+
+ l = dma_read(CLNK_CTRL(lch));
+
if (cpu_class_is_omap1())
- OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14);
+ l &= ~(1 << 14);
/* Set the ENABLE_LNK bits */
if (dma_chan[lch].next_lch != -1)
- OMAP_DMA_CLNK_CTRL_REG(lch) =
- dma_chan[lch].next_lch | (1 << 15);
+ l = dma_chan[lch].next_lch | (1 << 15);
#ifndef CONFIG_ARCH_OMAP1
- if (dma_chan[lch].next_linked_ch != -1)
- OMAP_DMA_CLNK_CTRL_REG(lch) =
- dma_chan[lch].next_linked_ch | (1 << 15);
+ if (cpu_class_is_omap2())
+ if (dma_chan[lch].next_linked_ch != -1)
+ l = dma_chan[lch].next_linked_ch | (1 << 15);
#endif
+
+ dma_write(l, CLNK_CTRL(lch));
}
static inline void disable_lnk(int lch)
{
+ u32 l;
+
+ l = dma_read(CLNK_CTRL(lch));
+
/* Disable interrupts */
if (cpu_class_is_omap1()) {
- OMAP_DMA_CICR_REG(lch) = 0;
+ dma_write(0, CICR(lch));
/* Set the STOP_LNK bit */
- OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14;
+ l |= 1 << 14;
}
if (cpu_class_is_omap2()) {
omap_disable_channel_irq(lch);
/* Clear the ENABLE_LNK bit */
- OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15);
+ l &= ~(1 << 15);
}
+ dma_write(l, CLNK_CTRL(lch));
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
@@ -563,13 +673,13 @@ static inline void omap2_enable_irq_lch(int lch)
if (!cpu_class_is_omap2())
return;
- val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
+ val = dma_read(IRQENABLE_L0);
val |= 1 << lch;
- omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
+ dma_write(val, IRQENABLE_L0);
}
int omap_request_dma(int dev_id, const char *dev_name,
- void (* callback)(int lch, u16 ch_status, void *data),
+ void (*callback)(int lch, u16 ch_status, void *data),
void *data, int *dma_ch_out)
{
int ch, free_ch = -1;
@@ -602,10 +712,14 @@ int omap_request_dma(int dev_id, const char *dev_name,
chan->dev_name = dev_name;
chan->callback = callback;
chan->data = data;
+
#ifndef CONFIG_ARCH_OMAP1
- chan->chain_id = -1;
- chan->next_linked_ch = -1;
+ if (cpu_class_is_omap2()) {
+ chan->chain_id = -1;
+ chan->next_linked_ch = -1;
+ }
#endif
+
chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
if (cpu_class_is_omap1())
@@ -620,26 +734,28 @@ int omap_request_dma(int dev_id, const char *dev_name,
set_gdma_dev(free_ch + 1, dev_id);
dev_id = free_ch + 1;
}
- /* Disable the 1510 compatibility mode and set the sync device
- * id. */
- OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10);
+ /*
+ * Disable the 1510 compatibility mode and set the sync device
+ * id.
+ */
+ dma_write(dev_id | (1 << 10), CCR(free_ch));
} else if (cpu_is_omap730() || cpu_is_omap15xx()) {
- OMAP_DMA_CCR_REG(free_ch) = dev_id;
+ dma_write(dev_id, CCR(free_ch));
}
if (cpu_class_is_omap2()) {
omap2_enable_irq_lch(free_ch);
-
omap_enable_channel_irq(free_ch);
/* Clear the CSR register and IRQ status register */
- OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK;
- omap_writel(1 << free_ch, OMAP_DMA4_IRQSTATUS_L0);
+ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch));
+ dma_write(1 << free_ch, IRQSTATUS_L0);
}
*dma_ch_out = free_ch;
return 0;
}
+EXPORT_SYMBOL(omap_request_dma);
void omap_free_dma(int lch)
{
@@ -647,11 +763,12 @@ void omap_free_dma(int lch)
spin_lock_irqsave(&dma_chan_lock, flags);
if (dma_chan[lch].dev_id == -1) {
- printk("omap_dma: trying to free nonallocated DMA channel %d\n",
+ pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
lch);
spin_unlock_irqrestore(&dma_chan_lock, flags);
return;
}
+
dma_chan[lch].dev_id = -1;
dma_chan[lch].next_lch = -1;
dma_chan[lch].callback = NULL;
@@ -659,30 +776,31 @@ void omap_free_dma(int lch)
if (cpu_class_is_omap1()) {
/* Disable all DMA interrupts for the channel. */
- OMAP_DMA_CICR_REG(lch) = 0;
+ dma_write(0, CICR(lch));
/* Make sure the DMA transfer is stopped. */
- OMAP_DMA_CCR_REG(lch) = 0;
+ dma_write(0, CCR(lch));
}
if (cpu_class_is_omap2()) {
u32 val;
/* Disable interrupts */
- val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
+ val = dma_read(IRQENABLE_L0);
val &= ~(1 << lch);
- omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
+ dma_write(val, IRQENABLE_L0);
/* Clear the CSR register and IRQ status register */
- OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
- omap_writel(1 << lch, OMAP_DMA4_IRQSTATUS_L0);
+ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch));
+ dma_write(1 << lch, IRQSTATUS_L0);
/* Disable all DMA interrupts for the channel. */
- OMAP_DMA_CICR_REG(lch) = 0;
+ dma_write(0, CICR(lch));
/* Make sure the DMA transfer is stopped. */
- OMAP_DMA_CCR_REG(lch) = 0;
+ dma_write(0, CCR(lch));
omap_clear_dma(lch);
}
}
+EXPORT_SYMBOL(omap_free_dma);
/**
* @brief omap_dma_set_global_params : Set global priority settings for dma
@@ -710,7 +828,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
reg = (arb_rate & 0xff) << 16;
reg |= (0xff & max_fifo_depth);
- omap_writel(reg, OMAP_DMA4_GCR_REG);
+ dma_write(reg, GCR);
}
EXPORT_SYMBOL(omap_dma_set_global_params);
@@ -727,20 +845,21 @@ int
omap_dma_set_prio_lch(int lch, unsigned char read_prio,
unsigned char write_prio)
{
- u32 w;
+ u32 l;
- if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((lch < 0 || lch >= dma_lch_count))) {
printk(KERN_ERR "Invalid channel id\n");
return -EINVAL;
}
- w = OMAP_DMA_CCR_REG(lch);
- w &= ~((1 << 6) | (1 << 26));
+ l = dma_read(CCR(lch));
+ l &= ~((1 << 6) | (1 << 26));
if (cpu_is_omap2430() || cpu_is_omap34xx())
- w |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
+ l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
else
- w |= ((read_prio & 0x1) << 6);
+ l |= ((read_prio & 0x1) << 6);
+
+ dma_write(l, CCR(lch));
- OMAP_DMA_CCR_REG(lch) = w;
return 0;
}
EXPORT_SYMBOL(omap_dma_set_prio_lch);
@@ -756,28 +875,34 @@ void omap_clear_dma(int lch)
local_irq_save(flags);
if (cpu_class_is_omap1()) {
- int status;
- OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
+ u32 l;
+
+ l = dma_read(CCR(lch));
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
/* Clear pending interrupts */
- status = OMAP_DMA_CSR_REG(lch);
+ l = dma_read(CSR(lch));
}
if (cpu_class_is_omap2()) {
int i;
- u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80;
+ void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch);
for (i = 0; i < 0x44; i += 4)
- omap_writel(0, lch_base + i);
+ __raw_writel(0, lch_base + i);
}
local_irq_restore(flags);
}
+EXPORT_SYMBOL(omap_clear_dma);
void omap_start_dma(int lch)
{
+ u32 l;
+
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch;
- char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
dma_chan_link_map[lch] = 1;
/* Set the link register of the first channel */
@@ -801,27 +926,34 @@ void omap_start_dma(int lch)
} while (next_lch != -1);
} else if (cpu_class_is_omap2()) {
/* Errata: Need to write lch even if not using chaining */
- OMAP_DMA_CLNK_CTRL_REG(lch) = lch;
+ dma_write(lch, CLNK_CTRL(lch));
}
omap_enable_channel_irq(lch);
- /* Errata: On ES2.0 BUFFERING disable must be set.
- * This will always fail on ES1.0 */
- if (cpu_is_omap24xx()) {
- OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
- }
+ l = dma_read(CCR(lch));
- OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
+ /*
+ * Errata: On ES2.0 BUFFERING disable must be set.
+ * This will always fail on ES1.0
+ */
+ if (cpu_is_omap24xx())
+ l |= OMAP_DMA_CCR_EN;
+
+ l |= OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
+EXPORT_SYMBOL(omap_start_dma);
void omap_stop_dma(int lch)
{
+ u32 l;
+
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
- char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
do {
@@ -842,18 +974,22 @@ void omap_stop_dma(int lch)
/* Disable all interrupts on the channel */
if (cpu_class_is_omap1())
- OMAP_DMA_CICR_REG(lch) = 0;
+ dma_write(0, CICR(lch));
+
+ l = dma_read(CCR(lch));
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR(lch));
- OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
+EXPORT_SYMBOL(omap_stop_dma);
/*
* Allows changing the DMA callback function or data. This may be needed if
* the driver shares a single DMA channel for multiple dma triggers.
*/
int omap_set_dma_callback(int lch,
- void (* callback)(int lch, u16 ch_status, void *data),
+ void (*callback)(int lch, u16 ch_status, void *data),
void *data)
{
unsigned long flags;
@@ -873,6 +1009,7 @@ int omap_set_dma_callback(int lch,
return 0;
}
+EXPORT_SYMBOL(omap_set_dma_callback);
/*
* Returns current physical source address for the given DMA channel.
@@ -886,15 +1023,24 @@ dma_addr_t omap_get_dma_src_pos(int lch)
{
dma_addr_t offset = 0;
- if (cpu_class_is_omap1())
- offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) |
- (OMAP1_DMA_CSSA_U_REG(lch) << 16));
+ if (cpu_is_omap15xx())
+ offset = dma_read(CPC(lch));
+ else
+ offset = dma_read(CSAC(lch));
- if (cpu_class_is_omap2())
- offset = OMAP_DMA_CSAC_REG(lch);
+ /*
+ * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx() && offset == 0)
+ offset = dma_read(CSAC(lch));
+
+ if (cpu_class_is_omap1())
+ offset |= (dma_read(CSSA_U(lch)) << 16);
return offset;
}
+EXPORT_SYMBOL(omap_get_dma_src_pos);
/*
* Returns current physical destination address for the given DMA channel.
@@ -908,25 +1054,30 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
{
dma_addr_t offset = 0;
- if (cpu_class_is_omap1())
- offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) |
- (OMAP1_DMA_CDSA_U_REG(lch) << 16));
+ if (cpu_is_omap15xx())
+ offset = dma_read(CPC(lch));
+ else
+ offset = dma_read(CDAC(lch));
- if (cpu_class_is_omap2())
- offset = OMAP_DMA_CDAC_REG(lch);
+ /*
+ * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx() && offset == 0)
+ offset = dma_read(CDAC(lch));
+
+ if (cpu_class_is_omap1())
+ offset |= (dma_read(CDSA_U(lch)) << 16);
return offset;
}
+EXPORT_SYMBOL(omap_get_dma_dst_pos);
-/*
- * Returns current source transfer counting for the given DMA channel.
- * Can be used to monitor the progress of a transfer inside a block.
- * It must be called with disabled interrupts.
- */
-int omap_get_dma_src_addr_counter(int lch)
+int omap_get_dma_active_status(int lch)
{
- return (dma_addr_t) OMAP_DMA_CSAC_REG(lch);
+ return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0;
}
+EXPORT_SYMBOL(omap_get_dma_active_status);
int omap_dma_running(void)
{
@@ -938,7 +1089,7 @@ int omap_dma_running(void)
return 1;
for (lch = 0; lch < dma_chan_count; lch++)
- if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN)
+ if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN)
return 1;
return 0;
@@ -949,7 +1100,7 @@ int omap_dma_running(void)
* For this DMA link to start, you still need to start (see omap_start_dma)
* the first one. That will fire up the entire queue.
*/
-void omap_dma_link_lch (int lch_head, int lch_queue)
+void omap_dma_link_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -966,11 +1117,12 @@ void omap_dma_link_lch (int lch_head, int lch_queue)
dma_chan[lch_head].next_lch = lch_queue;
}
+EXPORT_SYMBOL(omap_dma_link_lch);
/*
* Once the DMA queue is stopped, we can destroy it.
*/
-void omap_dma_unlink_lch (int lch_head, int lch_queue)
+void omap_dma_unlink_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
@@ -985,7 +1137,6 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
dump_stack();
}
-
if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
(dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
@@ -995,12 +1146,15 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue)
dma_chan[lch_head].next_lch = -1;
}
+EXPORT_SYMBOL(omap_dma_unlink_lch);
+
+/*----------------------------------------------------------------------------*/
#ifndef CONFIG_ARCH_OMAP1
/* Create chain of DMA channesls */
static void create_dma_lch_chain(int lch_head, int lch_queue)
{
- u32 w;
+ u32 l;
/* Check if this is the first link in chain */
if (dma_chan[lch_head].next_linked_ch == -1) {
@@ -1020,15 +1174,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
lch_queue;
}
- w = OMAP_DMA_CLNK_CTRL_REG(lch_head);
- w &= ~(0x1f);
- w |= lch_queue;
- OMAP_DMA_CLNK_CTRL_REG(lch_head) = w;
+ l = dma_read(CLNK_CTRL(lch_head));
+ l &= ~(0x1f);
+ l |= lch_queue;
+ dma_write(l, CLNK_CTRL(lch_head));
- w = OMAP_DMA_CLNK_CTRL_REG(lch_queue);
- w &= ~(0x1f);
- w |= (dma_chan[lch_queue].next_linked_ch);
- OMAP_DMA_CLNK_CTRL_REG(lch_queue) = w;
+ l = dma_read(CLNK_CTRL(lch_queue));
+ l &= ~(0x1f);
+ l |= (dma_chan[lch_queue].next_linked_ch);
+ dma_write(l, CLNK_CTRL(lch_queue));
}
/**
@@ -1063,7 +1217,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name,
}
if (unlikely((no_of_chans < 1
- || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) {
+ || no_of_chans > dma_lch_count))) {
printk(KERN_ERR "Invalid Number of channels requested\n");
return -EINVAL;
}
@@ -1118,6 +1272,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name,
for (i = 0; i < (no_of_chans - 1); i++)
create_dma_lch_chain(channels[i], channels[i + 1]);
}
+
return 0;
}
EXPORT_SYMBOL(omap_request_dma_chain);
@@ -1140,7 +1295,7 @@ int omap_modify_dma_chain_params(int chain_id,
/* Check for input params */
if (unlikely((chain_id < 0
- || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1160,6 +1315,7 @@ int omap_modify_dma_chain_params(int chain_id,
*/
omap_set_dma_params(channels[i], &params);
}
+
return 0;
}
EXPORT_SYMBOL(omap_modify_dma_chain_params);
@@ -1178,7 +1334,7 @@ int omap_free_dma_chain(int chain_id)
u32 i;
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1203,6 +1359,7 @@ int omap_free_dma_chain(int chain_id)
dma_linked_lch[chain_id].linked_dmach_q = NULL;
dma_linked_lch[chain_id].chain_mode = -1;
dma_linked_lch[chain_id].chain_state = -1;
+
return (0);
}
EXPORT_SYMBOL(omap_free_dma_chain);
@@ -1218,7 +1375,7 @@ EXPORT_SYMBOL(omap_free_dma_chain);
int omap_dma_chain_status(int chain_id)
{
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1233,6 +1390,7 @@ int omap_dma_chain_status(int chain_id)
if (OMAP_DMA_CHAIN_QEMPTY(chain_id))
return OMAP_DMA_CHAIN_INACTIVE;
+
return OMAP_DMA_CHAIN_ACTIVE;
}
EXPORT_SYMBOL(omap_dma_chain_status);
@@ -1255,11 +1413,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
int elem_count, int frame_count, void *callbk_data)
{
int *channels;
- u32 w, lch;
+ u32 l, lch;
int start_dma = 0;
- /* if buffer size is less than 1 then there is
- * no use of starting the chain */
+ /*
+ * if buffer size is less than 1 then there is
+ * no use of starting the chain
+ */
if (elem_count < 1) {
printk(KERN_ERR "Invalid buffer size\n");
return -EINVAL;
@@ -1267,7 +1427,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Check for input params */
if (unlikely((chain_id < 0
- || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1296,20 +1456,24 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Set the params to the free channel */
if (src_start != 0)
- OMAP2_DMA_CSSA_REG(lch) = src_start;
+ dma_write(src_start, CSSA(lch));
if (dest_start != 0)
- OMAP2_DMA_CDSA_REG(lch) = dest_start;
+ dma_write(dest_start, CDSA(lch));
/* Write the buffer size */
- OMAP_DMA_CEN_REG(lch) = elem_count;
- OMAP_DMA_CFN_REG(lch) = frame_count;
+ dma_write(elem_count, CEN(lch));
+ dma_write(frame_count, CFN(lch));
- /* If the chain is dynamically linked,
- * then we may have to start the chain if its not active */
+ /*
+ * If the chain is dynamically linked,
+ * then we may have to start the chain if its not active
+ */
if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) {
- /* In Dynamic chain, if the chain is not started,
- * queue the channel */
+ /*
+ * In Dynamic chain, if the chain is not started,
+ * queue the channel
+ */
if (dma_linked_lch[chain_id].chain_state ==
DMA_CHAIN_NOTSTARTED) {
/* Enable the link in previous channel */
@@ -1319,8 +1483,10 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
dma_chan[lch].state = DMA_CH_QUEUED;
}
- /* Chain is already started, make sure its active,
- * if not then start the chain */
+ /*
+ * Chain is already started, make sure its active,
+ * if not then start the chain
+ */
else {
start_dma = 1;
@@ -1329,8 +1495,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
enable_lnk(dma_chan[lch].prev_linked_ch);
dma_chan[lch].state = DMA_CH_QUEUED;
start_dma = 0;
- if (0 == ((1 << 7) & (OMAP_DMA_CCR_REG
- (dma_chan[lch].prev_linked_ch)))) {
+ if (0 == ((1 << 7) & dma_read(
+ CCR(dma_chan[lch].prev_linked_ch)))) {
disable_lnk(dma_chan[lch].
prev_linked_ch);
pr_debug("\n prev ch is stopped\n");
@@ -1346,27 +1512,28 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
}
omap_enable_channel_irq(lch);
- w = OMAP_DMA_CCR_REG(lch);
+ l = dma_read(CCR(lch));
- if ((0 == (w & (1 << 24))))
- w &= ~(1 << 25);
+ if ((0 == (l & (1 << 24))))
+ l &= ~(1 << 25);
else
- w |= (1 << 25);
+ l |= (1 << 25);
if (start_dma == 1) {
- if (0 == (w & (1 << 7))) {
- w |= (1 << 7);
+ if (0 == (l & (1 << 7))) {
+ l |= (1 << 7);
dma_chan[lch].state = DMA_CH_STARTED;
pr_debug("starting %d\n", lch);
- OMAP_DMA_CCR_REG(lch) = w;
+ dma_write(l, CCR(lch));
} else
start_dma = 0;
} else {
- if (0 == (w & (1 << 7)))
- OMAP_DMA_CCR_REG(lch) = w;
+ if (0 == (l & (1 << 7)))
+ dma_write(l, CCR(lch));
}
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
}
+
return 0;
}
EXPORT_SYMBOL(omap_dma_chain_a_transfer);
@@ -1382,9 +1549,9 @@ EXPORT_SYMBOL(omap_dma_chain_a_transfer);
int omap_start_dma_chain_transfers(int chain_id)
{
int *channels;
- u32 w, i;
+ u32 l, i;
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1406,18 +1573,19 @@ int omap_start_dma_chain_transfers(int chain_id)
omap_enable_channel_irq(channels[0]);
}
- w = OMAP_DMA_CCR_REG(channels[0]);
- w |= (1 << 7);
+ l = dma_read(CCR(channels[0]));
+ l |= (1 << 7);
dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
dma_chan[channels[0]].state = DMA_CH_STARTED;
- if ((0 == (w & (1 << 24))))
- w &= ~(1 << 25);
+ if ((0 == (l & (1 << 24))))
+ l &= ~(1 << 25);
else
- w |= (1 << 25);
- OMAP_DMA_CCR_REG(channels[0]) = w;
+ l |= (1 << 25);
+ dma_write(l, CCR(channels[0]));
dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
+
return 0;
}
EXPORT_SYMBOL(omap_start_dma_chain_transfers);
@@ -1433,11 +1601,11 @@ EXPORT_SYMBOL(omap_start_dma_chain_transfers);
int omap_stop_dma_chain_transfers(int chain_id)
{
int *channels;
- u32 w, i;
+ u32 l, i;
u32 sys_cf;
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1449,21 +1617,22 @@ int omap_stop_dma_chain_transfers(int chain_id)
}
channels = dma_linked_lch[chain_id].linked_dmach_q;
- /* DMA Errata:
+ /*
+ * DMA Errata:
* Special programming model needed to disable DMA before end of block
*/
- sys_cf = omap_readl(OMAP_DMA4_OCP_SYSCONFIG);
- w = sys_cf;
+ sys_cf = dma_read(OCP_SYSCONFIG);
+ l = sys_cf;
/* Middle mode reg set no Standby */
- w &= ~((1 << 12)|(1 << 13));
- omap_writel(w, OMAP_DMA4_OCP_SYSCONFIG);
+ l &= ~((1 << 12)|(1 << 13));
+ dma_write(l, OCP_SYSCONFIG);
for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
/* Stop the Channel transmission */
- w = OMAP_DMA_CCR_REG(channels[i]);
- w &= ~(1 << 7);
- OMAP_DMA_CCR_REG(channels[i]) = w;
+ l = dma_read(CCR(channels[i]));
+ l &= ~(1 << 7);
+ dma_write(l, CCR(channels[i]));
/* Disable the link in all the channels */
disable_lnk(channels[i]);
@@ -1476,7 +1645,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
OMAP_DMA_CHAIN_QINIT(chain_id);
/* Errata - put in the old value */
- omap_writel(sys_cf, OMAP_DMA4_OCP_SYSCONFIG);
+ dma_write(sys_cf, OCP_SYSCONFIG);
+
return 0;
}
EXPORT_SYMBOL(omap_stop_dma_chain_transfers);
@@ -1499,7 +1669,7 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
int *channels;
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1517,8 +1687,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- *ei = OMAP2_DMA_CCEN_REG(lch);
- *fi = OMAP2_DMA_CCFN_REG(lch);
+ *ei = dma_read(CCEN(lch));
+ *fi = dma_read(CCFN(lch));
return 0;
}
@@ -1539,7 +1709,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
int *channels;
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1555,7 +1725,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return (OMAP_DMA_CDAC_REG(lch));
+ return dma_read(CDAC(lch));
}
EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
@@ -1573,7 +1743,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
int *channels;
/* Check for input params */
- if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
printk(KERN_ERR "Invalid chain id\n");
return -EINVAL;
}
@@ -1589,10 +1759,10 @@ int omap_get_dma_chain_src_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return (OMAP_DMA_CSAC_REG(lch));
+ return dma_read(CSAC(lch));
}
EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
-#endif
+#endif /* ifndef CONFIG_ARCH_OMAP1 */
/*----------------------------------------------------------------------------*/
@@ -1600,13 +1770,13 @@ EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
static int omap1_dma_handle_ch(int ch)
{
- u16 csr;
+ u32 csr;
if (enable_1510_mode && ch >= 6) {
csr = dma_chan[ch].saved_csr;
dma_chan[ch].saved_csr = 0;
} else
- csr = OMAP_DMA_CSR_REG(ch);
+ csr = dma_read(CSR(ch));
if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
dma_chan[ch + 6].saved_csr = csr >> 7;
csr &= 0x7f;
@@ -1628,6 +1798,7 @@ static int omap1_dma_handle_ch(int ch)
dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
+
return 1;
}
@@ -1658,12 +1829,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
static int omap2_dma_handle_ch(int ch)
{
- u32 status = OMAP_DMA_CSR_REG(ch);
+ u32 status = dma_read(CSR(ch));
if (!status) {
if (printk_ratelimit())
- printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch);
- omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0);
+ printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
+ ch);
+ dma_write(1 << ch, IRQSTATUS_L0);
return 0;
}
if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -1686,14 +1858,14 @@ static int omap2_dma_handle_ch(int ch)
printk(KERN_INFO "DMA misaligned error with device %d\n",
dma_chan[ch].dev_id);
- OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK;
- omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0);
+ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
+ dma_write(1 << ch, IRQSTATUS_L0);
/* If the ch is not chained then chain_id will be -1 */
if (dma_chan[ch].chain_id != -1) {
int chain_id = dma_chan[ch].chain_id;
dma_chan[ch].state = DMA_CH_NOTSTARTED;
- if (OMAP_DMA_CLNK_CTRL_REG(ch) & (1 << 15))
+ if (dma_read(CLNK_CTRL(ch)) & (1 << 15))
dma_chan[dma_chan[ch].next_linked_ch].state =
DMA_CH_STARTED;
if (dma_linked_lch[chain_id].chain_mode ==
@@ -1703,13 +1875,13 @@ static int omap2_dma_handle_ch(int ch)
if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
OMAP_DMA_CHAIN_INCQHEAD(chain_id);
- status = OMAP_DMA_CSR_REG(ch);
+ status = dma_read(CSR(ch));
}
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, status, dma_chan[ch].data);
- OMAP_DMA_CSR_REG(ch) = status;
+ dma_write(status, CSR(ch));
return 0;
}
@@ -1720,13 +1892,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
u32 val;
int i;
- val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
+ val = dma_read(IRQSTATUS_L0);
if (val == 0) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ\n");
return IRQ_HANDLED;
}
- for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) {
+ for (i = 0; i < dma_lch_count && val != 0; i++) {
if (val & 1)
omap2_dma_handle_ch(i);
val >>= 1;
@@ -1750,7 +1922,7 @@ static struct irqaction omap24xx_dma_irq;
static struct lcd_dma_info {
spinlock_t lock;
int reserved;
- void (* callback)(u16 status, void *data);
+ void (*callback)(u16 status, void *data);
void *cb_data;
int active;
@@ -1772,6 +1944,7 @@ void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
lcd_dma.xres = fb_xres;
lcd_dma.yres = fb_yres;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1);
void omap_set_lcd_dma_src_port(int port)
{
@@ -1782,12 +1955,13 @@ void omap_set_lcd_dma_ext_controller(int external)
{
lcd_dma.ext_ctrl = external;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
void omap_set_lcd_dma_single_transfer(int single)
{
lcd_dma.single_transfer = single;
}
-
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
void omap_set_lcd_dma_b1_rotation(int rotate)
{
@@ -1798,6 +1972,7 @@ void omap_set_lcd_dma_b1_rotation(int rotate)
}
lcd_dma.rotate = rotate;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
void omap_set_lcd_dma_b1_mirror(int mirror)
{
@@ -1807,6 +1982,7 @@ void omap_set_lcd_dma_b1_mirror(int mirror)
}
lcd_dma.mirror = mirror;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
{
@@ -1817,6 +1993,7 @@ void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
}
lcd_dma.vxres = vxres;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
{
@@ -1827,6 +2004,7 @@ void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
lcd_dma.xscale = xscale;
lcd_dma.yscale = yscale;
}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
static void set_b1_regs(void)
{
@@ -1857,8 +2035,11 @@ static void set_b1_regs(void)
xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
BUG_ON(vxres < lcd_dma.xres);
-#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
+
+#define PIXADDR(x, y) (lcd_dma.addr + \
+ ((y) * vxres * yscale + (x) * xscale) * es)
#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+
switch (lcd_dma.rotate) {
case 0:
if (!lcd_dma.mirror) {
@@ -1867,8 +2048,8 @@ static void set_b1_regs(void)
/* 1510 DMA requires the bottom address to be 2 more
* than the actual last memory access location. */
if (omap_dma_in_1510_mode() &&
- lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
- bottom += 2;
+ lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+ bottom += 2;
ei = PIXSTEP(0, 0, 1, 0);
fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
} else {
@@ -1995,7 +2176,7 @@ static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
+int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
void *data)
{
spin_lock_irq(&lcd_dma.lock);
@@ -2021,6 +2202,7 @@ int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
return 0;
}
+EXPORT_SYMBOL(omap_request_lcd_dma);
void omap_free_lcd_dma(void)
{
@@ -2037,12 +2219,14 @@ void omap_free_lcd_dma(void)
lcd_dma.reserved = 0;
spin_unlock(&lcd_dma.lock);
}
+EXPORT_SYMBOL(omap_free_lcd_dma);
void omap_enable_lcd_dma(void)
{
u16 w;
- /* Set the Enable bit only if an external controller is
+ /*
+ * Set the Enable bit only if an external controller is
* connected. Otherwise the OMAP internal controller will
* start the transfer when it gets enabled.
*/
@@ -2059,6 +2243,7 @@ void omap_enable_lcd_dma(void)
w |= 1 << 7;
omap_writew(w, OMAP1610_DMA_LCD_CCR);
}
+EXPORT_SYMBOL(omap_enable_lcd_dma);
void omap_setup_lcd_dma(void)
{
@@ -2074,16 +2259,18 @@ void omap_setup_lcd_dma(void)
u16 w;
w = omap_readw(OMAP1610_DMA_LCD_CCR);
- /* If DMA was already active set the end_prog bit to have
+ /*
+ * If DMA was already active set the end_prog bit to have
* the programmed register set loaded into the active
* register set.
*/
w |= 1 << 11; /* End_prog */
if (!lcd_dma.single_transfer)
- w |= (3 << 8); /* Auto_init, repeat */
+ w |= (3 << 8); /* Auto_init, repeat */
omap_writew(w, OMAP1610_DMA_LCD_CCR);
}
}
+EXPORT_SYMBOL(omap_setup_lcd_dma);
void omap_stop_lcd_dma(void)
{
@@ -2101,6 +2288,7 @@ void omap_stop_lcd_dma(void)
w &= ~(1 << 8);
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
}
+EXPORT_SYMBOL(omap_stop_lcd_dma);
/*----------------------------------------------------------------------------*/
@@ -2108,27 +2296,55 @@ static int __init omap_init_dma(void)
{
int ch, r;
+ if (cpu_class_is_omap1()) {
+ omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE);
+ dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
+ } else if (cpu_is_omap24xx()) {
+ omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE);
+ dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
+ } else if (cpu_is_omap34xx()) {
+ omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE);
+ dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
+ } else {
+ pr_err("DMA init failed for unsupported omap\n");
+ return -ENODEV;
+ }
+
+ dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
+ GFP_KERNEL);
+ if (!dma_chan)
+ return -ENOMEM;
+
+ if (cpu_class_is_omap2()) {
+ dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
+ dma_lch_count, GFP_KERNEL);
+ if (!dma_linked_lch) {
+ kfree(dma_chan);
+ return -ENOMEM;
+ }
+ }
+
if (cpu_is_omap15xx()) {
printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
dma_chan_count = 9;
enable_1510_mode = 1;
} else if (cpu_is_omap16xx() || cpu_is_omap730()) {
printk(KERN_INFO "OMAP DMA hardware version %d\n",
- omap_readw(OMAP_DMA_HW_ID));
+ dma_read(HW_ID));
printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (omap_readw(OMAP_DMA_CAPS_0_U) << 16) |
- omap_readw(OMAP_DMA_CAPS_0_L),
- (omap_readw(OMAP_DMA_CAPS_1_U) << 16) |
- omap_readw(OMAP_DMA_CAPS_1_L),
- omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
- omap_readw(OMAP_DMA_CAPS_4));
+ (dma_read(CAPS_0_U) << 16) |
+ dma_read(CAPS_0_L),
+ (dma_read(CAPS_1_U) << 16) |
+ dma_read(CAPS_1_L),
+ dma_read(CAPS_2), dma_read(CAPS_3),
+ dma_read(CAPS_4));
if (!enable_1510_mode) {
u16 w;
/* Disable OMAP 3.0/3.1 compatibility mode. */
- w = omap_readw(OMAP_DMA_GSCR);
+ w = dma_read(GSCR);
w |= 1 << 3;
- omap_writew(w, OMAP_DMA_GSCR);
+ dma_write(w, GSCR);
dma_chan_count = 16;
} else
dma_chan_count = 9;
@@ -2141,19 +2357,17 @@ static int __init omap_init_dma(void)
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
}
} else if (cpu_class_is_omap2()) {
- u8 revision = omap_readb(OMAP_DMA4_REVISION);
+ u8 revision = dma_read(REVISION) & 0xff;
printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
revision >> 4, revision & 0xf);
- dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
+ dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
} else {
dma_chan_count = 0;
return 0;
}
- memset(&lcd_dma, 0, sizeof(lcd_dma));
spin_lock_init(&lcd_dma.lock);
spin_lock_init(&dma_chan_lock);
- memset(&dma_chan, 0, sizeof(dma_chan));
for (ch = 0; ch < dma_chan_count; ch++) {
omap_clear_dma(ch);
@@ -2164,8 +2378,10 @@ static int __init omap_init_dma(void)
continue;
if (cpu_class_is_omap1()) {
- /* request_irq() doesn't like dev_id (ie. ch) being
- * zero, so we have to kludge around this. */
+ /*
+ * request_irq() doesn't like dev_id (ie. ch) being
+ * zero, so we have to kludge around this.
+ */
r = request_irq(omap1_dma_irq[ch],
omap1_dma_irq_handler, 0, "DMA",
(void *) (ch + 1));
@@ -2210,48 +2426,4 @@ static int __init omap_init_dma(void)
arch_initcall(omap_init_dma);
-EXPORT_SYMBOL(omap_get_dma_src_pos);
-EXPORT_SYMBOL(omap_get_dma_dst_pos);
-EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
-EXPORT_SYMBOL(omap_clear_dma);
-EXPORT_SYMBOL(omap_set_dma_priority);
-EXPORT_SYMBOL(omap_request_dma);
-EXPORT_SYMBOL(omap_free_dma);
-EXPORT_SYMBOL(omap_start_dma);
-EXPORT_SYMBOL(omap_stop_dma);
-EXPORT_SYMBOL(omap_set_dma_callback);
-EXPORT_SYMBOL(omap_enable_dma_irq);
-EXPORT_SYMBOL(omap_disable_dma_irq);
-
-EXPORT_SYMBOL(omap_set_dma_transfer_params);
-EXPORT_SYMBOL(omap_set_dma_color_mode);
-EXPORT_SYMBOL(omap_set_dma_write_mode);
-
-EXPORT_SYMBOL(omap_set_dma_src_params);
-EXPORT_SYMBOL(omap_set_dma_src_index);
-EXPORT_SYMBOL(omap_set_dma_src_data_pack);
-EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
-
-EXPORT_SYMBOL(omap_set_dma_dest_params);
-EXPORT_SYMBOL(omap_set_dma_dest_index);
-EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
-EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
-
-EXPORT_SYMBOL(omap_set_dma_params);
-
-EXPORT_SYMBOL(omap_dma_link_lch);
-EXPORT_SYMBOL(omap_dma_unlink_lch);
-
-EXPORT_SYMBOL(omap_request_lcd_dma);
-EXPORT_SYMBOL(omap_free_lcd_dma);
-EXPORT_SYMBOL(omap_enable_lcd_dma);
-EXPORT_SYMBOL(omap_setup_lcd_dma);
-EXPORT_SYMBOL(omap_stop_lcd_dma);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1);
-EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
-EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 302ad8dff2c..f22506af0e6 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -38,34 +38,113 @@
#include <asm/arch/irqs.h>
/* register offsets */
-#define OMAP_TIMER_ID_REG 0x00
-#define OMAP_TIMER_OCP_CFG_REG 0x10
-#define OMAP_TIMER_SYS_STAT_REG 0x14
-#define OMAP_TIMER_STAT_REG 0x18
-#define OMAP_TIMER_INT_EN_REG 0x1c
-#define OMAP_TIMER_WAKEUP_EN_REG 0x20
-#define OMAP_TIMER_CTRL_REG 0x24
-#define OMAP_TIMER_COUNTER_REG 0x28
-#define OMAP_TIMER_LOAD_REG 0x2c
-#define OMAP_TIMER_TRIGGER_REG 0x30
-#define OMAP_TIMER_WRITE_PEND_REG 0x34
-#define OMAP_TIMER_MATCH_REG 0x38
-#define OMAP_TIMER_CAPTURE_REG 0x3c
-#define OMAP_TIMER_IF_CTRL_REG 0x40
-
-/* timer control reg bits */
-#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
-#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
-#define OMAP_TIMER_CTRL_PT (1 << 12)
-#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
-#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
-#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
-#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
-#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
-#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
-#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* how much to shift the prescaler value */
-#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
-#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
+#define _OMAP_TIMER_ID_OFFSET 0x00
+#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10
+#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14
+#define _OMAP_TIMER_STAT_OFFSET 0x18
+#define _OMAP_TIMER_INT_EN_OFFSET 0x1c
+#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20
+#define _OMAP_TIMER_CTRL_OFFSET 0x24
+#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
+#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
+#define OMAP_TIMER_CTRL_PT (1 << 12)
+#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
+#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
+#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
+#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
+#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
+#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
+#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */
+#define OMAP_TIMER_CTRL_POSTED (1 << 2)
+#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
+#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
+#define _OMAP_TIMER_COUNTER_OFFSET 0x28
+#define _OMAP_TIMER_LOAD_OFFSET 0x2c
+#define _OMAP_TIMER_TRIGGER_OFFSET 0x30
+#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34
+#define WP_NONE 0 /* no write pending bit */
+#define WP_TCLR (1 << 0)
+#define WP_TCRR (1 << 1)
+#define WP_TLDR (1 << 2)
+#define WP_TTGR (1 << 3)
+#define WP_TMAR (1 << 4)
+#define WP_TPIR (1 << 5)
+#define WP_TNIR (1 << 6)
+#define WP_TCVR (1 << 7)
+#define WP_TOCR (1 << 8)
+#define WP_TOWR (1 << 9)
+#define _OMAP_TIMER_MATCH_OFFSET 0x38
+#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c
+#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40
+#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44 /* TCAR2, 34xx only */
+#define _OMAP_TIMER_TICK_POS_OFFSET 0x48 /* TPIR, 34xx only */
+#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c /* TNIR, 34xx only */
+#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50 /* TCVR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54 /* TOCR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58 /* TOWR, 34xx only */
+
+/* register offsets with the write pending bit encoded */
+#define WPSHIFT 16
+
+#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CTRL_REG (_OMAP_TIMER_CTRL_OFFSET \
+ | (WP_TCLR << WPSHIFT))
+
+#define OMAP_TIMER_COUNTER_REG (_OMAP_TIMER_COUNTER_OFFSET \
+ | (WP_TCRR << WPSHIFT))
+
+#define OMAP_TIMER_LOAD_REG (_OMAP_TIMER_LOAD_OFFSET \
+ | (WP_TLDR << WPSHIFT))
+
+#define OMAP_TIMER_TRIGGER_REG (_OMAP_TIMER_TRIGGER_OFFSET \
+ | (WP_TTGR << WPSHIFT))
+
+#define OMAP_TIMER_WRITE_PEND_REG (_OMAP_TIMER_WRITE_PEND_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_MATCH_REG (_OMAP_TIMER_MATCH_OFFSET \
+ | (WP_TMAR << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE_REG (_OMAP_TIMER_CAPTURE_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_IF_CTRL_REG (_OMAP_TIMER_IF_CTRL_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE2_REG (_OMAP_TIMER_CAPTURE2_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_TICK_POS_REG (_OMAP_TIMER_TICK_POS_OFFSET \
+ | (WP_TPIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_NEG_REG (_OMAP_TIMER_TICK_NEG_OFFSET \
+ | (WP_TNIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_COUNT_REG (_OMAP_TIMER_TICK_COUNT_OFFSET \
+ | (WP_TCVR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_SET_REG \
+ (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
+ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
struct omap_dm_timer {
unsigned long phys_base;
@@ -76,6 +155,7 @@ struct omap_dm_timer {
void __iomem *io_base;
unsigned reserved:1;
unsigned enabled:1;
+ unsigned posted:1;
};
#ifdef CONFIG_ARCH_OMAP1
@@ -181,16 +261,34 @@ static struct clk **dm_source_clocks;
static spinlock_t dm_timer_lock;
-static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
+/*
+ * Reads timer registers in posted and non-posted mode. The posted mode bit
+ * is encoded in reg. Note that in posted mode write pending bit must be
+ * checked. Otherwise a read of a non completed write will produce an error.
+ */
+static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
{
- return readl(timer->io_base + reg);
+ if (timer->posted)
+ while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+ & (reg >> WPSHIFT))
+ cpu_relax();
+ return readl(timer->io_base + (reg & 0xff));
}
-static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
+/*
+ * Writes timer registers in posted and non-posted mode. The posted mode bit
+ * is encoded in reg. Note that in posted mode the write pending bit must be
+ * checked. Otherwise a write on a register which has a pending write will be
+ * lost.
+ */
+static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
+ u32 value)
{
- writel(value, timer->io_base + reg);
- while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
- ;
+ if (timer->posted)
+ while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+ & (reg >> WPSHIFT))
+ cpu_relax();
+ writel(value, timer->io_base + (reg & 0xff));
}
static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
@@ -217,17 +315,23 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
}
omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
- /* Set to smart-idle mode */
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
- l |= 0x02 << 3;
-
- if (cpu_class_is_omap2() && timer == &dm_timers[0]) {
- /* Enable wake-up only for GPT1 on OMAP2 CPUs*/
+ l |= 0x02 << 3; /* Set to smart-idle mode */
+ l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
+
+ /*
+ * Enable wake-up only for GPT1 on OMAP2 CPUs.
+ * FIXME: All timers should have wake-up enabled and clear
+ * PRCM status.
+ */
+ if (cpu_class_is_omap2() && (timer == &dm_timers[0]))
l |= 1 << 2;
- /* Non-posted mode */
- omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0);
- }
omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
+
+ /* Match hardware reset default of posted mode */
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->posted = 1;
}
static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
@@ -434,9 +538,32 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
l &= ~OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+
+ /* REVISIT: hw feature, ttgr overtaking tldr? */
+ while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)))
+ cpu_relax();
+
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
}
+/* Optimized set_load which removes costly spin wait in timer_start */
+void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
+ unsigned int load)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (autoreload)
+ l |= OMAP_TIMER_CTRL_AR;
+ else
+ l &= ~OMAP_TIMER_CTRL_AR;
+ l |= OMAP_TIMER_CTRL_ST;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
unsigned int match)
{
@@ -451,7 +578,6 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
}
-
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger)
{
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 9cf83c4da9f..c7f74064696 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -15,95 +15,66 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
#include <asm/arch/dma.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/dsp_common.h>
#include <asm/arch/mcbsp.h>
-#ifdef CONFIG_MCBSP_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...) do { } while (0)
-#endif
-
-struct omap_mcbsp {
- u32 io_base;
- u8 id;
- u8 free;
- omap_mcbsp_word_length rx_word_length;
- omap_mcbsp_word_length tx_word_length;
-
- omap_mcbsp_io_type_t io_type; /* IRQ or poll */
- /* IRQ based TX/RX */
- int rx_irq;
- int tx_irq;
-
- /* DMA stuff */
- u8 dma_rx_sync;
- short dma_rx_lch;
- u8 dma_tx_sync;
- short dma_tx_lch;
-
- /* Completion queues */
- struct completion tx_irq_completion;
- struct completion rx_irq_completion;
- struct completion tx_dma_completion;
- struct completion rx_dma_completion;
-
- spinlock_t lock;
-};
-
static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
-#ifdef CONFIG_ARCH_OMAP1
-static struct clk *mcbsp_dsp_ck = 0;
-static struct clk *mcbsp_api_ck = 0;
-static struct clk *mcbsp_dspxor_ck = 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP2
-static struct clk *mcbsp1_ick = 0;
-static struct clk *mcbsp1_fck = 0;
-static struct clk *mcbsp2_ick = 0;
-static struct clk *mcbsp2_fck = 0;
-#endif
+
+#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \
+ mcbsp[id].pdata->ops && \
+ mcbsp[id].pdata->ops->check && \
+ (mcbsp[id].pdata->ops->check(id) == 0))
static void omap_mcbsp_dump_reg(u8 id)
{
- DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
- DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
- DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
- DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
- DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
- DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
- DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
- DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
- DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
- DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
- DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
- DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
- DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
- DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
- DBG("***********************\n");
+ dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
+ dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
+ dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
+ dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
+ dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
+ dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
+ dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
+ dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
+ dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
+ dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
+ dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
+ dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
+ dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
+ dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
+ dev_dbg(mcbsp[id].dev, "***********************\n");
}
static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_tx = dev_id;
- DBG("TX IRQ callback : 0x%x\n",
- OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
+ dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
+ OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
complete(&mcbsp_tx->tx_irq_completion);
+
return IRQ_HANDLED;
}
@@ -111,10 +82,11 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_rx = dev_id;
- DBG("RX IRQ callback : 0x%x\n",
- OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
+ dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
+ OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
complete(&mcbsp_rx->rx_irq_completion);
+
return IRQ_HANDLED;
}
@@ -122,8 +94,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_mcbsp *mcbsp_dma_tx = data;
- DBG("TX DMA callback : 0x%x\n",
- OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+ dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
+ OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
/* We can free the channels */
omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -136,8 +108,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_mcbsp *mcbsp_dma_rx = data;
- DBG("RX DMA callback : 0x%x\n",
- OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+ dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
+ OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
/* We can free the channels */
omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
@@ -146,19 +118,24 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
complete(&mcbsp_dma_rx->rx_dma_completion);
}
-
/*
* omap_mcbsp_config simply write a config to the
* appropriate McBSP.
* You either call this function or set the McBSP registers
* by yourself before calling omap_mcbsp_start().
*/
-
-void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
{
- u32 io_base = mcbsp[id].io_base;
+ u32 io_base;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
- DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
+ io_base = mcbsp[id].io_base;
+ dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n",
+ mcbsp[id].id, io_base);
/* We write the given config */
OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -173,83 +150,7 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config
OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
}
-
-
-
-static int omap_mcbsp_check(unsigned int id)
-{
- if (cpu_is_omap730()) {
- if (id > OMAP_MAX_MCBSP_COUNT - 1) {
- printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
- return -1;
- }
- return 0;
- }
-
- if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
- if (id > OMAP_MAX_MCBSP_COUNT) {
- printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
- return -1;
- }
- return 0;
- }
-
- return -1;
-}
-
-#ifdef CONFIG_ARCH_OMAP1
-static void omap_mcbsp_dsp_request(void)
-{
- if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
- int ret;
-
- ret = omap_dsp_request_mem();
- if (ret < 0) {
- printk(KERN_ERR "Could not get dsp memory: %i\n", ret);
- return;
- }
-
- clk_enable(mcbsp_dsp_ck);
- clk_enable(mcbsp_api_ck);
-
- /* enable 12MHz clock to mcbsp 1 & 3 */
- clk_enable(mcbsp_dspxor_ck);
-
- /*
- * DSP external peripheral reset
- * FIXME: This should be moved to dsp code
- */
- __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
- DSP_RSTCT2);
- }
-}
-
-static void omap_mcbsp_dsp_free(void)
-{
- if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
- omap_dsp_release_mem();
- clk_disable(mcbsp_dspxor_ck);
- clk_disable(mcbsp_dsp_ck);
- clk_disable(mcbsp_api_ck);
- }
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
-static void omap2_mcbsp2_mux_setup(void)
-{
- if (cpu_is_omap2420()) {
- omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
- omap_cfg_reg(R14_24XX_MCBSP2_FSX);
- omap_cfg_reg(W15_24XX_MCBSP2_DR);
- omap_cfg_reg(V15_24XX_MCBSP2_DX);
- omap_cfg_reg(V14_24XX_GPIO117);
- }
- /*
- * Need to add MUX settings for OMAP 2430 SDP
- */
-}
-#endif
+EXPORT_SYMBOL(omap_mcbsp_config);
/*
* We can choose between IRQ based or polled IO.
@@ -257,13 +158,16 @@ static void omap2_mcbsp2_mux_setup(void)
*/
int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
{
- if (omap_mcbsp_check(id) < 0)
- return -EINVAL;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
spin_lock(&mcbsp[id].lock);
if (!mcbsp[id].free) {
- printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
+ dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
+ mcbsp[id].id);
spin_unlock(&mcbsp[id].lock);
return -EINVAL;
}
@@ -274,38 +178,26 @@ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
return 0;
}
+EXPORT_SYMBOL(omap_mcbsp_set_io_type);
int omap_mcbsp_request(unsigned int id)
{
int err;
- if (omap_mcbsp_check(id) < 0)
- return -EINVAL;
-
-#ifdef CONFIG_ARCH_OMAP1
- /*
- * On 1510, 1610 and 1710, McBSP1 and McBSP3
- * are DSP public peripherals.
- */
- if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
- omap_mcbsp_dsp_request();
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
- if (cpu_is_omap24xx()) {
- if (id == OMAP_MCBSP1) {
- clk_enable(mcbsp1_ick);
- clk_enable(mcbsp1_fck);
- } else {
- clk_enable(mcbsp2_ick);
- clk_enable(mcbsp2_fck);
- }
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
}
-#endif
+
+ if (mcbsp[id].pdata->ops->request)
+ mcbsp[id].pdata->ops->request(id);
+
+ clk_enable(mcbsp[id].clk);
spin_lock(&mcbsp[id].lock);
if (!mcbsp[id].free) {
- printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
+ dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
+ mcbsp[id].id);
spin_unlock(&mcbsp[id].lock);
return -1;
}
@@ -315,24 +207,23 @@ int omap_mcbsp_request(unsigned int id)
if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
/* We need to get IRQs here */
- err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
- "McBSP",
- (void *) (&mcbsp[id]));
+ err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
+ 0, "McBSP", (void *) (&mcbsp[id]));
if (err != 0) {
- printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
- mcbsp[id].tx_irq, mcbsp[id].id);
+ dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
+ "for McBSP%d\n", mcbsp[id].tx_irq,
+ mcbsp[id].id);
return err;
}
init_completion(&(mcbsp[id].tx_irq_completion));
-
- err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
- "McBSP",
- (void *) (&mcbsp[id]));
+ err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
+ 0, "McBSP", (void *) (&mcbsp[id]));
if (err != 0) {
- printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
- mcbsp[id].rx_irq, mcbsp[id].id);
+ dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
+ "for McBSP%d\n", mcbsp[id].rx_irq,
+ mcbsp[id].id);
free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
return err;
}
@@ -341,36 +232,25 @@ int omap_mcbsp_request(unsigned int id)
}
return 0;
-
}
+EXPORT_SYMBOL(omap_mcbsp_request);
void omap_mcbsp_free(unsigned int id)
{
- if (omap_mcbsp_check(id) < 0)
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
-
-#ifdef CONFIG_ARCH_OMAP1
- if (cpu_class_is_omap1()) {
- if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
- omap_mcbsp_dsp_free();
}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
- if (cpu_is_omap24xx()) {
- if (id == OMAP_MCBSP1) {
- clk_disable(mcbsp1_ick);
- clk_disable(mcbsp1_fck);
- } else {
- clk_disable(mcbsp2_ick);
- clk_disable(mcbsp2_fck);
- }
- }
-#endif
+
+ if (mcbsp[id].pdata->ops->free)
+ mcbsp[id].pdata->ops->free(id);
+
+ clk_disable(mcbsp[id].clk);
spin_lock(&mcbsp[id].lock);
if (mcbsp[id].free) {
- printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
+ dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
+ mcbsp[id].id);
spin_unlock(&mcbsp[id].lock);
return;
}
@@ -384,6 +264,7 @@ void omap_mcbsp_free(unsigned int id)
free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
}
}
+EXPORT_SYMBOL(omap_mcbsp_free);
/*
* Here we start the McBSP, by enabling the sample
@@ -395,13 +276,15 @@ void omap_mcbsp_start(unsigned int id)
u32 io_base;
u16 w;
- if (omap_mcbsp_check(id) < 0)
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
+ }
io_base = mcbsp[id].io_base;
- mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
- mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
+ mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
+ mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
/* Start the sample generator */
w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -422,20 +305,22 @@ void omap_mcbsp_start(unsigned int id)
/* Dump McBSP Regs */
omap_mcbsp_dump_reg(id);
-
}
+EXPORT_SYMBOL(omap_mcbsp_start);
void omap_mcbsp_stop(unsigned int id)
{
u32 io_base;
u16 w;
- if (omap_mcbsp_check(id) < 0)
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
+ }
io_base = mcbsp[id].io_base;
- /* Reset transmitter */
+ /* Reset transmitter */
w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
@@ -447,12 +332,19 @@ void omap_mcbsp_stop(unsigned int id)
w = OMAP_MCBSP_READ(io_base, SPCR2);
OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
}
-
+EXPORT_SYMBOL(omap_mcbsp_stop);
/* polled mcbsp i/o operations */
int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
{
- u32 base = mcbsp[id].io_base;
+ u32 base;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ base = mcbsp[id].io_base;
writew(buf, base + OMAP_MCBSP_REG_DXR1);
/* if frame sync error - clear the error */
if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -474,18 +366,27 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
(XRST),
base + OMAP_MCBSP_REG_SPCR2);
udelay(10);
- printk(KERN_ERR
- " Could not write to McBSP Register\n");
+ dev_err(mcbsp[id].dev, "Could not write to"
+ " McBSP%d Register\n", mcbsp[id].id);
return -2;
}
}
}
+
return 0;
}
+EXPORT_SYMBOL(omap_mcbsp_pollwrite);
-int omap_mcbsp_pollread(unsigned int id, u16 * buf)
+int omap_mcbsp_pollread(unsigned int id, u16 *buf)
{
- u32 base = mcbsp[id].io_base;
+ u32 base;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ base = mcbsp[id].io_base;
/* if frame sync error - clear the error */
if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
/* clear error */
@@ -506,15 +407,17 @@ int omap_mcbsp_pollread(unsigned int id, u16 * buf)
(RRST),
base + OMAP_MCBSP_REG_SPCR1);
udelay(10);
- printk(KERN_ERR
- " Could not read from McBSP Register\n");
+ dev_err(mcbsp[id].dev, "Could not read from"
+ " McBSP%d Register\n", mcbsp[id].id);
return -2;
}
}
}
*buf = readw(base + OMAP_MCBSP_REG_DRR1);
+
return 0;
}
+EXPORT_SYMBOL(omap_mcbsp_pollread);
/*
* IRQ based word transmission.
@@ -522,12 +425,15 @@ int omap_mcbsp_pollread(unsigned int id, u16 * buf)
void omap_mcbsp_xmit_word(unsigned int id, u32 word)
{
u32 io_base;
- omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
+ omap_mcbsp_word_length word_length;
- if (omap_mcbsp_check(id) < 0)
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
+ }
io_base = mcbsp[id].io_base;
+ word_length = mcbsp[id].tx_word_length;
wait_for_completion(&(mcbsp[id].tx_irq_completion));
@@ -535,16 +441,20 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
}
+EXPORT_SYMBOL(omap_mcbsp_xmit_word);
u32 omap_mcbsp_recv_word(unsigned int id)
{
u32 io_base;
u16 word_lsb, word_msb = 0;
- omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
+ omap_mcbsp_word_length word_length;
- if (omap_mcbsp_check(id) < 0)
- return -EINVAL;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ word_length = mcbsp[id].rx_word_length;
io_base = mcbsp[id].io_base;
wait_for_completion(&(mcbsp[id].rx_irq_completion));
@@ -555,15 +465,24 @@ u32 omap_mcbsp_recv_word(unsigned int id)
return (word_lsb | (word_msb << 16));
}
-
+EXPORT_SYMBOL(omap_mcbsp_recv_word);
int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
{
- u32 io_base = mcbsp[id].io_base;
- omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
- omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
+ u32 io_base;
+ omap_mcbsp_word_length tx_word_length;
+ omap_mcbsp_word_length rx_word_length;
u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ io_base = mcbsp[id].io_base;
+ tx_word_length = mcbsp[id].tx_word_length;
+ rx_word_length = mcbsp[id].rx_word_length;
+
if (tx_word_length != rx_word_length)
return -EINVAL;
@@ -577,7 +496,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
udelay(10);
- printk("McBSP transmitter not ready\n");
+ dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp[id].id);
return -EAGAIN;
}
}
@@ -597,7 +517,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
udelay(10);
- printk("McBSP receiver not ready\n");
+ dev_err(mcbsp[id].dev, "McBSP%d receiver not "
+ "ready\n", mcbsp[id].id);
return -EAGAIN;
}
}
@@ -609,14 +530,24 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
return 0;
}
+EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
-int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
{
- u32 io_base = mcbsp[id].io_base, clock_word = 0;
- omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
- omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
+ u32 io_base, clock_word = 0;
+ omap_mcbsp_word_length tx_word_length;
+ omap_mcbsp_word_length rx_word_length;
u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ io_base = mcbsp[id].io_base;
+ tx_word_length = mcbsp[id].tx_word_length;
+ rx_word_length = mcbsp[id].rx_word_length;
+
if (tx_word_length != rx_word_length)
return -EINVAL;
@@ -630,7 +561,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
udelay(10);
- printk("McBSP transmitter not ready\n");
+ dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp[id].id);
return -EAGAIN;
}
}
@@ -650,7 +582,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
udelay(10);
- printk("McBSP receiver not ready\n");
+ dev_err(mcbsp[id].dev, "McBSP%d receiver not "
+ "ready\n", mcbsp[id].id);
return -EAGAIN;
}
}
@@ -664,7 +597,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
return 0;
}
-
+EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
/*
* Simple DMA based buffer rx/tx routines.
@@ -673,25 +606,32 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
* For anything fancier, you should use your own customized DMA
* routines and callbacks.
*/
-int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
+ unsigned int length)
{
int dma_tx_ch;
int src_port = 0;
int dest_port = 0;
int sync_dev = 0;
- if (omap_mcbsp_check(id) < 0)
- return -EINVAL;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
- if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
- &mcbsp[id],
- &dma_tx_ch)) {
- printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
+ if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
+ omap_mcbsp_tx_dma_callback,
+ &mcbsp[id],
+ &dma_tx_ch)) {
+ dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
+ "McBSP%d TX. Trying IRQ based TX\n",
+ mcbsp[id].id);
return -EAGAIN;
}
mcbsp[id].dma_tx_lch = dma_tx_ch;
- DBG("TX DMA on channel %d\n", dma_tx_ch);
+ dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
+ dma_tx_ch);
init_completion(&(mcbsp[id].tx_dma_completion));
@@ -699,7 +639,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
src_port = OMAP_DMA_PORT_TIPB;
dest_port = OMAP_DMA_PORT_EMIFF;
}
- if (cpu_is_omap24xx())
+ if (cpu_class_is_omap2())
sync_dev = mcbsp[id].dma_tx_sync;
omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
@@ -722,29 +662,37 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
omap_start_dma(mcbsp[id].dma_tx_lch);
wait_for_completion(&(mcbsp[id].tx_dma_completion));
+
return 0;
}
+EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
-
-int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
+ unsigned int length)
{
int dma_rx_ch;
int src_port = 0;
int dest_port = 0;
int sync_dev = 0;
- if (omap_mcbsp_check(id) < 0)
- return -EINVAL;
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
- if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
- &mcbsp[id],
- &dma_rx_ch)) {
- printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
+ if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
+ omap_mcbsp_rx_dma_callback,
+ &mcbsp[id],
+ &dma_rx_ch)) {
+ dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
+ "McBSP%d RX. Trying IRQ based RX\n",
+ mcbsp[id].id);
return -EAGAIN;
}
mcbsp[id].dma_rx_lch = dma_rx_ch;
- DBG("RX DMA on channel %d\n", dma_rx_ch);
+ dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
+ dma_rx_ch);
init_completion(&(mcbsp[id].rx_dma_completion));
@@ -752,14 +700,14 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
src_port = OMAP_DMA_PORT_TIPB;
dest_port = OMAP_DMA_PORT_EMIFF;
}
- if (cpu_is_omap24xx())
+ if (cpu_class_is_omap2())
sync_dev = mcbsp[id].dma_rx_sync;
omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
- OMAP_DMA_DATA_TYPE_S16,
- length >> 1, 1,
- OMAP_DMA_SYNC_ELEMENT,
- sync_dev, 0);
+ OMAP_DMA_DATA_TYPE_S16,
+ length >> 1, 1,
+ OMAP_DMA_SYNC_ELEMENT,
+ sync_dev, 0);
omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
src_port,
@@ -768,16 +716,17 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
0, 0);
omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
- dest_port,
- OMAP_DMA_AMODE_POST_INC,
- buffer,
- 0, 0);
+ dest_port,
+ OMAP_DMA_AMODE_POST_INC,
+ buffer,
+ 0, 0);
omap_start_dma(mcbsp[id].dma_rx_lch);
wait_for_completion(&(mcbsp[id].rx_dma_completion));
+
return 0;
}
-
+EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
/*
* SPI wrapper.
@@ -785,12 +734,15 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
* this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
* Once this is done, you can call omap_mcbsp_start().
*/
-void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
+void omap_mcbsp_set_spi_mode(unsigned int id,
+ const struct omap_mcbsp_spi_cfg *spi_cfg)
{
struct omap_mcbsp_reg_cfg mcbsp_cfg;
- if (omap_mcbsp_check(id) < 0)
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
+ }
memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
@@ -798,7 +750,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *
mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
- /* Clock stop mode */
+ /* Clock stop mode */
if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
mcbsp_cfg.spcr1 |= (1 << 12);
else
@@ -827,13 +779,12 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *
if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
mcbsp_cfg.pcr0 |= CLKXM;
- mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
+ mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
mcbsp_cfg.pcr0 |= FSXM;
mcbsp_cfg.srgr2 &= ~FSGM;
mcbsp_cfg.xcr2 |= XDATDLY(1);
mcbsp_cfg.rcr2 |= RDATDLY(1);
- }
- else {
+ } else {
mcbsp_cfg.pcr0 &= ~CLKXM;
mcbsp_cfg.srgr1 |= CLKGDV(1);
mcbsp_cfg.pcr0 &= ~FSXM;
@@ -846,199 +797,99 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *
omap_mcbsp_config(id, &mcbsp_cfg);
}
-
+EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
/*
* McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
* 730 has only 2 McBSP, and both of them are MPU peripherals.
*/
-struct omap_mcbsp_info {
- u32 virt_base;
- u8 dma_rx_sync, dma_tx_sync;
- u16 rx_irq, tx_irq;
-};
+static int __init omap_mcbsp_probe(struct platform_device *pdev)
+{
+ struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
+ int id = pdev->id - 1;
+ int ret = 0;
-#ifdef CONFIG_ARCH_OMAP730
-static const struct omap_mcbsp_info mcbsp_730[] = {
- [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
- .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
- .rx_irq = INT_730_McBSP1RX,
- .tx_irq = INT_730_McBSP1TX },
- [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
- .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
- .rx_irq = INT_730_McBSP2RX,
- .tx_irq = INT_730_McBSP2TX },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP15XX
-static const struct omap_mcbsp_info mcbsp_1510[] = {
- [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
- .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
- .rx_irq = INT_McBSP1RX,
- .tx_irq = INT_McBSP1TX },
- [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
- .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
- .rx_irq = INT_1510_SPI_RX,
- .tx_irq = INT_1510_SPI_TX },
- [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
- .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
- .rx_irq = INT_McBSP3RX,
- .tx_irq = INT_McBSP3TX },
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static const struct omap_mcbsp_info mcbsp_1610[] = {
- [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
- .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
- .rx_irq = INT_McBSP1RX,
- .tx_irq = INT_McBSP1TX },
- [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
- .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
- .rx_irq = INT_1610_McBSP2_RX,
- .tx_irq = INT_1610_McBSP2_TX },
- [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
- .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
- .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
- .rx_irq = INT_McBSP3RX,
- .tx_irq = INT_McBSP3TX },
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP24XX)
-static const struct omap_mcbsp_info mcbsp_24xx[] = {
- [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
- .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
- .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
- .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
- .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
- },
- [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
- .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
- .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
- .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
- .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
- },
-};
-#endif
+ if (!pdata) {
+ dev_err(&pdev->dev, "McBSP device initialized without"
+ "platform data\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
+
+ if (id >= OMAP_MAX_MCBSP_COUNT) {
+ dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ spin_lock_init(&mcbsp[id].lock);
+ mcbsp[id].id = id + 1;
+ mcbsp[id].free = 1;
+ mcbsp[id].dma_tx_lch = -1;
+ mcbsp[id].dma_rx_lch = -1;
+
+ mcbsp[id].io_base = pdata->virt_base;
+ /* Default I/O is IRQ based */
+ mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
+ mcbsp[id].tx_irq = pdata->tx_irq;
+ mcbsp[id].rx_irq = pdata->rx_irq;
+ mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
+ mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
+
+ if (pdata->clk_name)
+ mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(mcbsp[id].clk)) {
+ mcbsp[id].free = 0;
+ dev_err(&pdev->dev,
+ "Invalid clock configuration for McBSP%d.\n",
+ mcbsp[id].id);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ mcbsp[id].pdata = pdata;
+ mcbsp[id].dev = &pdev->dev;
+ platform_set_drvdata(pdev, &mcbsp[id]);
+
+exit:
+ return ret;
+}
-static int __init omap_mcbsp_init(void)
+static int omap_mcbsp_remove(struct platform_device *pdev)
{
- int mcbsp_count = 0, i;
- static const struct omap_mcbsp_info *mcbsp_info;
+ struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
- printk("Initializing OMAP McBSP system\n");
+ platform_set_drvdata(pdev, NULL);
+ if (mcbsp) {
-#ifdef CONFIG_ARCH_OMAP1
- mcbsp_dsp_ck = clk_get(0, "dsp_ck");
- if (IS_ERR(mcbsp_dsp_ck)) {
- printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
- return PTR_ERR(mcbsp_dsp_ck);
- }
- mcbsp_api_ck = clk_get(0, "api_ck");
- if (IS_ERR(mcbsp_api_ck)) {
- printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
- return PTR_ERR(mcbsp_api_ck);
- }
- mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
- if (IS_ERR(mcbsp_dspxor_ck)) {
- printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
- return PTR_ERR(mcbsp_dspxor_ck);
- }
-#endif
-#ifdef CONFIG_ARCH_OMAP2
- mcbsp1_ick = clk_get(0, "mcbsp1_ick");
- if (IS_ERR(mcbsp1_ick)) {
- printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
- return PTR_ERR(mcbsp1_ick);
- }
- mcbsp1_fck = clk_get(0, "mcbsp1_fck");
- if (IS_ERR(mcbsp1_fck)) {
- printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
- return PTR_ERR(mcbsp1_fck);
- }
- mcbsp2_ick = clk_get(0, "mcbsp2_ick");
- if (IS_ERR(mcbsp2_ick)) {
- printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
- return PTR_ERR(mcbsp2_ick);
- }
- mcbsp2_fck = clk_get(0, "mcbsp2_fck");
- if (IS_ERR(mcbsp2_fck)) {
- printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
- return PTR_ERR(mcbsp2_fck);
- }
-#endif
+ if (mcbsp->pdata && mcbsp->pdata->ops &&
+ mcbsp->pdata->ops->free)
+ mcbsp->pdata->ops->free(mcbsp->id);
-#ifdef CONFIG_ARCH_OMAP730
- if (cpu_is_omap730()) {
- mcbsp_info = mcbsp_730;
- mcbsp_count = ARRAY_SIZE(mcbsp_730);
- }
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
- if (cpu_is_omap15xx()) {
- mcbsp_info = mcbsp_1510;
- mcbsp_count = ARRAY_SIZE(mcbsp_1510);
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
- if (cpu_is_omap16xx()) {
- mcbsp_info = mcbsp_1610;
- mcbsp_count = ARRAY_SIZE(mcbsp_1610);
- }
-#endif
-#if defined(CONFIG_ARCH_OMAP24XX)
- if (cpu_is_omap24xx()) {
- mcbsp_info = mcbsp_24xx;
- mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
- omap2_mcbsp2_mux_setup();
- }
-#endif
- for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
- if (i >= mcbsp_count) {
- mcbsp[i].io_base = 0;
- mcbsp[i].free = 0;
- continue;
- }
- mcbsp[i].id = i + 1;
- mcbsp[i].free = 1;
- mcbsp[i].dma_tx_lch = -1;
- mcbsp[i].dma_rx_lch = -1;
-
- mcbsp[i].io_base = mcbsp_info[i].virt_base;
- mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */
- mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
- mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
- mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
- mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
- spin_lock_init(&mcbsp[i].lock);
+ clk_disable(mcbsp->clk);
+ clk_put(mcbsp->clk);
+
+ mcbsp->clk = NULL;
+ mcbsp->free = 0;
+ mcbsp->dev = NULL;
}
return 0;
}
-arch_initcall(omap_mcbsp_init);
+static struct platform_driver omap_mcbsp_driver = {
+ .probe = omap_mcbsp_probe,
+ .remove = omap_mcbsp_remove,
+ .driver = {
+ .name = "omap-mcbsp",
+ },
+};
+
+int __init omap_mcbsp_init(void)
+{
+ /* Register the McBSP driver */
+ return platform_driver_register(&omap_mcbsp_driver);
+}
-EXPORT_SYMBOL(omap_mcbsp_config);
-EXPORT_SYMBOL(omap_mcbsp_request);
-EXPORT_SYMBOL(omap_mcbsp_set_io_type);
-EXPORT_SYMBOL(omap_mcbsp_free);
-EXPORT_SYMBOL(omap_mcbsp_start);
-EXPORT_SYMBOL(omap_mcbsp_stop);
-EXPORT_SYMBOL(omap_mcbsp_pollread);
-EXPORT_SYMBOL(omap_mcbsp_pollwrite);
-EXPORT_SYMBOL(omap_mcbsp_xmit_word);
-EXPORT_SYMBOL(omap_mcbsp_recv_word);
-EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
-EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
-EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
-EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
-EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 1f23f0459e5..554ee58e129 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -10,6 +10,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#undef DEBUG
#include <linux/module.h>
#include <linux/kernel.h>
@@ -24,25 +25,43 @@
#include <asm/arch/sram.h>
#include <asm/arch/board.h>
+#include <asm/arch/control.h>
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+# include "../mach-omap2/prm.h"
+# include "../mach-omap2/cm.h"
+# include "../mach-omap2/sdrc.h"
+#endif
+
#define OMAP1_SRAM_PA 0x20000000
-#define OMAP1_SRAM_VA 0xd0000000
+#define OMAP1_SRAM_VA VMALLOC_END
#define OMAP2_SRAM_PA 0x40200000
#define OMAP2_SRAM_PUB_PA 0x4020f800
-#define OMAP2_SRAM_VA 0xd0000000
-#define OMAP2_SRAM_PUB_VA 0xd0000800
-
-#if defined(CONFIG_ARCH_OMAP24XX)
+#define OMAP2_SRAM_VA VMALLOC_END
+#define OMAP2_SRAM_PUB_VA (VMALLOC_END + 0x800)
+#define OMAP3_SRAM_PA 0x40200000
+#define OMAP3_SRAM_VA 0xd7000000
+#define OMAP3_SRAM_PUB_PA 0x40208000
+#define OMAP3_SRAM_PUB_VA 0xd7008000
+
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
#define SRAM_BOOTLOADER_SZ 0x00
#else
#define SRAM_BOOTLOADER_SZ 0x80
#endif
-#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048)
-#define VA_READPERM0 IO_ADDRESS(0x68005050)
-#define VA_WRITEPERM0 IO_ADDRESS(0x68005058)
-#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8)
+#define OMAP24XX_VA_REQINFOPERM0 IO_ADDRESS(0x68005048)
+#define OMAP24XX_VA_READPERM0 IO_ADDRESS(0x68005050)
+#define OMAP24XX_VA_WRITEPERM0 IO_ADDRESS(0x68005058)
+
+#define OMAP34XX_VA_REQINFOPERM0 IO_ADDRESS(0x68012848)
+#define OMAP34XX_VA_READPERM0 IO_ADDRESS(0x68012850)
+#define OMAP34XX_VA_WRITEPERM0 IO_ADDRESS(0x68012858)
+#define OMAP34XX_VA_ADDR_MATCH2 IO_ADDRESS(0x68012880)
+#define OMAP34XX_VA_SMS_RG_ATT0 IO_ADDRESS(0x6C000048)
+#define OMAP34XX_VA_CONTROL_STAT IO_ADDRESS(0x480022F0)
+
#define GP_DEVICE 0x300
-#define TYPE_MASK 0x700
#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
@@ -68,14 +87,21 @@ static int is_sram_locked(void)
int type = 0;
if (cpu_is_omap242x())
- type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK;
+ type = system_rev & OMAP2_DEVICETYPE_MASK;
if (type == GP_DEVICE) {
/* RAMFW: R/W access to all initiators for all qualifier sets */
if (cpu_is_omap242x()) {
- __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */
- __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */
- __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */
+ __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
+ __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */
+ __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
+ }
+ if (cpu_is_omap34xx()) {
+ __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
+ __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */
+ __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
+ __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2);
+ __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
}
return 0;
} else
@@ -92,18 +118,30 @@ void __init omap_detect_sram(void)
{
unsigned long reserved;
- if (cpu_is_omap24xx()) {
+ if (cpu_class_is_omap2()) {
if (is_sram_locked()) {
- omap_sram_base = OMAP2_SRAM_PUB_VA;
- omap_sram_start = OMAP2_SRAM_PUB_PA;
- omap_sram_size = 0x800; /* 2K */
+ if (cpu_is_omap34xx()) {
+ omap_sram_base = OMAP3_SRAM_PUB_VA;
+ omap_sram_start = OMAP3_SRAM_PUB_PA;
+ omap_sram_size = 0x8000; /* 32K */
+ } else {
+ omap_sram_base = OMAP2_SRAM_PUB_VA;
+ omap_sram_start = OMAP2_SRAM_PUB_PA;
+ omap_sram_size = 0x800; /* 2K */
+ }
} else {
- omap_sram_base = OMAP2_SRAM_VA;
- omap_sram_start = OMAP2_SRAM_PA;
- if (cpu_is_omap242x())
- omap_sram_size = 0xa0000; /* 640K */
- else if (cpu_is_omap243x())
+ if (cpu_is_omap34xx()) {
+ omap_sram_base = OMAP3_SRAM_VA;
+ omap_sram_start = OMAP3_SRAM_PA;
omap_sram_size = 0x10000; /* 64K */
+ } else {
+ omap_sram_base = OMAP2_SRAM_VA;
+ omap_sram_start = OMAP2_SRAM_PA;
+ if (cpu_is_omap242x())
+ omap_sram_size = 0xa0000; /* 640K */
+ else if (cpu_is_omap243x())
+ omap_sram_size = 0x10000; /* 64K */
+ }
}
} else {
omap_sram_base = OMAP1_SRAM_VA;
@@ -157,6 +195,13 @@ void __init omap_map_sram(void)
omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
}
+ if (cpu_is_omap34xx()) {
+ omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA;
+ base = OMAP3_SRAM_PA;
+ base = ROUND_DOWN(base, PAGE_SIZE);
+ omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
+ }
+
omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
@@ -191,6 +236,7 @@ void * omap_sram_push(void * start, unsigned long size)
omap_sram_ceil -= size;
omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
memcpy((void *)omap_sram_ceil, start, size);
+ flush_icache_range((unsigned long)start, (unsigned long)(start + size));
return (void *)omap_sram_ceil;
}
@@ -214,8 +260,9 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
int __init omap1_sram_init(void)
{
- _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
- sram_reprogram_clock_sz);
+ _omap_sram_reprogram_clock =
+ omap_sram_push(omap1_sram_reprogram_clock,
+ omap1_sram_reprogram_clock_sz);
return 0;
}
@@ -224,7 +271,7 @@ int __init omap1_sram_init(void)
#define omap1_sram_init() do {} while (0)
#endif
-#ifdef CONFIG_ARCH_OMAP2
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
u32 base_cs, u32 force_unlock);
@@ -259,19 +306,109 @@ u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2420
+int __init omap242x_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
+ omap242x_sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc,
+ omap242x_sram_reprogram_sdrc_sz);
+
+ _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm,
+ omap242x_sram_set_prcm_sz);
+
+ return 0;
+}
+#else
+static inline int omap242x_sram_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+int __init omap243x_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
+ omap243x_sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc,
+ omap243x_sram_reprogram_sdrc_sz);
+
+ _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm,
+ omap243x_sram_set_prcm_sz);
+
+ return 0;
+}
+#else
+static inline int omap243x_sram_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+
+static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level);
+u32 omap2_sram_reprogram_gpmc(u32 perf_level)
+{
+ if (!_omap2_sram_reprogram_gpmc)
+ omap_sram_error();
+
+ return _omap2_sram_reprogram_gpmc(perf_level);
+}
+
+static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n,
+ u32 freqsel, u32 m2);
+u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2)
+{
+ if (!_omap2_sram_configure_core_dpll)
+ omap_sram_error();
+
+ return _omap2_sram_configure_core_dpll(m, n, freqsel, m2);
+}
-int __init omap2_sram_init(void)
+/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
+void restore_sram_functions(void)
{
- _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz);
+ omap_sram_ceil = omap_sram_base + omap_sram_size;
- _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc,
- sram_reprogram_sdrc_sz);
- _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz);
+ _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
+ omap34xx_sram_reprogram_gpmc_sz);
+
+ _omap2_sram_configure_core_dpll =
+ omap_sram_push(omap34xx_sram_configure_core_dpll,
+ omap34xx_sram_configure_core_dpll_sz);
+}
+
+int __init omap34xx_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init,
+ omap34xx_sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc,
+ omap34xx_sram_reprogram_sdrc_sz);
+
+ _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm,
+ omap34xx_sram_set_prcm_sz);
+
+ _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
+ omap34xx_sram_reprogram_gpmc_sz);
+
+ _omap2_sram_configure_core_dpll =
+ omap_sram_push(omap34xx_sram_configure_core_dpll,
+ omap34xx_sram_configure_core_dpll_sz);
return 0;
}
#else
-#define omap2_sram_init() do {} while (0)
+static inline int omap34xx_sram_init(void)
+{
+ return 0;
+}
#endif
int __init omap_sram_init(void)
@@ -279,10 +416,14 @@ int __init omap_sram_init(void)
omap_detect_sram();
omap_map_sram();
- if (!cpu_is_omap24xx())
+ if (!(cpu_class_is_omap2()))
omap1_sram_init();
- else
- omap2_sram_init();
+ else if (cpu_is_omap242x())
+ omap242x_sram_init();
+ else if (cpu_is_omap2430())
+ omap243x_sram_init();
+ else if (cpu_is_omap34xx())
+ omap34xx_sram_init();
return 0;
}
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index a619475c4b7..2699c16d4da 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -1,4 +1,4 @@
-/*
+ /*
* arch/arm/plat-omap/usb.c -- platform level USB initialization
*
* Copyright (C) 2004 Texas Instruments, Inc.
@@ -156,8 +156,12 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
if (nwires == 0) {
if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
+ u32 l;
+
/* pulldown D+/D- */
- USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
}
return 0;
}
@@ -171,6 +175,8 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
/* internal transceiver (unavailable on 17xx, 24xx) */
if (!cpu_class_is_omap2() && nwires == 2) {
+ u32 l;
+
// omap_cfg_reg(P9_USB_DP);
// omap_cfg_reg(R8_USB_DM);
@@ -185,9 +191,11 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
* - OTG support on this port not yet written
*/
- USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(7 << 4);
if (!is_device)
- USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+ l |= (3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
return 3 << 16;
}
@@ -217,8 +225,13 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
* with VBUS switching and overcurrent detection.
*/
- if (cpu_class_is_omap1() && nwires != 6)
- USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
+ if (cpu_class_is_omap1() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
switch (nwires) {
case 3:
@@ -238,9 +251,13 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
omap_cfg_reg(K20_24XX_USB0_VM);
omap2_usb_devconf_set(0, USB_UNIDIR);
} else {
+ u32 l;
+
omap_cfg_reg(AA9_USB0_VP);
omap_cfg_reg(R9_USB0_VM);
- USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
}
break;
default:
@@ -254,8 +271,13 @@ static u32 __init omap_usb1_init(unsigned nwires)
{
u32 syscon1 = 0;
- if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
- USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
if (cpu_is_omap24xx())
omap2_usb_devconf_clear(1, USB_BIDIR_TLL);
@@ -316,8 +338,13 @@ static u32 __init omap_usb1_init(unsigned nwires)
syscon1 = 3;
omap_cfg_reg(USB1_VP);
omap_cfg_reg(USB1_VM);
- if (!cpu_is_omap15xx())
- USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
+ if (!cpu_is_omap15xx()) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
break;
default:
bad:
@@ -340,8 +367,13 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
if (alt_pingroup || nwires == 0)
return 0;
- if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
- USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
/* external transceiver */
if (cpu_is_omap15xx()) {
@@ -410,9 +442,13 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
omap_cfg_reg(USB2_VP);
omap_cfg_reg(USB2_VM);
} else {
+ u32 l;
+
omap_cfg_reg(AA9_USB2_VP);
omap_cfg_reg(R9_USB2_VM);
- USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
}
break;
default:
@@ -531,10 +567,6 @@ static struct platform_device otg_device = {
/*-------------------------------------------------------------------------*/
-#define ULPD_CLOCK_CTRL_REG __REG16(ULPD_CLOCK_CTRL)
-#define ULPD_SOFT_REQ_REG __REG16(ULPD_SOFT_REQ)
-
-
// FIXME correct answer depends on hmc_mode,
// as does (on omap1) any nonzero value for config->otg port number
#ifdef CONFIG_USB_GADGET_OMAP
@@ -550,17 +582,17 @@ static struct platform_device otg_device = {
void __init
omap_otg_init(struct omap_usb_config *config)
{
- u32 syscon = OTG_SYSCON_1_REG & 0xffff;
+ u32 syscon;
int status;
int alt_pingroup = 0;
/* NOTE: no bus or clock setup (yet?) */
- syscon = OTG_SYSCON_1_REG & 0xffff;
+ syscon = omap_readl(OTG_SYSCON_1) & 0xffff;
if (!(syscon & OTG_RESET_DONE))
pr_debug("USB resets not complete?\n");
- // OTG_IRQ_EN_REG = 0;
+ //omap_writew(0, OTG_IRQ_EN);
/* pin muxing and transceiver pinouts */
if (config->pins[0] > 2) /* alt pingroup 2 */
@@ -568,8 +600,8 @@ omap_otg_init(struct omap_usb_config *config)
syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
syscon |= omap_usb1_init(config->pins[1]);
syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
- pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
- OTG_SYSCON_1_REG = syscon;
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
+ omap_writel(syscon, OTG_SYSCON_1);
syscon = config->hmc_mode;
syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
@@ -578,9 +610,10 @@ omap_otg_init(struct omap_usb_config *config)
syscon |= OTG_EN;
#endif
if (cpu_class_is_omap1())
- pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
- pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
- OTG_SYSCON_2_REG = syscon;
+ pr_debug("USB_TRANSCEIVER_CTRL = %03x\n",
+ omap_readl(USB_TRANSCEIVER_CTRL));
+ pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2));
+ omap_writel(syscon, OTG_SYSCON_2);
printk("USB: hmc %d", config->hmc_mode);
if (!alt_pingroup)
@@ -597,12 +630,19 @@ omap_otg_init(struct omap_usb_config *config)
printk("\n");
if (cpu_class_is_omap1()) {
+ u16 w;
+
/* leave USB clocks/controllers off until needed */
- ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
- ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
- ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
+ w = omap_readw(ULPD_SOFT_REQ);
+ w &= ~SOFT_USB_CLK_REQ;
+ omap_writew(w, ULPD_SOFT_REQ);
+
+ w = omap_readw(ULPD_CLOCK_CTRL);
+ w &= ~USB_MCLK_EN;
+ w |= DIS_USB_PVCI_CLK;
+ omap_writew(w, ULPD_CLOCK_CTRL);
}
- syscon = OTG_SYSCON_1_REG;
+ syscon = omap_readl(OTG_SYSCON_1);
syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
#ifdef CONFIG_USB_GADGET_OMAP
@@ -639,8 +679,8 @@ omap_otg_init(struct omap_usb_config *config)
pr_debug("can't register OTG device, %d\n", status);
}
#endif
- pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
- OTG_SYSCON_1_REG = syscon;
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
+ omap_writel(syscon, OTG_SYSCON_1);
status = 0;
}
@@ -653,18 +693,19 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
#ifdef CONFIG_ARCH_OMAP15XX
-#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL)
+/* ULPD_DPLL_CTRL */
#define DPLL_IOB (1 << 13)
#define DPLL_PLL_ENABLE (1 << 4)
#define DPLL_LOCK (1 << 0)
-#define ULPD_APLL_CTRL_REG __REG16(ULPD_APLL_CTRL)
+/* ULPD_APLL_CTRL */
#define APLL_NDPLL_SWITCH (1 << 0)
static void __init omap_1510_usb_init(struct omap_usb_config *config)
{
unsigned int val;
+ u16 w;
omap_usb0_init(config->pins[0], is_usb0_device(config));
omap_usb1_init(config->pins[1]);
@@ -685,12 +726,22 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
printk("\n");
/* use DPLL for 48 MHz function clock */
- pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG,
- ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG);
- ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH;
- ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE;
- ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
- while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK))
+ pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL),
+ omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ));
+
+ w = omap_readw(ULPD_APLL_CTRL);
+ w &= ~APLL_NDPLL_SWITCH;
+ omap_writew(w, ULPD_APLL_CTRL);
+
+ w = omap_readw(ULPD_DPLL_CTRL);
+ w |= DPLL_IOB | DPLL_PLL_ENABLE;
+ omap_writew(w, ULPD_DPLL_CTRL);
+
+ w = omap_readw(ULPD_SOFT_REQ);
+ w |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
+ omap_writew(w, ULPD_SOFT_REQ);
+
+ while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK))
cpu_relax();
#ifdef CONFIG_USB_GADGET_OMAP
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index b66fb3c4e22..5e28c217b8c 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
depends on ARCH_S3C2410
default y if ARCH_S3C2410
select NO_IOPORT
+ select HAVE_GPIO_LIB
help
Base platform code for any Samsung S3C24XX device
@@ -20,6 +21,13 @@ config CPU_S3C244X
help
Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+config S3C24XX_PWM
+ bool "PWM device support"
+ select HAVE_PWM
+ help
+ Support for exporting the PWM timer blocks via the pwm device
+ system.
+
config PM_SIMTEC
bool
help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 131d20237dd..d82767b2b83 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -16,8 +16,10 @@ obj-y += cpu.o
obj-y += irq.o
obj-y += devs.o
obj-y += gpio.o
+obj-y += gpiolib.o
obj-y += time.o
obj-y += clock.o
+obj-y += pwm-clock.o
# Architecture dependant builds
@@ -27,5 +29,6 @@ obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_HAVE_PWM) += pwm.o
obj-$(CONFIG_S3C2410_DMA) += dma.o
obj-$(CONFIG_MACH_SMDK) += common-smdk.o
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index e546e933b3f..eea3b32ff79 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -495,106 +495,6 @@ struct platform_device s3c_device_spi1 = {
EXPORT_SYMBOL(s3c_device_spi1);
-/* pwm timer blocks */
-
-static struct resource s3c_timer0_resource[] = {
- [0] = {
- .start = S3C24XX_PA_TIMER + 0x0C,
- .end = S3C24XX_PA_TIMER + 0x0C + 0xB,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_TIMER0,
- .end = IRQ_TIMER0,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-struct platform_device s3c_device_timer0 = {
- .name = "s3c2410-timer",
- .id = 0,
- .num_resources = ARRAY_SIZE(s3c_timer0_resource),
- .resource = s3c_timer0_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer0);
-
-/* timer 1 */
-
-static struct resource s3c_timer1_resource[] = {
- [0] = {
- .start = S3C24XX_PA_TIMER + 0x18,
- .end = S3C24XX_PA_TIMER + 0x23,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_TIMER1,
- .end = IRQ_TIMER1,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-struct platform_device s3c_device_timer1 = {
- .name = "s3c2410-timer",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c_timer1_resource),
- .resource = s3c_timer1_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer1);
-
-/* timer 2 */
-
-static struct resource s3c_timer2_resource[] = {
- [0] = {
- .start = S3C24XX_PA_TIMER + 0x24,
- .end = S3C24XX_PA_TIMER + 0x2F,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_TIMER2,
- .end = IRQ_TIMER2,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-struct platform_device s3c_device_timer2 = {
- .name = "s3c2410-timer",
- .id = 2,
- .num_resources = ARRAY_SIZE(s3c_timer2_resource),
- .resource = s3c_timer2_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer2);
-
-/* timer 3 */
-
-static struct resource s3c_timer3_resource[] = {
- [0] = {
- .start = S3C24XX_PA_TIMER + 0x30,
- .end = S3C24XX_PA_TIMER + 0x3B,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_TIMER3,
- .end = IRQ_TIMER3,
- .flags = IORESOURCE_IRQ,
- }
-
-};
-
-struct platform_device s3c_device_timer3 = {
- .name = "s3c2410-timer",
- .id = 3,
- .num_resources = ARRAY_SIZE(s3c_timer3_resource),
- .resource = s3c_timer3_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer3);
-
#ifdef CONFIG_CPU_S3C2440
/* Camif Controller */
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
new file mode 100644
index 00000000000..825d8d0c5ca
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -0,0 +1,259 @@
+/* linux/arch/arm/plat-s3c24xx/gpiolib.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX GPIOlib support
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+
+struct s3c24xx_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *base;
+};
+
+static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct s3c24xx_gpio_chip, chip);
+}
+
+/* these routines are exported for use by other parts of the platform
+ * and system support, but are not intended to be used directly by the
+ * drivers themsevles.
+ */
+
+int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+ con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2);
+
+ __raw_writel(con, base + 0x00);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+int s3c24xx_gpiolib_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+ con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+
+ local_irq_save(flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+}
+
+int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
+ unsigned long val;
+
+ val = __raw_readl(ourchip->base + 0x04);
+ val >>= offset;
+ val &= 1;
+
+ return val;
+}
+
+static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
+{
+ return -EINVAL;
+}
+
+static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ dat = __raw_readl(base + 0x04);
+
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+
+ __raw_writel(dat, base + 0x04);
+
+ con &= ~(1 << offset);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+
+struct s3c24xx_gpio_chip gpios[] = {
+ [0] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPA0),
+ .chip = {
+ .base = S3C2410_GPA0,
+ .owner = THIS_MODULE,
+ .label = "GPIOA",
+ .ngpio = 24,
+ .direction_input = s3c24xx_gpiolib_banka_input,
+ .direction_output = s3c24xx_gpiolib_banka_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [1] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPB0),
+ .chip = {
+ .base = S3C2410_GPB0,
+ .owner = THIS_MODULE,
+ .label = "GPIOB",
+ .ngpio = 16,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [2] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPC0),
+ .chip = {
+ .base = S3C2410_GPC0,
+ .owner = THIS_MODULE,
+ .label = "GPIOC",
+ .ngpio = 16,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [3] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPD0),
+ .chip = {
+ .base = S3C2410_GPD0,
+ .owner = THIS_MODULE,
+ .label = "GPIOD",
+ .ngpio = 16,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [4] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPE0),
+ .chip = {
+ .base = S3C2410_GPE0,
+ .label = "GPIOE",
+ .owner = THIS_MODULE,
+ .ngpio = 16,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [5] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPF0),
+ .chip = {
+ .base = S3C2410_GPF0,
+ .owner = THIS_MODULE,
+ .label = "GPIOF",
+ .ngpio = 8,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+ [6] = {
+ .base = S3C24XX_GPIO_BASE(S3C2410_GPG0),
+ .chip = {
+ .base = S3C2410_GPG0,
+ .owner = THIS_MODULE,
+ .label = "GPIOG",
+ .ngpio = 10,
+ .direction_input = s3c24xx_gpiolib_input,
+ .direction_output = s3c24xx_gpiolib_output,
+ .set = s3c24xx_gpiolib_set,
+ .get = s3c24xx_gpiolib_get,
+ },
+ },
+};
+
+static __init int s3c24xx_gpiolib_init(void)
+{
+ struct s3c24xx_gpio_chip *chip = gpios;
+ int gpn;
+
+ for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++)
+ gpiochip_add(&chip->chip);
+
+ return 0;
+}
+
+arch_initcall(s3c24xx_gpiolib_init);
diff --git a/arch/arm/plat-s3c24xx/pwm-clock.c b/arch/arm/plat-s3c24xx/pwm-clock.c
new file mode 100644
index 00000000000..2cda3e3c678
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pwm-clock.c
@@ -0,0 +1,437 @@
+/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2008 Ben Dooks
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * 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.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/plat-s3c/regs-timer.h>
+
+/* Each of the timers 0 through 5 go through the following
+ * clock tree, with the inputs depending on the timers.
+ *
+ * pclk ---- [ prescaler 0 ] -+---> timer 0
+ * +---> timer 1
+ *
+ * pclk ---- [ prescaler 1 ] -+---> timer 2
+ * +---> timer 3
+ * \---> timer 4
+ *
+ * Which are fed into the timers as so:
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 0
+ * tclk 0 ------------------------------/
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 1
+ * tclk 0 ------------------------------/
+ *
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 2
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 3
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8, 16 ] --\
+ * [mux] -> timer 4
+ * tclk 1 ------------------------------/
+ *
+ * Since the mux and the divider are tied together in the
+ * same register space, it is impossible to set the parent
+ * and the rate at the same time. To avoid this, we add an
+ * intermediate 'prescaled-and-divided' clock to select
+ * as the parent for the timer input clock called tdiv.
+ *
+ * prescaled clk --> pwm-tdiv ---\
+ * [ mux ] --> timer X
+ * tclk -------------------------/
+*/
+
+static unsigned long clk_pwm_scaler_getrate(struct clk *clk)
+{
+ unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ if (clk->id == 1) {
+ tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
+ tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
+ } else {
+ tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
+ }
+
+ return clk_get_rate(clk->parent) / (tcfg0 + 1);
+}
+
+/* TODO - add set rate calls. */
+
+struct clk clk_timer_scaler[] = {
+ [0] = {
+ .name = "pwm-scaler0",
+ .id = -1,
+ .get_rate = clk_pwm_scaler_getrate,
+ },
+ [1] = {
+ .name = "pwm-scaler1",
+ .id = -1,
+ .get_rate = clk_pwm_scaler_getrate,
+ },
+};
+
+struct clk clk_timer_tclk[] = {
+ [0] = {
+ .name = "pwm-tclk0",
+ .id = -1,
+ },
+ [1] = {
+ .name = "pwm-tclk1",
+ .id = -1,
+ },
+};
+
+struct pwm_tdiv_clk {
+ struct clk clk;
+ unsigned int divisor;
+};
+
+static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
+{
+ return container_of(clk, struct pwm_tdiv_clk, clk);
+}
+
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << (1 + tcfg1);
+}
+
+static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
+ divisor = to_tdiv(clk)->divisor;
+ else
+ divisor = tcfg_to_divisor(tcfg1);
+
+ return clk_get_rate(clk->parent) / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate;
+ unsigned long divisor;
+
+ parent_rate = clk_get_rate(clk->parent);
+ divisor = parent_rate / rate;
+
+ if (divisor <= 2)
+ divisor = 2;
+ else if (divisor <= 4)
+ divisor = 4;
+ else if (divisor <= 8)
+ divisor = 8;
+ else
+ divisor = 16;
+
+ return parent_rate / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
+{
+ unsigned long bits;
+
+ switch (divclk->divisor) {
+ case 2:
+ bits = S3C2410_TCFG1_MUX_DIV2;
+ break;
+ case 4:
+ bits = S3C2410_TCFG1_MUX_DIV4;
+ break;
+ case 8:
+ bits = S3C2410_TCFG1_MUX_DIV8;
+ break;
+ case 16:
+ default:
+ bits = S3C2410_TCFG1_MUX_DIV16;
+ break;
+ }
+
+ return bits;
+}
+
+static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long bits = clk_pwm_tdiv_bits(divclk);
+ unsigned long flags;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id);
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ tcfg1 |= bits << shift;
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+}
+
+static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct pwm_tdiv_clk *divclk = to_tdiv(clk);
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ rate = clk_round_rate(clk, rate);
+ divisor = parent_rate / rate;
+
+ if (divisor > 16)
+ return -EINVAL;
+
+ divclk->divisor = divisor;
+
+ /* Update the current MUX settings if we are currently
+ * selected as the clock source for this clock. */
+
+ if (tcfg1 != S3C2410_TCFG1_MUX_TCLK)
+ clk_pwm_tdiv_update(divclk);
+
+ return 0;
+}
+
+struct pwm_tdiv_clk clk_timer_tdiv[] = {
+ [0] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .parent = &clk_timer_scaler[0],
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+ },
+ },
+ [1] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .parent = &clk_timer_scaler[0],
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+ }
+ },
+ [2] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .parent = &clk_timer_scaler[1],
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+ },
+ },
+ [3] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .parent = &clk_timer_scaler[1],
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+ },
+ },
+ [4] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .parent = &clk_timer_scaler[1],
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+ },
+ },
+};
+
+static int __init clk_pwm_tdiv_register(unsigned int id)
+{
+ struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ divclk->clk.id = id;
+ divclk->divisor = tcfg_to_divisor(tcfg1);
+
+ return s3c24xx_register_clock(&divclk->clk);
+}
+
+static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
+{
+ return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
+}
+
+static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
+{
+ return &clk_timer_tdiv[id].clk;
+}
+
+static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned int id = clk->id;
+ unsigned long tcfg1;
+ unsigned long flags;
+ unsigned long bits;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(id);
+
+ if (parent == s3c24xx_pwmclk_tclk(id))
+ bits = S3C2410_TCFG1_MUX_TCLK << shift;
+ else if (parent == s3c24xx_pwmclk_tdiv(id))
+ bits = clk_pwm_tdiv_bits(to_tdiv(clk)) << shift;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ __raw_writel(tcfg1 | bits, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk clk_tin[] = {
+ [0] = {
+ .name = "pwm-tin",
+ .id = 0,
+ .set_parent = clk_pwm_tin_set_parent,
+ },
+ [1] = {
+ .name = "pwm-tin",
+ .id = 1,
+ .set_parent = clk_pwm_tin_set_parent,
+ },
+ [2] = {
+ .name = "pwm-tin",
+ .id = 2,
+ .set_parent = clk_pwm_tin_set_parent,
+ },
+ [3] = {
+ .name = "pwm-tin",
+ .id = 3,
+ .set_parent = clk_pwm_tin_set_parent,
+ },
+ [4] = {
+ .name = "pwm-tin",
+ .id = 4,
+ .set_parent = clk_pwm_tin_set_parent,
+ },
+};
+
+static __init int clk_pwm_tin_register(struct clk *pwm)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int id = pwm->id;
+
+ struct clk *parent;
+ int ret;
+
+ ret = s3c24xx_register_clock(pwm);
+ if (ret < 0)
+ return ret;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
+ parent = s3c24xx_pwmclk_tclk(id);
+ else
+ parent = s3c24xx_pwmclk_tdiv(id);
+
+ return clk_set_parent(pwm, parent);
+}
+
+static __init int s3c24xx_pwmclk_init(void)
+{
+ struct clk *clk_timers;
+ unsigned int clk;
+ int ret;
+
+ clk_timers = clk_get(NULL, "timers");
+ if (IS_ERR(clk_timers)) {
+ printk(KERN_ERR "%s: no parent clock\n", __func__);
+ return -EINVAL;
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) {
+ clk_timer_scaler[clk].parent = clk_timers;
+ ret = s3c24xx_register_clock(&clk_timer_scaler[clk]);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm scaler%d clock\n", clk);
+ goto err;
+ }
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) {
+ ret = s3c24xx_register_clock(&clk_timer_tclk[clk]);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pww tclk%d\n", clk);
+ goto err;
+ }
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
+ ret = clk_pwm_tdiv_register(clk);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
+ goto err;
+ }
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
+ ret = clk_pwm_tin_register(&clk_tin[clk]);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
+ goto err;
+ }
+ }
+
+ return 0;
+
+ err:
+ return ret;
+}
+
+arch_initcall(s3c24xx_pwmclk_init);
diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c24xx/pwm.c
new file mode 100644
index 00000000000..18c4bdc49a0
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pwm.c
@@ -0,0 +1,402 @@
+/* arch/arm/plat-s3c24xx/pwm.c
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C24XX PWM device core
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <asm/plat-s3c/regs-timer.h>
+
+struct pwm_device {
+ struct list_head list;
+ struct platform_device *pdev;
+
+ struct clk *clk_div;
+ struct clk *clk;
+ const char *label;
+
+ unsigned int period_ns;
+ unsigned int duty_ns;
+
+ unsigned char tcon_base;
+ unsigned char running;
+ unsigned char use_count;
+ unsigned char pwm_id;
+};
+
+#define pwm_dbg(_pwm, msg...) dev_info(&(_pwm)->pdev->dev, msg)
+
+static struct clk *clk_scaler[2];
+
+/* Standard setup for a timer block. */
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq) \
+ (struct resource [TIMER_RESOURCE_SIZE]) { \
+ [0] = { \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ \
+ } \
+ }
+
+#define DEFINE_TIMER(_tmr_no, _irq) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
+ */
+
+struct platform_device s3c_device_timer[] = {
+ [0] = { DEFINE_TIMER(0, IRQ_TIMER0) },
+ [1] = { DEFINE_TIMER(1, IRQ_TIMER1) },
+ [2] = { DEFINE_TIMER(2, IRQ_TIMER2) },
+ [3] = { DEFINE_TIMER(3, IRQ_TIMER3) },
+ [4] = { DEFINE_TIMER(4, IRQ_TIMER4) },
+};
+
+static inline int pwm_is_tdiv(struct pwm_device *pwm)
+{
+ return clk_get_parent(pwm->clk) == pwm->clk_div;
+}
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, list) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count = 1;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+
+EXPORT_SYMBOL(pwm_request);
+
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
+
+ mutex_unlock(&pwm_lock);
+}
+
+EXPORT_SYMBOL(pwm_free);
+
+#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 1;
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 0;
+}
+
+EXPORT_SYMBOL(pwm_disable);
+
+unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
+{
+ unsigned long tin_parent_rate;
+ unsigned int div;
+
+ tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
+ pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
+
+ for (div = 2; div <= 16; div *= 2) {
+ if ((tin_parent_rate / (div << 16)) < freq)
+ return tin_parent_rate / div;
+ }
+
+ return tin_parent_rate / 16;
+}
+
+#define NS_IN_HZ (1000000000UL)
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long tin_rate;
+ unsigned long tin_ns;
+ unsigned long period;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned long tcnt;
+ long tcmp;
+
+ /* We currently avoid using 64bit arithmetic by using the
+ * fact that anything faster than 1Hz is easily representable
+ * by 32bits. */
+
+ if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+ return -ERANGE;
+
+ if (duty_ns > period_ns)
+ return -EINVAL;
+
+ if (period_ns == pwm->period_ns &&
+ duty_ns == pwm->duty_ns)
+ return 0;
+
+ /* The TCMP and TCNT can be read without a lock, they're not
+ * shared between the timers. */
+
+ tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
+ tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
+
+ period = NS_IN_HZ / period_ns;
+
+ pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
+ duty_ns, period_ns, period);
+
+ /* Check to see if we are changing the clock rate of the PWM */
+
+ if (pwm->period_ns != period_ns) {
+ if (pwm_is_tdiv(pwm)) {
+ tin_rate = pwm_calc_tin(pwm, period);
+ clk_set_rate(pwm->clk_div, tin_rate);
+ } else
+ tin_rate = clk_get_rate(pwm->clk);
+
+ pwm->period_ns = period_ns;
+
+ pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
+
+ tin_ns = NS_IN_HZ / tin_rate;
+ tcnt = period_ns / tin_ns;
+ } else
+ tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
+
+ /* Note, counters count down */
+
+ tcmp = duty_ns / tin_ns;
+ tcmp = tcnt - tcmp;
+
+ pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+
+ if (tcmp < 0)
+ tcmp = 0;
+
+ /* Update the PWM register block. */
+
+ local_irq_save(flags);
+
+ __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
+ __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_manulupdate(pwm);
+ tcon |= pwm_tcon_autoreload(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ tcon &= ~pwm_tcon_manulupdate(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_config);
+
+static int pwm_register(struct pwm_device *pwm)
+{
+ pwm->duty_ns = -1;
+ pwm->period_ns = -1;
+
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->list, &pwm_list);
+ mutex_unlock(&pwm_lock);
+
+ return 0;
+}
+
+static int s3c_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pwm_device *pwm;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned int id = pdev->id;
+ int ret;
+
+ if (id == 4) {
+ dev_err(dev, "TIMER4 is currently not supported\n");
+ return -ENXIO;
+ }
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(dev, "failed to allocate pwm_device\n");
+ return -ENOMEM;
+ }
+
+ pwm->pdev = pdev;
+ pwm->pwm_id = id;
+
+ /* calculate base of control bits in TCON */
+ pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+
+ pwm->clk = clk_get(dev, "pwm-tin");
+ if (IS_ERR(pwm->clk)) {
+ dev_err(dev, "failed to get pwm tin clk\n");
+ ret = PTR_ERR(pwm->clk);
+ goto err_alloc;
+ }
+
+ pwm->clk_div = clk_get(dev, "pwm-tdiv");
+ if (IS_ERR(pwm->clk_div)) {
+ dev_err(dev, "failed to get pwm tdiv clk\n");
+ ret = PTR_ERR(pwm->clk_div);
+ goto err_clk_tin;
+ }
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+
+ ret = pwm_register(pwm);
+ if (ret) {
+ dev_err(dev, "failed to register pwm\n");
+ goto err_clk_tdiv;
+ }
+
+ pwm_dbg(pwm, "config bits %02x\n",
+ (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
+
+ dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+ clk_get_rate(pwm->clk),
+ clk_get_rate(pwm->clk_div),
+ pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+ err_clk_tdiv:
+ clk_put(pwm->clk_div);
+
+ err_clk_tin:
+ clk_put(pwm->clk);
+
+ err_alloc:
+ kfree(pwm);
+ return ret;
+}
+
+static int s3c_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+ clk_put(pwm->clk_div);
+ clk_put(pwm->clk);
+ kfree(pwm);
+
+ return 0;
+}
+
+static struct platform_driver s3c_pwm_driver = {
+ .driver = {
+ .name = "s3c24xx-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = s3c_pwm_probe,
+ .remove = __devexit_p(s3c_pwm_remove),
+};
+
+static int __init pwm_init(void)
+{
+ int ret;
+
+ clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+ clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+
+ if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+ printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = platform_driver_register(&s3c_pwm_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
+
+ return ret;
+}
+
+arch_initcall(pwm_init);
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 917325bfbd8..6be0c50122e 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -254,7 +254,8 @@ close_cplbtab(struct cplb_tab *table)
}
/* helper function */
-static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+static void __init
+__fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
{
if (cplb_data[i].psize) {
fill_cplbtab(t,
@@ -291,7 +292,8 @@ static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_en
}
}
-static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+static void __init
+__fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
{
if (cplb_data[i].psize) {
fill_cplbtab(t,
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 73647c15877..07402f57c9d 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -60,9 +60,14 @@ static struct irq_chip bad_chip = {
};
static struct irq_desc bad_irq_desc = {
+ .status = IRQ_DISABLED,
.chip = &bad_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
+ .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
+#ifdef CONFIG_SMP
+ .affinity = CPU_MASK_ALL
+#endif
};
int show_interrupts(struct seq_file *p, void *v)
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 4ae15c8c248..632cda8f2e7 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -547,7 +547,8 @@ setup_arch (char **cmdline_p)
# ifdef CONFIG_ACPI_NUMA
acpi_numa_init();
per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ?
- 32 : cpus_weight(early_cpu_possible_map)), additional_cpus);
+ 32 : cpus_weight(early_cpu_possible_map)),
+ additional_cpus > 0 ? additional_cpus : 0);
# endif
#else
# ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 8c73643f2d6..aad1b7b1fff 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -117,6 +117,7 @@ void account_system_vtime(struct task_struct *tsk)
local_irq_restore(flags);
}
+EXPORT_SYMBOL_GPL(account_system_vtime);
/*
* Called from the timer interrupt handler to charge accumulated user time
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 1cee2f9fdf0..095e04db1c0 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -273,7 +273,8 @@ endif
initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
initrd-y := $(patsubst zImage%, zImage.initrd%, \
$(patsubst dtbImage%, dtbImage.initrd%, \
- $(patsubst treeImage%, treeImage.initrd%, $(image-y))))
+ $(patsubst simpleImage%, simpleImage.initrd%, \
+ $(patsubst treeImage%, treeImage.initrd%, $(image-y)))))
initrd-y := $(filter-out $(image-y), $(initrd-y))
targets += $(image-y) $(initrd-y)
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 61dd17449dd..cf37f5ca4b7 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -136,6 +136,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
if (of_get_property(np, "clock-frequency", NULL) == NULL)
return -1;
+ /* if reg-shift or offset, don't try to use it */
+ if ((of_get_property(np, "reg-shift", NULL) != NULL) ||
+ (of_get_property(np, "reg-offset", NULL) != NULL))
+ return -1;
+
/* if rtas uses this device, don't try to use it as well */
if (of_get_property(np, "used-by-rtas", NULL) != NULL)
return -1;
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index 41c7fd91e99..fe92e65103e 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes;
static struct mpc52xx_xlb __iomem *xlb;
static struct mpc52xx_gpio __iomem *gps;
static struct mpc52xx_gpio_wkup __iomem *gpw;
+static void __iomem *pci;
static void __iomem *sram;
static const int sram_size = 0x4000; /* 16 kBytes */
static void __iomem *mbar;
@@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void)
{ .type = "builtin", .compatible = "mpc5200", }, /* efika */
{}
};
+ u64 regaddr64 = 0;
+ const u32 *regaddr_p;
/* deep sleep? let mpc52xx code handle that */
if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
@@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void)
/* map registers */
np = of_find_matching_node(NULL, immr_ids);
- mbar = of_iomap(np, 0);
+ regaddr_p = of_get_address(np, 0, NULL, NULL);
+ if (regaddr_p)
+ regaddr64 = of_translate_address(np, regaddr_p);
of_node_put(np);
+
+ mbar = ioremap((u32) regaddr64, 0xC000);
if (!mbar) {
printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
return -ENOSYS;
@@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void)
pic = mbar + 0x500;
gps = mbar + 0xb00;
gpw = mbar + 0xc00;
+ pci = mbar + 0xd00;
bes = mbar + 0x1200;
xlb = mbar + 0x1f00;
sram = mbar + 0x8000;
@@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes;
static struct mpc52xx_xlb sxlb;
static struct mpc52xx_gpio sgps;
static struct mpc52xx_gpio_wkup sgpw;
+static char spci[0x200];
static void lite5200_save_regs(void)
{
@@ -94,6 +103,7 @@ static void lite5200_save_regs(void)
_memcpy_fromio(&sxlb, xlb, sizeof(*xlb));
_memcpy_fromio(&sgps, gps, sizeof(*gps));
_memcpy_fromio(&sgpw, gpw, sizeof(*gpw));
+ _memcpy_fromio(spci, pci, 0x200);
_memcpy_fromio(saved_sram, sram, sram_size);
}
@@ -103,6 +113,8 @@ static void lite5200_restore_regs(void)
int i;
_memcpy_toio(sram, saved_sram, sram_size);
+ /* PCI Configuration */
+ _memcpy_toio(pci, spci, 0x200);
/*
* GPIOs. Interrupt Master Enable has higher address then other
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index f52db125432..38f934ab50c 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -226,7 +226,6 @@ CONFIG_CPU_HAS_PTEA=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=16
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index 9fa66d92a4e..b68b6cdbb78 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -231,7 +231,6 @@ CONFIG_CPU_HAS_PTEA=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=16
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=40000000
#
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 84717d85486..490dcbc2ce3 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -239,7 +239,6 @@ CONFIG_CPU_HAS_SR_RB=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=16
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index 240a1cef69a..2dd83af988f 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -236,7 +236,6 @@ CONFIG_CPU_HAS_SR_RB=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=16
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=66666666
#
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index c60b6fd4fc4..167786f9a9b 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -235,7 +235,6 @@ CONFIG_CPU_HAS_PTEA=y
#
CONFIG_SH_TMU=y
CONFIG_SH_TIMER_IRQ=16
-# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e0edaaa6920..bf07b6f50fa 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -966,8 +966,8 @@ config NUMA_EMU
number of nodes. This is only useful for debugging.
config NODES_SHIFT
- int "Max num nodes shift(1-15)"
- range 1 15 if X86_64
+ int "Max num nodes shift(1-9)"
+ range 1 9 if X86_64
default "6" if X86_64
default "4" if X86_NUMAQ
default "3"
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index eb9ddd8efb8..95e80e5033c 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -162,7 +162,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
int ret;
if (!cpu_has_fxsr)
- return -ENODEV;
+ return -EIO;
ret = init_fpu(target);
if (ret)
@@ -179,7 +179,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
int ret;
if (!cpu_has_fxsr)
- return -ENODEV;
+ return -EIO;
ret = init_fpu(target);
if (ret)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 56078d61c79..3e1cecedde4 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -996,7 +996,6 @@ do_rest:
#endif
cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */
cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
- cpu_clear(cpu, cpu_possible_map);
cpu_clear(cpu, cpu_present_map);
per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
}
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 156e6d7b0e3..f6d20be7a8f 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -135,7 +135,7 @@ static __init void *spp_getpage(void)
return ptr;
}
-static void
+static __init void
set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
{
pgd_t *pgd;
@@ -214,7 +214,7 @@ void __init cleanup_highmap(void)
}
/* NOTE: this is meant to be run only at boot */
-void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
{
unsigned long address = __fix_to_virt(idx);
@@ -506,7 +506,7 @@ early_param("memtest", parse_memtest);
static void __init early_memtest(unsigned long start, unsigned long end)
{
- u64 t_start, t_size;
+ unsigned long t_start, t_size;
unsigned pattern;
if (!memtest_pattern)
@@ -525,7 +525,7 @@ static void __init early_memtest(unsigned long start, unsigned long end)
if (t_start + t_size > end)
t_size = end - t_start;
- printk(KERN_CONT "\n %016llx - %016llx pattern %d",
+ printk(KERN_CONT "\n %016lx - %016lx pattern %d",
t_start, t_start + t_size, pattern);
memtest(t_start, t_size, pattern);
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 8c3946787db..743f33a01a0 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -831,6 +831,8 @@ static void as_completed_request(struct request_queue *q, struct request *rq)
}
if (ad->changed_batch && ad->nr_dispatched == 1) {
+ ad->current_batch_expires = jiffies +
+ ad->batch_expire[ad->batch_data_dir];
kblockd_schedule_work(&ad->antic_work);
ad->changed_batch = 0;
diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile
deleted file mode 100644
index d006c9f168d..00000000000
--- a/drivers/acorn/char/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the acorn character device drivers.
-#
-
-obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c
deleted file mode 100644
index 93d80a1c36f..00000000000
--- a/drivers/acorn/char/defkeymap-l7200.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * linux/drivers/acorn/char/defkeymap-l7200.c
- *
- * Default keyboard maps for LinkUp Systems L7200 board
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 08-04-2000 SJH Created file
- */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-/* Normal (maps 1:1 with no processing) */
-#define KTn 0xF0
-/* Function keys */
-#define KTf 0xF1
-/* Special (Performs special house-keeping funcs) */
-#define KTs 0xF2
-#define KIGNORE K(KTs, 0) /* Ignore */
-#define KENTER K(KTs, 1) /* Enter */
-#define KREGS K(KTs, 2) /* Regs */
-#define KMEM K(KTs, 3) /* Mem */
-#define KSTAT K(KTs, 4) /* State */
-#define KINTR K(KTs, 5) /* Intr */
-#define Ksl 6 /* Last console */
-#define KCAPSLK K(KTs, 7) /* Caps lock */
-#define KNUMLK K(KTs, 8) /* Num-lock */
-#define KSCRLLK K(KTs, 9) /* Scroll-lock */
-#define KSCRLFOR K(KTs,10) /* Scroll forward */
-#define KSCRLBAK K(KTs,11) /* Scroll back */
-#define KREBOOT K(KTs,12) /* Reboot */
-#define KCAPSON K(KTs,13) /* Caps on */
-#define KCOMPOSE K(KTs,14) /* Compose */
-#define KSAK K(KTs,15) /* SAK */
-#define CONS_DEC K(KTs,16) /* Dec console */
-#define CONS_INC K(KTs,17) /* Incr console */
-#define KFLOPPY K(KTs,18) /* Floppy */
-/* Key pad (0-9 = digits, 10=+, 11=-, 12=*, 13=/, 14=enter, 16=., 17=# */
-#define KTp 0xF3
-#define KPAD_0 K(KTp, 0 )
-#define KPAD_1 K(KTp, 1 )
-#define KPAD_2 K(KTp, 2 )
-#define KPAD_3 K(KTp, 3 )
-#define KPAD_4 K(KTp, 4 )
-#define KPAD_5 K(KTp, 5 )
-#define KPAD_6 K(KTp, 6 )
-#define KPAD_7 K(KTp, 7 )
-#define KPAD_8 K(KTp, 8 )
-#define KPAD_9 K(KTp, 9 )
-#define KPAD_PL K(KTp,10 )
-#define KPAD_MI K(KTp,11 )
-#define KPAD_ML K(KTp,12 )
-#define KPAD_DV K(KTp,13 )
-#define KPAD_EN K(KTp,14 )
-#define KPAD_DT K(KTp,16 )
-#define KPAD_HS K(KTp,20 )
-/* Console switching */
-#define KCn 0xF5
-/* Cursor */
-#define KTc 0xF6
-#define Kcd 0 /* Cursor down */
-#define Kcl 1 /* Cursor left */
-#define Kcr 2 /* Cursor right */
-#define Kcu 3 /* Cursor up */
-/* Shift/alt modifiers etc */
-#define KMd 0xF7
-#define KSHIFT K(KMd, 0 )
-#define KALTGR K(KMd, 1 )
-#define KCTRL K(KMd, 2 )
-#define KALT K(KMd, 3 )
-/* Meta */
-#define KMt 0xF8
-#define KAs 0xF9
-#define KPADA_0 K(KAs, 0 )
-#define KPADA_1 K(KAs, 1 )
-#define KPADA_2 K(KAs, 2 )
-#define KPADA_3 K(KAs, 3 )
-#define KPADA_4 K(KAs, 4 )
-#define KPADA_5 K(KAs, 5 )
-#define KPADA_6 K(KAs, 6 )
-#define KPADA_7 K(KAs, 7 )
-#define KPADA_8 K(KAs, 8 )
-#define KPADA_9 K(KAs, 9 )
-#define KPADB_0 K(KAs,10 )
-#define KPADB_1 K(KAs,11 )
-#define KPADB_2 K(KAs,12 )
-#define KPADB_3 K(KAs,13 )
-#define KPADB_4 K(KAs,14 )
-#define KPADB_5 K(KAs,15 )
-#define KPADB_6 K(KAs,16 )
-#define KPADB_7 K(KAs,17 )
-#define KPADB_8 K(KAs,18 )
-#define KPADB_9 K(KAs,19 )
-/* Locking keys */
-#define KLk 0xFA
-/* Letters */
-#define KTl 0xFB
-
-/*
- * Here is the layout of the keys for the Fujitsu QWERTY
- * style keyboard:
- *
- * static char Fujitsu_Key_Table[] =
- * {
- * KALT, '`' , KNUL, KCTL, KFUN, KESC, '1' , '2' ,
- * '9' , '0' , '-' , '=' , KNUL, KBSP, KNUL, KNUL,
- * KNUL, KBSL, KSHF, KNUL, KNUL, KDEL, KNUL, 't' ,
- * 'y' , 'u' , 'i' , KRET, KSHF, KPGD, KNUL, KNUL,
- * KNUL, KTAB, KNUL, KNUL, KNUL, 'q' , 'w' , 'e' ,
- * 'r' , 'o' , 'p' , '[' , KNUL, ']' , KNUL, KNUL,
- * KNUL, 'z' , KNUL, KNUL, KNUL, KSHL, KNUL, KNUL,
- * 'k' , 'l' , ';' , KSQT, KNUL, KPGU, KNUL, KNUL,
- * KNUL, 'a' , KNUL, KNUL, KNUL, 's' , 'd' , 'f' ,
- * 'g' , 'h' , 'j' , '/' , KNUL, KHME, KNUL, KNUL,
- * KNUL, 'x' , KNUL, KNUL, KNUL, 'c' , 'v' , 'b' ,
- * 'n' , 'm' , ',' , '.' , KNUL, ' ' , KNUL, KNUL,
- * KNUL, KNUL, KNUL, KNUL, KNUL, '3' , '4' , '5' ,
- * '6' , '7' , '8' , KNUL, KPRG, KNUL, KEND, KNUL,
- * };
- */
-
-u_short plain_map[NR_KEYS]=
-{
- 0xf703, 0xf060, 0xf200, 0xf702, 0xf200, 0xf01b, 0xf031, 0xf032,
- 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf200, 0xf07f, 0xf200, 0xf200,
- 0xf200, 0xf05c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xfb74,
- 0xfb79, 0xfb75, 0xfb69, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
- 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xfb71, 0xfb77, 0xfb65,
- 0xfb72, 0xfb6f, 0xfb70, 0xf05b, 0xf200, 0xf05d, 0xf200, 0xf200,
- 0xf200, 0xfb7a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
- 0xfb6b, 0xfb6c, 0xf03b, 0xf027, 0xf200, 0xf603, 0xf200, 0xf200,
- 0xf200, 0xfb61, 0xf200, 0xf200, 0xf200, 0xfb73, 0xfb64, 0xfb66,
- 0xfb67, 0xfb68, 0xfb6a, 0xf02f, 0xf200, 0xf601, 0xf200, 0xf200,
- 0xf200, 0xfb78, 0xf200, 0xf200, 0xf200, 0xfb63, 0xfb76, 0xfb62,
- 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf200, 0xf020, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf033, 0xf034, 0xf035,
- 0xf036, 0xf037, 0xf038, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short shift_map[NR_KEYS]=
-{
- 0xf703, 0xf07e, 0xf200, 0xf702, 0xf200, 0xf01b, 0xf021, 0xf040,
- 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf200, 0xf07f, 0xf200, 0xf200,
- 0xf200, 0xf07c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xfb54,
- 0xfb59, 0xfb55, 0xfb49, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
- 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xfb51, 0xfb57, 0xfb45,
- 0xfb52, 0xfb4f, 0xfb50, 0xf07b, 0xf200, 0xf07d, 0xf200, 0xf200,
- 0xf200, 0xfb5a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
- 0xfb4b, 0xfb4c, 0xf03a, 0xf022, 0xf200, 0xf603, 0xf200, 0xf200,
- 0xf200, 0xfb41, 0xf200, 0xf200, 0xf200, 0xfb53, 0xfb44, 0xfb46,
- 0xfb47, 0xfb48, 0xfb4a, 0xf03f, 0xf200, 0xf601, 0xf200, 0xf200,
- 0xf200, 0xfb58, 0xf200, 0xf200, 0xf200, 0xfb43, 0xfb56, 0xfb42,
- 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf200, 0xf020, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf023, 0xf024, 0xf025,
- 0xf05e, 0xf026, 0xf02a, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short altgr_map[NR_KEYS]=
-{
- KIGNORE ,K(KCn,12 ),K(KCn,13 ),K(KCn,14 ),K(KCn,15 ),K(KCn,16 ),K(KCn,17 ),K(KCn, 18),
- K(KCn, 19),K(KCn,20 ),K(KCn,21 ),K(KCn,22 ),K(KCn,23 ),KIGNORE ,KREGS ,KINTR ,
- KIGNORE ,KIGNORE ,K(KTn,'@'),KIGNORE ,K(KTn,'$'),KIGNORE ,KIGNORE ,K(KTn,'{'),
- K(KTn,'['),K(KTn,']'),K(KTn,'}'),K(KTn,'\\'),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
- K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KTl,'q'),
- K(KTl,'w'),K(KTl,'e'),K(KTl,'r'),K(KTl,'t' ),K(KTl,'y'),K(KTl,'u'),K(KTl,'i' ),K(KTl,'o'),
- K(KTl,'p'),KIGNORE ,K(KTn,'~'),KIGNORE ,K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPADB_7 ,
- KPADB_8 ,KPADB_9 ,KPAD_MI ,KCTRL ,K(KAs,20 ),K(KTl,'s'),K(KAs,23 ),K(KAs,25 ),
- K(KTl,'g'),K(KTl,'h'),K(KTl,'j'),K(KTl,'k' ),K(KTl,'l'),KIGNORE ,KIGNORE ,KENTER ,
- KPADB_4 ,KPADB_5 ,KPADB_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KTl,'z' ),K(KTl,'x'),
- K(KAs,22 ),K(KTl,'v'),K(KTl,21 ),K(KTl,'n' ),K(KTl,'m'),KIGNORE ,KIGNORE ,KIGNORE ,
- KSHIFT ,K(KTc,Kcu),KPADB_1 ,KPADB_2 ,KPADB_3 ,KCAPSLK ,KALT ,KIGNORE ,
- KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPADB_0 ,KPAD_DT ,KPAD_EN ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
-};
-
-u_short ctrl_map[NR_KEYS]=
-{
- 0xf703, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200, 0xf001, 0xf002,
- 0xf009, 0xf000, 0xf031, 0xf200, 0xf200, 0xf07f, 0xf200, 0xf200,
- 0xf200, 0xf01c, 0xf700, 0xf200, 0xf200, 0xf116, 0xf000, 0xf020,
- 0xf019, 0xf015, 0xf009, 0xf201, 0xf700, 0xf600, 0xf200, 0xf200,
- 0xf200, 0xf009, 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005,
- 0xf012, 0xf00f, 0xf010, 0xf01b, 0xf200, 0xf01d, 0xf200, 0xf200,
- 0xf200, 0xf01a, 0xf200, 0xf200, 0xf200, 0xf207, 0xf200, 0xf200,
- 0xf00b, 0xf00c, 0xf200, 0xf007, 0xf200, 0xf603, 0xf200, 0xf200,
- 0xf200, 0xf001, 0xf200, 0xf200, 0xf200, 0xf001, 0xf013, 0xf006,
- 0xf007, 0xf008, 0xf00a, 0xf07f, 0xf200, 0xf601, 0xf200, 0xf200,
- 0xf200, 0xf018, 0xf200, 0xf200, 0xf200, 0xf003, 0xf016, 0xf002,
- 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b, 0xf01c, 0xf01d,
- 0xf036, 0xf037, 0xf038, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf602, 0xf200,
-};
-
-u_short shift_ctrl_map[NR_KEYS]=
-{
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KFLOPPY ,KINTR ,
- KIGNORE ,KIGNORE ,K(KTn, 0 ),KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,K(KTn,31 ),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
- K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KTn,17 ),
- K(KTn,23 ),K(KTn, 5 ),K(KTn,18 ),K(KTn,20 ),K(KTn,25 ),K(KTn,21 ),K(KTn, 9 ),K(KTn,15 ),
- K(KTn,16 ),KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPAD_7 ,
- KPAD_8 ,KPAD_9 ,KPAD_MI ,KCTRL ,K(KTn, 1 ),K(KTn,19 ),K(KTn, 4 ),K(KTn, 6 ),
- K(KTn, 7 ),K(KTn, 8 ),K(KTn,10 ),K(KTn,11 ),K(KTn,12 ),KIGNORE ,K(KTn, 7 ),KENTER ,
- KPAD_4 ,KPAD_5 ,KPAD_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KTn,26 ),K(KTn,24 ),
- K(KTn, 3 ),K(KTn,22 ),K(KTn, 2 ),K(KTn,14 ),K(KTn,13 ),KIGNORE ,KIGNORE ,KIGNORE ,
- KSHIFT ,K(KTc,Kcu),KPAD_1 ,KPAD_2 ,KPAD_3 ,KCAPSLK ,KALT ,K(KTn, 0 ),
- KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPAD_0 ,KPAD_DT ,KPAD_EN ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
-};
-
-u_short alt_map[NR_KEYS]=
-{
- K(KMt,27 ),K(KCn, 0 ),K(KCn, 1 ),K(KCn, 2 ),K(KCn, 3 ),K(KCn, 4 ),K(KCn, 5 ),K(KCn, 6 ),
- K(KCn, 7 ),K(KCn, 8 ),K(KCn, 9 ),K(KCn,10 ),K(KCn,11 ),KIGNORE ,KSCRLLK ,KINTR ,
- K(KMt,'`'),K(KMt,'1'),K(KMt,'2'),K(KMt,'3' ),K(KMt,'4'),K(KMt,'5'),K(KMt,'6' ),K(KMt,'7'),
- K(KMt,'8'),K(KMt,'9'),K(KMt,'0'),K(KMt,'-' ),K(KMt,'='),K(KMt,'£'),K(KMt,127 ),K(KTf,21 ),
- K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,K(KMt, 9 ),K(KMt,'q'),
- K(KMt,'w'),K(KMt,'e'),K(KMt,'r'),K(KMt,'t' ),K(KMt,'y'),K(KMt,'u'),K(KMt,'i' ),K(KMt,'o'),
- K(KMt,'p'),K(KMt,'['),K(KMt,']'),K(KMt,'\\'),K(KTf,22 ),K(KTf,23 ),K(KTf,25 ),KPADA_7 ,
- KPADA_8 ,KPADA_9 ,KPAD_MI ,KCTRL ,K(KMt,'a'),K(KMt,'s'),K(KMt,'d' ),K(KMt,'f'),
- K(KMt,'g'),K(KMt,'h'),K(KMt,'j'),K(KMt,'k' ),K(KMt,'l'),K(KMt,';'),K(KMt,'\''),K(KMt,13 ),
- KPADA_4 ,KPADA_5 ,KPADA_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KMt,'z' ),K(KMt,'x'),
- K(KMt,'c'),K(KMt,'v'),K(KMt,'b'),K(KMt,'n' ),K(KMt,'m'),K(KMt,','),K(KMt,'.' ),KIGNORE ,
- KSHIFT ,K(KTc,Kcu),KPADA_1 ,KPADA_2 ,KPADA_3 ,KCAPSLK ,KALT ,K(KMt,' '),
- KALTGR ,KCTRL ,CONS_DEC ,K(KTc,Kcd ),CONS_INC ,KPADA_0 ,KPAD_DT ,KPAD_EN ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
-};
-
-u_short ctrl_alt_map[NR_KEYS]=
-{
- KIGNORE ,K(KCn, 0 ),K(KCn, 1 ),K(KCn, 2 ),K(KCn, 3 ),K(KCn, 4 ),K(KCn, 5 ),K(KCn, 6 ),
- K(KCn, 7 ),K(KCn, 8 ),K(KCn, 9 ),K(KCn,10 ),K(KCn,11 ),KIGNORE ,KIGNORE ,KINTR ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,K(KTf,21 ),
- K(KTf,20 ),K(KTf,24 ),KNUMLK ,KPAD_DV ,KPAD_ML ,KPAD_HS ,KIGNORE ,K(KMt,17 ),
- K(KMt,23 ),K(KMt, 5 ),K(KMt,18 ),K(KMt,20 ),K(KMt,25 ),K(KMt,21 ),K(KMt, 9 ),K(KMt,15 ),
- K(KMt,16 ),KIGNORE ,KIGNORE ,KIGNORE ,KREBOOT ,K(KTf,23 ),K(KTf,25 ),KPAD_7 ,
- KPAD_8 ,KPAD_9 ,KPAD_MI ,KCTRL ,K(KMt, 1 ),K(KMt,19 ),K(KMt, 4 ),K(KMt, 6 ),
- K(KMt, 7 ),K(KMt, 8 ),K(KMt,10 ),K(KMt,11 ),K(KMt,12 ),KIGNORE ,KIGNORE ,KENTER ,
- KPAD_4 ,KPAD_5 ,KPAD_6 ,KPAD_PL ,KSHIFT ,KIGNORE ,K(KMt,26 ),K(KMt,24 ),
- K(KMt, 3 ),K(KMt,22 ),K(KMt, 2 ),K(KMt,14 ),K(KMt,13 ),KIGNORE ,KIGNORE ,KIGNORE ,
- KSHIFT ,K(KTc,Kcu),KPAD_1 ,KPAD_2 ,KPAD_3 ,KCAPSLK ,KALT ,KIGNORE ,
- KALTGR ,KCTRL ,K(KTc,Kcl),K(KTc,Kcd ),K(KTc,Kcr),KPAD_0 ,KREBOOT ,KPAD_EN ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
- KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,KIGNORE ,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
- plain_map, shift_map, altgr_map, 0,
- ctrl_map, shift_ctrl_map, 0, 0,
- alt_map, 0, 0, 0,
- ctrl_alt_map, 0
-};
-
-unsigned int keymap_count = 7;
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
- '\033', '[', '[', 'A', 0,
- '\033', '[', '[', 'B', 0,
- '\033', '[', '[', 'C', 0,
- '\033', '[', '[', 'D', 0,
- '\033', '[', '[', 'E', 0,
- '\033', '[', '1', '7', '~', 0,
- '\033', '[', '1', '8', '~', 0,
- '\033', '[', '1', '9', '~', 0,
- '\033', '[', '2', '0', '~', 0,
- '\033', '[', '2', '1', '~', 0,
- '\033', '[', '2', '3', '~', 0,
- '\033', '[', '2', '4', '~', 0,
- '\033', '[', '2', '5', '~', 0,
- '\033', '[', '2', '6', '~', 0,
- '\033', '[', '2', '8', '~', 0,
- '\033', '[', '2', '9', '~', 0,
- '\033', '[', '3', '1', '~', 0,
- '\033', '[', '3', '2', '~', 0,
- '\033', '[', '3', '3', '~', 0,
- '\033', '[', '3', '4', '~', 0,
- '\033', '[', '1', '~', 0,
- '\033', '[', '2', '~', 0,
- '\033', '[', '3', '~', 0,
- '\033', '[', '4', '~', 0,
- '\033', '[', '5', '~', 0,
- '\033', '[', '6', '~', 0,
- '\033', '[', 'M', 0,
- '\033', '[', 'P', 0,
-};
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0; /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
- func_buf + 0,
- func_buf + 5,
- func_buf + 10,
- func_buf + 15,
- func_buf + 20,
- func_buf + 25,
- func_buf + 31,
- func_buf + 37,
- func_buf + 43,
- func_buf + 49,
- func_buf + 55,
- func_buf + 61,
- func_buf + 67,
- func_buf + 73,
- func_buf + 79,
- func_buf + 85,
- func_buf + 91,
- func_buf + 97,
- func_buf + 103,
- func_buf + 109,
- func_buf + 115,
- func_buf + 120,
- func_buf + 125,
- func_buf + 130,
- func_buf + 135,
- func_buf + 140,
- func_buf + 145,
- 0,
- 0,
- func_buf + 149,
- 0,
-};
-
-struct kbdiacruc accent_table[MAX_DIACR] = {
- {'`', 'A', 0300}, {'`', 'a', 0340},
- {'\'', 'A', 0301}, {'\'', 'a', 0341},
- {'^', 'A', 0302}, {'^', 'a', 0342},
- {'~', 'A', 0303}, {'~', 'a', 0343},
- {'"', 'A', 0304}, {'"', 'a', 0344},
- {'O', 'A', 0305}, {'o', 'a', 0345},
- {'0', 'A', 0305}, {'0', 'a', 0345},
- {'A', 'A', 0305}, {'a', 'a', 0345},
- {'A', 'E', 0306}, {'a', 'e', 0346},
- {',', 'C', 0307}, {',', 'c', 0347},
- {'`', 'E', 0310}, {'`', 'e', 0350},
- {'\'', 'E', 0311}, {'\'', 'e', 0351},
- {'^', 'E', 0312}, {'^', 'e', 0352},
- {'"', 'E', 0313}, {'"', 'e', 0353},
- {'`', 'I', 0314}, {'`', 'i', 0354},
- {'\'', 'I', 0315}, {'\'', 'i', 0355},
- {'^', 'I', 0316}, {'^', 'i', 0356},
- {'"', 'I', 0317}, {'"', 'i', 0357},
- {'-', 'D', 0320}, {'-', 'd', 0360},
- {'~', 'N', 0321}, {'~', 'n', 0361},
- {'`', 'O', 0322}, {'`', 'o', 0362},
- {'\'', 'O', 0323}, {'\'', 'o', 0363},
- {'^', 'O', 0324}, {'^', 'o', 0364},
- {'~', 'O', 0325}, {'~', 'o', 0365},
- {'"', 'O', 0326}, {'"', 'o', 0366},
- {'/', 'O', 0330}, {'/', 'o', 0370},
- {'`', 'U', 0331}, {'`', 'u', 0371},
- {'\'', 'U', 0332}, {'\'', 'u', 0372},
- {'^', 'U', 0333}, {'^', 'u', 0373},
- {'"', 'U', 0334}, {'"', 'u', 0374},
- {'\'', 'Y', 0335}, {'\'', 'y', 0375},
- {'T', 'H', 0336}, {'t', 'h', 0376},
- {'s', 's', 0337}, {'"', 'y', 0377},
- {'s', 'z', 0337}, {'i', 'j', 0377},
-};
-
-unsigned int accent_table_size = 68;
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 26038c2a2a7..61b6c5beb2d 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -377,6 +377,9 @@ static int __init bay_init(void)
INIT_LIST_HEAD(&drive_bays);
+ if (acpi_disabled)
+ return -ENODEV;
+
/* look for dockable drive bays */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_bay, &bays, NULL);
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 96c542f7fde..bb7c51f712b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -917,6 +917,9 @@ static int __init dock_init(void)
dock_station = NULL;
+ if (acpi_disabled)
+ return 0;
+
/* look for a dock station */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock, &num, NULL);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 2808dc60fd6..9b227d4dc9c 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void)
{
struct device *dev = get_rtc_dev();
+ if (acpi_disabled)
+ return 0;
+
if (dev) {
rtc_wake_setup();
rtc_info.wake_on = rtc_wake_on;
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index f7f16e7a8bf..df036118b8b 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -62,11 +62,11 @@ static void i915_vblank_tasklet(struct drm_device *dev)
u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
RING_LOCALS;
- if (sarea_priv->front_tiled) {
+ if (IS_I965G(dev) && sarea_priv->front_tiled) {
cmd |= XY_SRC_COPY_BLT_DST_TILED;
dst_pitch >>= 2;
}
- if (sarea_priv->back_tiled) {
+ if (IS_I965G(dev) && sarea_priv->back_tiled) {
cmd |= XY_SRC_COPY_BLT_SRC_TILED;
src_pitch >>= 2;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e94bee03231..750131010af 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3322,7 +3322,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
msleep_interruptible(duration);
tty->ops->break_ctl(tty, 0);
tty_write_unlock(tty);
- if (!signal_pending(current))
+ if (signal_pending(current))
return -EINTR;
return 0;
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 85e2ba7fcfb..bf4830082a1 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -27,6 +27,8 @@
#include <linux/moduleparam.h>
#include <linux/connector.h>
#include <linux/mutex.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
#include <net/sock.h>
@@ -403,6 +405,40 @@ static void cn_callback(void *data)
mutex_unlock(&notify_lock);
}
+static int cn_proc_show(struct seq_file *m, void *v)
+{
+ struct cn_queue_dev *dev = cdev.cbdev;
+ struct cn_callback_entry *cbq;
+
+ seq_printf(m, "Name ID\n");
+
+ spin_lock_bh(&dev->queue_lock);
+
+ list_for_each_entry(cbq, &dev->queue_list, callback_entry) {
+ seq_printf(m, "%-15s %u:%u\n",
+ cbq->id.name,
+ cbq->id.id.idx,
+ cbq->id.id.val);
+ }
+
+ spin_unlock_bh(&dev->queue_lock);
+
+ return 0;
+}
+
+static int cn_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cn_proc_show, NULL);
+}
+
+static const struct file_operations cn_file_ops = {
+ .owner = THIS_MODULE,
+ .open = cn_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release
+};
+
static int __devinit cn_init(void)
{
struct cn_dev *dev = &cdev;
@@ -434,6 +470,8 @@ static int __devinit cn_init(void)
return -EINVAL;
}
+ proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);
+
return 0;
}
@@ -443,6 +481,8 @@ static void __devexit cn_fini(void)
cn_already_initialized = 0;
+ proc_net_remove(&init_net, "connector");
+
cn_del_callback(&dev->id);
cn_queue_free_dev(dev->cbdev);
netlink_kernel_release(dev->nls);
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index b2458bb8e9c..227d2e036cd 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -1051,7 +1051,8 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
break;
case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
- if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
+ /* Adjust for the increment in the iterator */
+ if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0)
return -ENOMEM;
break;
}
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 1305ef190fc..9e8c875437b 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -290,12 +290,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* bus, or started a new i2c message
*/
- if (iicstat & S3C2410_IICSTAT_LASTBIT &&
+ if (iicstat & S3C2410_IICSTAT_LASTBIT &&
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */
dev_dbg(i2c->dev, "ack was not received\n");
- s3c24xx_i2c_stop(i2c, -EREMOTEIO);
+ s3c24xx_i2c_stop(i2c, -ENXIO);
goto out_ack;
}
@@ -305,7 +305,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
i2c->state = STATE_WRITE;
/* terminate the transfer if there is nothing to do
- * (used by the i2c probe to find devices */
+ * as this is used by the i2c probe to find devices. */
if (is_lastmsg(i2c) && i2c->msg->len == 0) {
s3c24xx_i2c_stop(i2c, 0);
@@ -323,7 +323,17 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* end of the message, and if so, work out what to do
*/
+ if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
+ if (iicstat & S3C2410_IICSTAT_LASTBIT) {
+ dev_dbg(i2c->dev, "WRITE: No Ack\n");
+
+ s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
+ goto out_ack;
+ }
+ }
+
retry_write:
+
if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + S3C2410_IICDS);
@@ -377,17 +387,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* going to do any more read/write
*/
- if (!(i2c->msg->flags & I2C_M_IGNORE_NAK) &&
- !(is_msglast(i2c) && is_lastmsg(i2c))) {
-
- if (iicstat & S3C2410_IICSTAT_LASTBIT) {
- dev_dbg(i2c->dev, "READ: No Ack\n");
-
- s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
- goto out_ack;
- }
- }
-
byte = readb(i2c->regs + S3C2410_IICDS);
i2c->msg->buf[i2c->msg_ptr++] = byte;
@@ -949,3 +948,4 @@ MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s3c2410-i2c");
+MODULE_ALIAS("platform:s3c2440-i2c");
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index b1b45dddb17..03a33f1b9cd 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -72,7 +72,7 @@ struct isp1301 {
};
-/* bits in OTG_CTRL_REG */
+/* bits in OTG_CTRL */
#define OTG_XCEIV_OUTPUTS \
(OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
@@ -186,8 +186,8 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits)
/* operational registers */
#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */
-# define MC1_SPEED_REG (1 << 0)
-# define MC1_SUSPEND_REG (1 << 1)
+# define MC1_SPEED (1 << 0)
+# define MC1_SUSPEND (1 << 1)
# define MC1_DAT_SE0 (1 << 2)
# define MC1_TRANSPARENT (1 << 3)
# define MC1_BDIS_ACON_EN (1 << 4)
@@ -274,7 +274,7 @@ static void power_down(struct isp1301 *isp)
isp->otg.state = OTG_STATE_UNDEFINED;
// isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG);
+ isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND);
isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN);
isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
@@ -283,7 +283,7 @@ static void power_down(struct isp1301 *isp)
static void power_up(struct isp1301 *isp)
{
// isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG);
+ isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND);
/* do this only when cpu is driving transceiver,
* so host won't see a low speed device...
@@ -360,6 +360,8 @@ isp1301_defer_work(struct isp1301 *isp, int work)
/* called from irq handlers */
static void a_idle(struct isp1301 *isp, const char *tag)
{
+ u32 l;
+
if (isp->otg.state == OTG_STATE_A_IDLE)
return;
@@ -373,13 +375,17 @@ static void a_idle(struct isp1301 *isp, const char *tag)
gadget_suspend(isp);
}
isp->otg.state = OTG_STATE_A_IDLE;
- isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
+ l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS;
+ omap_writel(l, OTG_CTRL);
+ isp->last_otg_ctrl = l;
pr_debug(" --> %s/%s\n", state_name(isp), tag);
}
/* called from irq handlers */
static void b_idle(struct isp1301 *isp, const char *tag)
{
+ u32 l;
+
if (isp->otg.state == OTG_STATE_B_IDLE)
return;
@@ -393,7 +399,9 @@ static void b_idle(struct isp1301 *isp, const char *tag)
gadget_suspend(isp);
}
isp->otg.state = OTG_STATE_B_IDLE;
- isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
+ l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS;
+ omap_writel(l, OTG_CTRL);
+ isp->last_otg_ctrl = l;
pr_debug(" --> %s/%s\n", state_name(isp), tag);
}
@@ -406,7 +414,7 @@ dump_regs(struct isp1301 *isp, const char *label)
u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE);
pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n",
- OTG_CTRL_REG, label, state_name(isp),
+ omap_readl(OTG_CTRL), label, state_name(isp),
ctrl, status, src);
/* mode control and irq enables don't change much */
#endif
@@ -429,7 +437,7 @@ dump_regs(struct isp1301 *isp, const char *label)
static void check_state(struct isp1301 *isp, const char *tag)
{
enum usb_otg_state state = OTG_STATE_UNDEFINED;
- u8 fsm = OTG_TEST_REG & 0x0ff;
+ u8 fsm = omap_readw(OTG_TEST) & 0x0ff;
unsigned extra = 0;
switch (fsm) {
@@ -494,7 +502,8 @@ static void check_state(struct isp1301 *isp, const char *tag)
if (isp->otg.state == state && !extra)
return;
pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag,
- state_string(state), fsm, state_name(isp), OTG_CTRL_REG);
+ state_string(state), fsm, state_name(isp),
+ omap_readl(OTG_CTRL));
}
#else
@@ -508,10 +517,11 @@ static void update_otg1(struct isp1301 *isp, u8 int_src)
{
u32 otg_ctrl;
- otg_ctrl = OTG_CTRL_REG
- & OTG_CTRL_MASK
- & ~OTG_XCEIV_INPUTS
- & ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD);
+ otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
+ otg_ctrl &= ~OTG_XCEIV_INPUTS;
+ otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD);
+
+
if (int_src & INTR_SESS_VLD)
otg_ctrl |= OTG_ASESSVLD;
else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) {
@@ -534,7 +544,7 @@ static void update_otg1(struct isp1301 *isp, u8 int_src)
return;
}
}
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
}
/* outputs from ISP1301_OTG_STATUS */
@@ -542,15 +552,14 @@ static void update_otg2(struct isp1301 *isp, u8 otg_status)
{
u32 otg_ctrl;
- otg_ctrl = OTG_CTRL_REG
- & OTG_CTRL_MASK
- & ~OTG_XCEIV_INPUTS
- & ~(OTG_BSESSVLD|OTG_BSESSEND);
+ otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
+ otg_ctrl &= ~OTG_XCEIV_INPUTS;
+ otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND);
if (otg_status & OTG_B_SESS_VLD)
otg_ctrl |= OTG_BSESSVLD;
else if (otg_status & OTG_B_SESS_END)
otg_ctrl |= OTG_BSESSEND;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
}
/* inputs going to ISP1301 */
@@ -559,7 +568,7 @@ static void otg_update_isp(struct isp1301 *isp)
u32 otg_ctrl, otg_change;
u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP;
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
otg_change = otg_ctrl ^ isp->last_otg_ctrl;
isp->last_otg_ctrl = otg_ctrl;
otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS;
@@ -639,6 +648,8 @@ pulldown:
/* HNP switch to host or peripheral; and SRP */
if (otg_change & OTG_PULLUP) {
+ u32 l;
+
switch (isp->otg.state) {
case OTG_STATE_B_IDLE:
if (clr & OTG1_DP_PULLUP)
@@ -655,7 +666,9 @@ pulldown:
default:
break;
}
- OTG_CTRL_REG |= OTG_PULLUP;
+ l = omap_readl(OTG_CTRL);
+ l |= OTG_PULLUP;
+ omap_writel(l, OTG_CTRL);
}
check_state(isp, __func__);
@@ -664,20 +677,20 @@ pulldown:
static irqreturn_t omap_otg_irq(int irq, void *_isp)
{
- u16 otg_irq = OTG_IRQ_SRC_REG;
+ u16 otg_irq = omap_readw(OTG_IRQ_SRC);
u32 otg_ctrl;
int ret = IRQ_NONE;
struct isp1301 *isp = _isp;
/* update ISP1301 transciever from OTG controller */
if (otg_irq & OPRT_CHG) {
- OTG_IRQ_SRC_REG = OPRT_CHG;
+ omap_writew(OPRT_CHG, OTG_IRQ_SRC);
isp1301_defer_work(isp, WORK_UPDATE_ISP);
ret = IRQ_HANDLED;
/* SRP to become b_peripheral failed */
} else if (otg_irq & B_SRP_TMROUT) {
- pr_debug("otg: B_SRP_TIMEOUT, %06x\n", OTG_CTRL_REG);
+ pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL));
notresponding(isp);
/* gadget drivers that care should monitor all kinds of
@@ -687,31 +700,31 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
if (isp->otg.state == OTG_STATE_B_SRP_INIT)
b_idle(isp, "srp_timeout");
- OTG_IRQ_SRC_REG = B_SRP_TMROUT;
+ omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
/* HNP to become b_host failed */
} else if (otg_irq & B_HNP_FAIL) {
pr_debug("otg: %s B_HNP_FAIL, %06x\n",
- state_name(isp), OTG_CTRL_REG);
+ state_name(isp), omap_readl(OTG_CTRL));
notresponding(isp);
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
otg_ctrl |= OTG_BUSDROP;
otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
/* subset of b_peripheral()... */
isp->otg.state = OTG_STATE_B_PERIPHERAL;
pr_debug(" --> b_peripheral\n");
- OTG_IRQ_SRC_REG = B_HNP_FAIL;
+ omap_writew(B_HNP_FAIL, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
/* detect SRP from B-device ... */
} else if (otg_irq & A_SRP_DETECT) {
pr_debug("otg: %s SRP_DETECT, %06x\n",
- state_name(isp), OTG_CTRL_REG);
+ state_name(isp), omap_readl(OTG_CTRL));
isp1301_defer_work(isp, WORK_UPDATE_OTG);
switch (isp->otg.state) {
@@ -719,49 +732,49 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
if (!isp->otg.host)
break;
isp1301_defer_work(isp, WORK_HOST_RESUME);
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
otg_ctrl |= OTG_A_BUSREQ;
otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ)
& ~OTG_XCEIV_INPUTS
& OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
break;
default:
break;
}
- OTG_IRQ_SRC_REG = A_SRP_DETECT;
+ omap_writew(A_SRP_DETECT, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
/* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise)
* we don't track them separately
*/
} else if (otg_irq & A_REQ_TMROUT) {
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
pr_info("otg: BCON_TMOUT from %s, %06x\n",
state_name(isp), otg_ctrl);
notresponding(isp);
otg_ctrl |= OTG_BUSDROP;
otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
isp->otg.state = OTG_STATE_A_WAIT_VFALL;
- OTG_IRQ_SRC_REG = A_REQ_TMROUT;
+ omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
/* A-supplied voltage fell too low; overcurrent */
} else if (otg_irq & A_VBUS_ERR) {
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n",
state_name(isp), otg_irq, otg_ctrl);
otg_ctrl |= OTG_BUSDROP;
otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
isp->otg.state = OTG_STATE_A_VBUS_ERR;
- OTG_IRQ_SRC_REG = A_VBUS_ERR;
+ omap_writew(A_VBUS_ERR, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
/* switch driver; the transciever code activates it,
@@ -770,7 +783,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
} else if (otg_irq & DRIVER_SWITCH) {
int kick = 0;
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n",
state_name(isp),
(otg_ctrl & OTG_DRIVER_SEL)
@@ -793,7 +806,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
} else {
if (!(otg_ctrl & OTG_ID)) {
otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ;
+ omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL);
}
if (isp->otg.host) {
@@ -818,7 +831,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
}
}
- OTG_IRQ_SRC_REG = DRIVER_SWITCH;
+ omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC);
ret = IRQ_HANDLED;
if (kick)
@@ -834,12 +847,15 @@ static struct platform_device *otg_dev;
static int otg_init(struct isp1301 *isp)
{
+ u32 l;
+
if (!otg_dev)
return -ENODEV;
dump_regs(isp, __func__);
/* some of these values are board-specific... */
- OTG_SYSCON_2_REG |= OTG_EN
+ l = omap_readl(OTG_SYSCON_2);
+ l |= OTG_EN
/* for B-device: */
| SRP_GPDATA /* 9msec Bdev D+ pulse */
| SRP_GPDVBUS /* discharge after VBUS pulse */
@@ -849,18 +865,22 @@ static int otg_init(struct isp1301 *isp)
| SRP_DPW /* detect 167+ns SRP pulses */
| SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */
;
+ omap_writel(l, OTG_SYSCON_2);
update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
check_state(isp, __func__);
pr_debug("otg: %s, %s %06x\n",
- state_name(isp), __func__, OTG_CTRL_REG);
+ state_name(isp), __func__, omap_readl(OTG_CTRL));
- OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
+ omap_writew(DRIVER_SWITCH | OPRT_CHG
| B_SRP_TMROUT | B_HNP_FAIL
- | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT;
- OTG_SYSCON_2_REG |= OTG_EN;
+ | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN);
+
+ l = omap_readl(OTG_SYSCON_2);
+ l |= OTG_EN;
+ omap_writel(l, OTG_SYSCON_2);
return 0;
}
@@ -927,7 +947,11 @@ static void otg_unbind(struct isp1301 *isp)
static void b_peripheral(struct isp1301 *isp)
{
- OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
+ u32 l;
+
+ l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS;
+ omap_writel(l, OTG_CTRL);
+
usb_gadget_vbus_connect(isp->otg.gadget);
#ifdef CONFIG_USB_OTG
@@ -999,6 +1023,8 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
isp_bstat = 0;
}
} else {
+ u32 l;
+
/* if user unplugged mini-A end of cable,
* don't bypass A_WAIT_VFALL.
*/
@@ -1019,8 +1045,9 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1,
MC1_BDIS_ACON_EN);
isp->otg.state = OTG_STATE_B_IDLE;
- OTG_CTRL_REG &= OTG_CTRL_REG & OTG_CTRL_MASK
- & ~OTG_CTRL_BITS;
+ l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
+ l &= ~OTG_CTRL_BITS;
+ omap_writel(l, OTG_CTRL);
break;
case OTG_STATE_B_IDLE:
break;
@@ -1046,7 +1073,8 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
/* FALLTHROUGH */
case OTG_STATE_B_SRP_INIT:
b_idle(isp, __func__);
- OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
+ l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS;
+ omap_writel(l, OTG_CTRL);
/* FALLTHROUGH */
case OTG_STATE_B_IDLE:
if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) {
@@ -1130,11 +1158,11 @@ isp1301_work(struct work_struct *work)
case OTG_STATE_A_WAIT_VRISE:
isp->otg.state = OTG_STATE_A_HOST;
pr_debug(" --> a_host\n");
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
otg_ctrl |= OTG_A_BUSREQ;
otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ)
& OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
break;
case OTG_STATE_B_WAIT_ACON:
isp->otg.state = OTG_STATE_B_HOST;
@@ -1274,7 +1302,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
return -ENODEV;
if (!host) {
- OTG_IRQ_EN_REG = 0;
+ omap_writew(0, OTG_IRQ_EN);
power_down(isp);
isp->otg.host = 0;
return 0;
@@ -1325,12 +1353,13 @@ static int
isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
{
struct isp1301 *isp = container_of(otg, struct isp1301, otg);
+ u32 l;
if (!otg || isp != the_transceiver)
return -ENODEV;
if (!gadget) {
- OTG_IRQ_EN_REG = 0;
+ omap_writew(0, OTG_IRQ_EN);
if (!isp->otg.default_a)
enable_vbus_draw(isp, 0);
usb_gadget_vbus_disconnect(isp->otg.gadget);
@@ -1351,9 +1380,11 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
isp->otg.gadget = gadget;
// FIXME update its refcount
- OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK
- & ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS))
- | OTG_ID;
+ l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
+ l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS);
+ l |= OTG_ID;
+ omap_writel(l, OTG_CTRL);
+
power_up(isp);
isp->otg.state = OTG_STATE_B_IDLE;
@@ -1405,16 +1436,17 @@ isp1301_start_srp(struct otg_transceiver *dev)
|| isp->otg.state != OTG_STATE_B_IDLE)
return -ENODEV;
- otg_ctrl = OTG_CTRL_REG;
+ otg_ctrl = omap_readl(OTG_CTRL);
if (!(otg_ctrl & OTG_BSESSEND))
return -EINVAL;
otg_ctrl |= OTG_B_BUSREQ;
otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
+ omap_writel(otg_ctrl, OTG_CTRL);
isp->otg.state = OTG_STATE_B_SRP_INIT;
- pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
+ pr_debug("otg: SRP, %s ... %06x\n", state_name(isp),
+ omap_readl(OTG_CTRL));
#ifdef CONFIG_USB_OTG
check_state(isp, __func__);
#endif
@@ -1426,6 +1458,7 @@ isp1301_start_hnp(struct otg_transceiver *dev)
{
#ifdef CONFIG_USB_OTG
struct isp1301 *isp = container_of(dev, struct isp1301, otg);
+ u32 l;
if (!dev || isp != the_transceiver)
return -ENODEV;
@@ -1452,7 +1485,9 @@ isp1301_start_hnp(struct otg_transceiver *dev)
#endif
/* caller must suspend then clear A_BUSREQ */
usb_gadget_vbus_connect(isp->otg.gadget);
- OTG_CTRL_REG |= OTG_A_SETB_HNPEN;
+ l = omap_readl(OTG_CTRL);
+ l |= OTG_A_SETB_HNPEN;
+ omap_writel(l, OTG_CTRL);
break;
case OTG_STATE_A_PERIPHERAL:
@@ -1462,7 +1497,7 @@ isp1301_start_hnp(struct otg_transceiver *dev)
return -EILSEQ;
}
pr_debug("otg: HNP %s, %06x ...\n",
- state_name(isp), OTG_CTRL_REG);
+ state_name(isp), omap_readl(OTG_CTRL));
check_state(isp, __func__);
return 0;
#else
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8e07de23d22..1607536ff5f 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -823,6 +823,13 @@ config BLK_DEV_IDE_RAPIDE
Say Y here if you want to support the Yellowstone RapIDE controller
manufactured for use with Acorn computers.
+config BLK_DEV_IDE_BAST
+ tristate "Simtec BAST / Thorcom VR1000 IDE support"
+ depends on ARM && (ARCH_BAST || MACH_VR1000)
+ help
+ Say Y here if you want to support the onboard IDE channels on the
+ Simtec BAST or the Thorcom VR1000
+
config IDE_H8300
tristate "H8300 IDE support"
depends on H8300
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile
index 5bc26053afa..936e7b0237f 100644
--- a/drivers/ide/arm/Makefile
+++ b/drivers/ide/arm/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
+obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o
obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
ifeq ($(CONFIG_IDE_ARM), m)
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
new file mode 100644
index 00000000000..8e8c28104b4
--- /dev/null
+++ b/drivers/ide/arm/bast-ide.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/map.h>
+#include <asm/arch/bast-map.h>
+#include <asm/arch/bast-irq.h>
+
+#define DRV_NAME "bast-ide"
+
+static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
+{
+ ide_hwif_t *hwif;
+ hw_regs_t hw;
+ int i;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+
+ memset(&hw, 0, sizeof(hw));
+
+ base += BAST_IDE_CS;
+ aux += BAST_IDE_CS;
+
+ for (i = 0; i <= 7; i++) {
+ hw.io_ports_array[i] = (unsigned long)base;
+ base += 0x20;
+ }
+
+ hw.io_ports.ctl_addr = aux + (6 * 0x20);
+ hw.irq = irq;
+ hw.chipset = ide_generic;
+
+ hwif = ide_find_port();
+ if (hwif == NULL)
+ goto out;
+
+ i = hwif->index;
+
+ ide_init_port_data(hwif, i);
+ ide_init_port_hw(hwif, &hw);
+ hwif->port_ops = NULL;
+
+ idx[0] = i;
+
+ ide_device_add(idx, NULL);
+out:
+ return 0;
+}
+
+static int __init bastide_init(void)
+{
+ unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS;
+
+ /* we can treat the VR1000 and the BAST the same */
+
+ if (!(machine_is_bast() || machine_is_vr1000()))
+ return 0;
+
+ printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n");
+
+ if (!request_mem_region(base, 0x400000, DRV_NAME)) {
+ printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+ return -EBUSY;
+ }
+
+ bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0);
+ bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1);
+
+ return 0;
+}
+
+module_init(bastide_init);
+
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver");
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 55ec7f79877..8af88bf0969 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -76,7 +76,7 @@ static int proc_ide_read_mate
ide_hwif_t *hwif = (ide_hwif_t *) data;
int len;
- if (hwif && hwif->mate && hwif->mate->present)
+ if (hwif && hwif->mate)
len = sprintf(page, "%s\n", hwif->mate->name);
else
len = sprintf(page, "(none)\n");
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index eebc72465fc..72c63e5dd63 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -28,6 +28,7 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
/*
* Check that the effect_id is a valid effect and whether the user
@@ -166,8 +167,10 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
if (ret)
goto out;
+ spin_lock_irq(&dev->event_lock);
ff->effects[id] = *effect;
ff->effect_owners[id] = file;
+ spin_unlock_irq(&dev->event_lock);
out:
mutex_unlock(&ff->mutex);
@@ -189,16 +192,22 @@ static int erase_effect(struct input_dev *dev, int effect_id,
if (error)
return error;
+ spin_lock_irq(&dev->event_lock);
ff->playback(dev, effect_id, 0);
+ ff->effect_owners[effect_id] = NULL;
+ spin_unlock_irq(&dev->event_lock);
if (ff->erase) {
error = ff->erase(dev, effect_id);
- if (error)
+ if (error) {
+ spin_lock_irq(&dev->event_lock);
+ ff->effect_owners[effect_id] = file;
+ spin_unlock_irq(&dev->event_lock);
+
return error;
+ }
}
- ff->effect_owners[effect_id] = NULL;
-
return 0;
}
@@ -263,8 +272,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type,
if (type != EV_FF)
return 0;
- mutex_lock(&ff->mutex);
-
switch (code) {
case FF_GAIN:
if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff)
@@ -286,7 +293,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type,
break;
}
- mutex_unlock(&ff->mutex);
return 0;
}
EXPORT_SYMBOL_GPL(input_ff_event);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 835def11419..ab6a61db63c 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -432,6 +432,7 @@ static int crypt_convert(struct crypt_config *cc,
case 0:
atomic_dec(&ctx->pending);
ctx->sector++;
+ cond_resched();
continue;
/* error */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7cf512a34cc..2580ac1b9b0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3897,8 +3897,10 @@ static void autorun_devices(int part)
md_probe(dev, NULL, NULL);
mddev = mddev_find(dev);
- if (!mddev) {
- printk(KERN_ERR
+ if (!mddev || !mddev->gendisk) {
+ if (mddev)
+ mddev_put(mddev);
+ printk(KERN_ERR
"md: cannot allocate memory for md drive.\n");
break;
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1de17da34a9..a71277b640a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2137,6 +2137,8 @@ static int run(mddev_t *mddev)
!test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;
mddev->degraded++;
+ if (disk->rdev)
+ conf->fullsync = 1;
}
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index c37e256b117..54c8ee28fcc 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2898,6 +2898,8 @@ static void handle_stripe5(struct stripe_head *sh)
for (i = conf->raid_disks; i--; ) {
set_bit(R5_Wantwrite, &sh->dev[i].flags);
+ set_bit(R5_LOCKED, &dev->flags);
+ s.locked++;
if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
sh->ops.count++;
}
@@ -2911,6 +2913,7 @@ static void handle_stripe5(struct stripe_head *sh)
conf->raid_disks);
s.locked += handle_write_operations5(sh, 1, 1);
} else if (s.expanded &&
+ s.locked == 0 &&
!test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) {
clear_bit(STRIPE_EXPAND_READY, &sh->state);
atomic_dec(&conf->reshape_stripes);
@@ -4305,7 +4308,9 @@ static int run(mddev_t *mddev)
" disk %d\n", bdevname(rdev->bdev,b),
raid_disk);
working_disks++;
- }
+ } else
+ /* Cannot rely on bitmap to complete recovery */
+ conf->fullsync = 1;
}
/*
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index a3485817e46..8fa91f846d5 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -2201,3 +2201,41 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
[0x25] = KEY_POWER, /* power */
};
EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);
+
+IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
+ [0x20] = KEY_LIST,
+ [0x00] = KEY_POWER,
+ [0x28] = KEY_1,
+ [0x18] = KEY_2,
+ [0x38] = KEY_3,
+ [0x24] = KEY_4,
+ [0x14] = KEY_5,
+ [0x34] = KEY_6,
+ [0x2c] = KEY_7,
+ [0x1c] = KEY_8,
+ [0x3c] = KEY_9,
+ [0x12] = KEY_SUBTITLE,
+ [0x22] = KEY_0,
+ [0x32] = KEY_REWIND,
+ [0x3a] = KEY_SHUFFLE,
+ [0x02] = KEY_PRINT,
+ [0x11] = KEY_CHANNELDOWN,
+ [0x31] = KEY_CHANNELUP,
+ [0x0c] = KEY_ZOOM,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x3e] = KEY_VOLUMEUP,
+ [0x0a] = KEY_MUTE,
+ [0x04] = KEY_AUDIO,
+ [0x26] = KEY_RECORD,
+ [0x06] = KEY_PLAY,
+ [0x36] = KEY_STOP,
+ [0x16] = KEY_PAUSE,
+ [0x2e] = KEY_REWIND,
+ [0x0e] = KEY_FASTFORWARD,
+ [0x30] = KEY_TEXT,
+ [0x21] = KEY_GREEN,
+ [0x01] = KEY_BLUE,
+ [0x08] = KEY_EPG,
+ [0x2a] = KEY_MENU,
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d);
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index f1894fec32b..6fb5b458656 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -649,9 +649,17 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
u8 val;
int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
+ /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
+ * for frequencies above 61.1 MHz. In these cases, the internal RF
+ * tracking filters calibration mechanism is used.
+ *
+ * There is no need to warn the user about this.
+ */
+ if (ret < 0)
+ goto fail;
regs[R_EB14] = val;
-
+fail:
return ret;
}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 89c01fb1f85..93063c6fbbf 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -45,6 +45,21 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force)
TDA18271_MAIN_PLL, force);
}
+static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
+{
+ struct tda18271_priv *priv = fe->tuner_priv;
+ unsigned char *regs = priv->tda18271_regs;
+
+ switch (priv->mode) {
+ case TDA18271_ANALOG:
+ regs[R_MPD] &= ~0x80; /* IF notch = 0 */
+ break;
+ case TDA18271_DIGITAL:
+ regs[R_MPD] |= 0x80; /* IF notch = 1 */
+ break;
+ }
+}
+
static int tda18271_channel_configuration(struct dvb_frontend *fe,
struct tda18271_std_map_item *map,
u32 freq, u32 bw)
@@ -60,25 +75,18 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
regs[R_EP3] &= ~0x1f; /* clear std bits */
regs[R_EP3] |= (map->agc_mode << 3) | map->std;
- /* set rfagc to high speed mode */
- regs[R_EP3] &= ~0x04;
+ if (priv->id == TDA18271HDC2) {
+ /* set rfagc to high speed mode */
+ regs[R_EP3] &= ~0x04;
+ }
/* set cal mode to normal */
regs[R_EP4] &= ~0x03;
- /* update IF output level & IF notch frequency */
+ /* update IF output level */
regs[R_EP4] &= ~0x1c; /* clear if level bits */
regs[R_EP4] |= (map->if_lvl << 2);
- switch (priv->mode) {
- case TDA18271_ANALOG:
- regs[R_MPD] &= ~0x80; /* IF notch = 0 */
- break;
- case TDA18271_DIGITAL:
- regs[R_MPD] |= 0x80; /* IF notch = 1 */
- break;
- }
-
/* update FM_RFn */
regs[R_EP4] &= ~0x80;
regs[R_EP4] |= map->fm_rfn << 7;
@@ -95,6 +103,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
/* disable Power Level Indicator */
regs[R_EP1] |= 0x40;
+ /* make sure thermometer is off */
+ regs[R_TM] &= ~0x10;
+
/* frequency dependent parameters */
tda18271_calc_ir_measure(fe, &freq);
@@ -135,6 +146,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
switch (priv->role) {
case TDA18271_MASTER:
tda18271_calc_main_pll(fe, N);
+ tda18271_set_if_notch(fe);
tda18271_write_regs(fe, R_MPD, 4);
break;
case TDA18271_SLAVE:
@@ -142,6 +154,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
tda18271_write_regs(fe, R_CPD, 4);
regs[R_MPD] = regs[R_CPD] & 0x7f;
+ tda18271_set_if_notch(fe);
tda18271_write_regs(fe, R_MPD, 1);
break;
}
@@ -160,12 +173,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
msleep(20);
- /* set rfagc to normal speed mode */
- if (map->fm_rfn)
- regs[R_EP3] &= ~0x04;
- else
- regs[R_EP3] |= 0x04;
- ret = tda18271_write_regs(fe, R_EP3, 1);
+ if (priv->id == TDA18271HDC2) {
+ /* set rfagc to normal speed mode */
+ if (map->fm_rfn)
+ regs[R_EP3] &= ~0x04;
+ else
+ regs[R_EP3] |= 0x04;
+ ret = tda18271_write_regs(fe, R_EP3, 1);
+ }
fail:
return ret;
}
@@ -507,7 +522,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
/* set cal mode to normal */
regs[R_EP4] &= ~0x03;
- /* update IF output level & IF notch frequency */
+ /* update IF output level */
regs[R_EP4] &= ~0x1c; /* clear if level bits */
ret = tda18271_write_regs(fe, R_EP3, 2);
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index ceae6db901e..7cf4f5bdb2e 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"FM Radio-INPUT1", 0x0208, 0x9002}
};
+static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static void xc5000_TunerReset(struct dvb_frontend *fe);
@@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
static int xc_shutdown(struct xc5000_priv *priv)
{
- return 0;
+ return XC_RESULT_SUCCESS;
/* Fixme: cannot bring tuner back alive once shutdown
* without reloading the driver modules.
* return xc_write_reg(priv, XREG_POWER_DOWN, 0);
@@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe,
return 0;
}
+static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
+{
+ struct xc5000_priv *priv = fe->tuner_priv;
+ int ret;
+ u16 id;
+
+ ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
+ if (ret == XC_RESULT_SUCCESS) {
+ if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
+ ret = XC_RESULT_RESET_FAILURE;
+ else
+ ret = XC_RESULT_SUCCESS;
+ }
+
+ dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
+ ret == XC_RESULT_SUCCESS ? "True" : "False", id);
+ return ret;
+}
+
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
static int xc5000_set_analog_params(struct dvb_frontend *fe,
@@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
- if(priv->fwloaded == 0)
+ if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
xc_load_fw_and_init_tuner(fe);
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
@@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
struct xc5000_priv *priv = fe->tuner_priv;
int ret = 0;
- if (priv->fwloaded == 0) {
+ if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
ret = xc5000_fwupload(fe);
if (ret != XC_RESULT_SUCCESS)
return ret;
- priv->fwloaded = 1;
}
/* Start the tuner self-calibration process */
@@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe)
return -EREMOTEIO;
}
else {
- /* priv->fwloaded = 0; */
return XC_RESULT_SUCCESS;
}
}
@@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
cfg->i2c_address);
printk(KERN_INFO
"xc5000: Firmware has been loaded previously\n");
- priv->fwloaded = 1;
break;
case XC_PRODUCT_ID_FW_NOT_LOADED:
printk(KERN_INFO
@@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
cfg->i2c_address);
printk(KERN_INFO
"xc5000: Firmware has not been loaded previously\n");
- priv->fwloaded = 0;
break;
default:
printk(KERN_ERR
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index ecebfe4745a..a72a9887fe7 100644
--- a/drivers/media/common/tuners/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
@@ -30,7 +30,6 @@ struct xc5000_priv {
u32 bandwidth;
u8 video_standard;
u8 rf_mode;
- u8 fwloaded;
void *devptr;
};
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
index 0a8ac64a4e3..037f7ffb47b 100644
--- a/drivers/media/dvb/dvb-usb/gl861.c
+++ b/drivers/media/dvb/dvb-usb/gl861.c
@@ -47,6 +47,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
return -EINVAL;
}
+ msleep(1); /* avoid I2C errors */
+
return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
value, index, rbuf, rlen, 2000);
}
@@ -92,16 +94,6 @@ static struct i2c_algorithm gl861_i2c_algo = {
};
/* Callbacks for DVB USB */
-static int gl861_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
-{
- *cold = 0;
-
- return 0;
-}
-
static struct zl10353_config gl861_zl10353_config = {
.demod_address = 0x0f,
.no_tuner = 1,
@@ -172,7 +164,6 @@ static struct dvb_usb_device_properties gl861_properties = {
.size_of_priv = 0,
- .identify_state = gl861_identify_state,
.num_adapters = 1,
.adapter = {{
@@ -194,13 +185,15 @@ static struct dvb_usb_device_properties gl861_properties = {
.num_device_descs = 2,
.devices = {
- { "MSI Mega Sky 55801 DVB-T USB2.0",
- { &gl861_table[0], NULL },
- { NULL },
+ {
+ .name = "MSI Mega Sky 55801 DVB-T USB2.0",
+ .cold_ids = { NULL },
+ .warm_ids = { &gl861_table[0], NULL },
},
- { "A-LINK DTU DVB-T USB2.0",
- { &gl861_table[1], NULL },
- { NULL },
+ {
+ .name = "A-LINK DTU DVB-T USB2.0",
+ .cold_ids = { NULL },
+ .warm_ids = { &gl861_table[1], NULL },
},
}
};
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 9e7653bb3b6..118aab1a3e5 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -107,7 +107,7 @@ static struct dvb_usb_device_properties umt_properties = {
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
- .count = 20,
+ .count = MAX_NO_URBS_FOR_DATA_STREAM,
.endpoint = 0x06,
.u = {
.bulk = {
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 084a280c2d7..03900d241a7 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -463,10 +463,13 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct au8522_state *state = fe->demodulator_priv;
+ int ret = -EINVAL;
dprintk("%s(frequency=%d)\n", __func__, p->frequency);
- state->current_frequency = p->frequency;
+ if ((state->current_frequency == p->frequency) &&
+ (state->current_modulation == p->u.vsb.modulation))
+ return 0;
au8522_enable_modulation(fe, p->u.vsb.modulation);
@@ -476,11 +479,16 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- fe->ops.tuner_ops.set_params(fe, p);
+ ret = fe->ops.tuner_ops.set_params(fe, p);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
+ if (ret < 0)
+ return ret;
+
+ state->current_frequency = p->frequency;
+
return 0;
}
@@ -498,6 +506,16 @@ static int au8522_init(struct dvb_frontend *fe)
return 0;
}
+static int au8522_sleep(struct dvb_frontend *fe)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ dprintk("%s()\n", __func__);
+
+ state->current_frequency = 0;
+
+ return 0;
+}
+
static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct au8522_state *state = fe->demodulator_priv;
@@ -509,10 +527,8 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
if (state->current_modulation == VSB_8) {
dprintk("%s() Checking VSB_8\n", __func__);
reg = au8522_readreg(state, 0x4088);
- if (reg & 0x01)
- *status |= FE_HAS_VITERBI;
- if (reg & 0x02)
- *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+ if ((reg & 0x03) == 0x03)
+ *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
} else {
dprintk("%s() Checking QAM\n", __func__);
reg = au8522_readreg(state, 0x4541);
@@ -672,6 +688,7 @@ static struct dvb_frontend_ops au8522_ops = {
},
.init = au8522_init,
+ .sleep = au8522_sleep,
.i2c_gate_ctrl = au8522_i2c_gate_ctrl,
.set_frontend = au8522_set_frontend,
.get_frontend = au8522_get_frontend,
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 17556183e87..35435bef8e7 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -63,6 +63,7 @@ struct stv0299_state {
u32 symbol_rate;
fe_code_rate_t fec_inner;
int errmode;
+ u32 ucblocks;
};
#define STATUS_BER 0
@@ -501,8 +502,10 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_BER) return 0;
- *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+ if (state->errmode != STATUS_BER)
+ return -ENOSYS;
+
+ *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
return 0;
}
@@ -540,8 +543,12 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
- else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+ if (state->errmode != STATUS_UCBLOCKS)
+ return -ENOSYS;
+
+ state->ucblocks += stv0299_readreg(state, 0x1e);
+ state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
+ *ucblocks = state->ucblocks;
return 0;
}
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
index 0727b80bc4d..c6ff5b82ff8 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -116,9 +116,12 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
int ret;
ret = i2c_transfer (state->i2c, msg, 2);
- if (ret != 2)
- printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
- __func__, ret);
+ if (ret != 2) {
+ int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+ printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
+ "(reg == 0x%02x, ret == %i)\n",
+ num, __func__, reg, ret);
+ }
return b1[0];
}
@@ -129,11 +132,12 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
int ret;
ret = i2c_transfer (state->i2c, &msg, 1);
- if (ret != 1)
- printk("DVB: TDA10023(%d): %s, writereg error "
+ if (ret != 1) {
+ int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+ printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
"(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
- state->frontend.dvb->num, __func__, reg, data, ret);
-
+ num, __func__, reg, data, ret);
+ }
return (ret != 1) ? -EREMOTEIO : 0;
}
@@ -464,7 +468,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
int i;
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
+ state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
if (state == NULL) goto error;
/* setup the state */
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 49973846373..a0d63865356 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -1248,11 +1248,14 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
struct tda1004x_state *state;
+ int id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
- if (!state)
+ if (!state) {
+ printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
return NULL;
+ }
/* setup the state */
state->config = config;
@@ -1260,7 +1263,15 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
state->demod_type = TDA1004X_DEMOD_TDA10045;
/* check if the demod is there */
- if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {
+ id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+ if (id < 0) {
+ printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
+ kfree(state);
+ return NULL;
+ }
+
+ if (id != 0x25) {
+ printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
kfree(state);
return NULL;
}
@@ -1307,11 +1318,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
struct tda1004x_state *state;
+ int id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
- if (!state)
+ if (!state) {
+ printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
return NULL;
+ }
/* setup the state */
state->config = config;
@@ -1319,7 +1333,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
state->demod_type = TDA1004X_DEMOD_TDA10046;
/* check if the demod is there */
- if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
+ id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+ if (id < 0) {
+ printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
+ kfree(state);
+ return NULL;
+ }
+ if (id != 0x46) {
+ printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index d4339b1b3b6..07643e01009 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -101,6 +101,7 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_BUDGET_CORE && I2C
+ depends on INPUT # due to IR
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 9d81074b31d..3a3f5279e92 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -427,6 +427,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
if (err) {
printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
__func__, type);
+ av7110->arm_errors++;
return -ETIMEDOUT;
}
msleep(1);
@@ -853,10 +854,8 @@ static osd_raw_window_t bpp2bit[8] = {
static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
{
- int ret = wait_event_interruptible_timeout(av7110->bmpq,
+ int ret = wait_event_timeout(av7110->bmpq,
av7110->bmp_state != BMP_LOADING, 10*HZ);
- if (ret == -ERESTARTSYS)
- return ret;
if (ret == 0) {
printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
ret, av7110->bmp_state);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 3b26fbd3e55..5ccb0aeca8c 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -793,6 +793,14 @@ menuconfig V4L_USB_DRIVERS
if V4L_USB_DRIVERS && USB
+config USB_VIDEO_CLASS
+ tristate "USB Video Class (UVC)"
+ ---help---
+ Support for the USB Video Class (UVC). Currently only video
+ input devices, such as webcams, are supported.
+
+ For more information see: <http://linux-uvc.berlios.de/>
+
source "drivers/media/video/pvrusb2/Kconfig"
source "drivers/media/video/em28xx/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index dff0d6abe91..ecbbfaab24d 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -136,6 +136,8 @@ obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
obj-$(CONFIG_VIDEO_AU0828) += au0828/
+obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index a2a6983444f..898e12395e7 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -77,8 +77,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
/* Make sure we support the board model */
switch (tv.model) {
+ case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
+ case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+ case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break;
default:
printk(KERN_WARNING "%s: warning: "
@@ -175,6 +181,18 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 },
{ USB_DEVICE(0x0fe9, 0xd620),
.driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 },
+ { USB_DEVICE(0x2040, 0x7210),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x7217),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x721b),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x721f),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x7280),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x0fd9, 0x0008),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ },
};
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 5f942690570..9aefdc5ea79 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -10,8 +10,8 @@ config VIDEO_CX18
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_CS5345
- select DVB_S5H1409
- select MEDIA_TUNER_MXL5005S
+ select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 9a26751615c..faca43eb940 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -69,6 +69,58 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
+int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
+{
+ int retval;
+ u32 saved_reg[8] = {0};
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
+ saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
+ saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
+ }
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
+ saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
+ saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
+ }
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
+ saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
+ saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
+ saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
+ saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
+ }
+
+ retval = cx18_av_write(cx, addr, value);
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
+ cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
+ cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]);
+ }
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]);
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
+ }
+
+ if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
+ cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]);
+ cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]);
+ cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]);
+ cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
+ }
+
+ return retval;
+}
+
+int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
+ u8 or_value, int no_acfg_mask)
+{
+ return cx18_av_write_no_acfg(cx, addr,
+ (cx18_av_read(cx, addr) & and_mask) |
+ or_value, no_acfg_mask);
+}
+
/* ----------------------------------------------------------------------- */
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
@@ -170,13 +222,15 @@ static void input_change(struct cx18 *cx)
/* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
if (std & V4L2_STD_SECAM)
- cx18_av_write(cx, 0x402, 0);
+ cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL);
else {
- cx18_av_write(cx, 0x402, 0x04);
+ cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
}
- cx18_av_and_or(cx, 0x401, ~0x60, 0);
- cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
+ cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
+ CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
+ cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
+ CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
if (std & V4L2_STD_525_60) {
if (std == V4L2_STD_NTSC_M_JP) {
@@ -228,7 +282,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
if ((vid_input & ~0xff0) ||
luma < CX18_AV_SVIDEO_LUMA1 ||
- luma > CX18_AV_SVIDEO_LUMA4 ||
+ luma > CX18_AV_SVIDEO_LUMA8 ||
chroma < CX18_AV_SVIDEO_CHROMA4 ||
chroma > CX18_AV_SVIDEO_CHROMA8) {
CX18_ERR("0x%04x is not a valid video input!\n",
@@ -262,7 +316,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
cx18_av_write(cx, 0x103, reg);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
- cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
+ cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02,
+ CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
@@ -318,12 +373,12 @@ static int set_v4lstd(struct cx18 *cx)
This happens for example with the Yuan MPC622. */
if (fmt >= 4 && fmt < 8) {
/* Set format to NTSC-M */
- cx18_av_and_or(cx, 0x400, ~0xf, 1);
+ cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE);
/* Turn off LCOMB */
cx18_av_and_or(cx, 0x47b, ~6, 0);
}
- cx18_av_and_or(cx, 0x400, ~0xf, fmt);
- cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
+ cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE);
+ cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL);
cx18_av_vbi_setup(cx);
input_change(cx);
return 0;
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index 786901d72e9..c172823ce1d 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -37,12 +37,16 @@ enum cx18_av_video_input {
CX18_AV_COMPOSITE7,
CX18_AV_COMPOSITE8,
- /* S-Video inputs consist of one luma input (In1-In4) ORed with one
+ /* S-Video inputs consist of one luma input (In1-In8) ORed with one
chroma input (In5-In8) */
CX18_AV_SVIDEO_LUMA1 = 0x10,
CX18_AV_SVIDEO_LUMA2 = 0x20,
CX18_AV_SVIDEO_LUMA3 = 0x30,
CX18_AV_SVIDEO_LUMA4 = 0x40,
+ CX18_AV_SVIDEO_LUMA5 = 0x50,
+ CX18_AV_SVIDEO_LUMA6 = 0x60,
+ CX18_AV_SVIDEO_LUMA7 = 0x70,
+ CX18_AV_SVIDEO_LUMA8 = 0x80,
CX18_AV_SVIDEO_CHROMA4 = 0x400,
CX18_AV_SVIDEO_CHROMA5 = 0x500,
CX18_AV_SVIDEO_CHROMA6 = 0x600,
@@ -291,14 +295,24 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
+/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/
+#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */
+#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */
+#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */
+#define CXADEC_NO_ACFG_ALL 0x07
+
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
+int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value,
+ int no_acfg_mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
+int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value,
+ int no_acfg_mask);
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index baccd079243..c26e0ef5b07 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -23,6 +23,7 @@
#include "cx18-driver.h"
#include "cx18-cards.h"
+#include "cx18-av-core.h"
#include "cx18-i2c.h"
#include <media/cs5345.h>
@@ -54,22 +55,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
+ { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
+ { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
+ CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
- CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
.ddr = {
/* ESMT M13S128324A-5B memory */
.chip_config = 0x003,
@@ -81,6 +82,11 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
+ .gpio_i2c_slave_reset = {
+ .active_lo_mask = 0x3001,
+ .msecs_asserted = 10,
+ .msecs_recovery = 40,
+ },
.i2c = &cx18_i2c_std,
};
@@ -94,22 +100,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
- { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
- { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
+ { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
+ { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
+ CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
- CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
.ddr = {
/* Samsung K4D263238G-VC33 memory */
.chip_config = 0x003,
@@ -121,6 +127,11 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
+ .gpio_i2c_slave_reset = {
+ .active_lo_mask = 0x3001,
+ .msecs_asserted = 10,
+ .msecs_recovery = 40,
+ },
.i2c = &cx18_i2c_std,
};
@@ -141,19 +152,19 @@ static const struct cx18_card cx18_card_h900 = {
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
.video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 },
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
- CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
+ CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO8, 0 },
+ CX18_AV_AUDIO8, 0 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX23418_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL, 0 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL, 0 },
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
},
@@ -183,23 +194,26 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
static const struct cx18_card cx18_card_mpc718 = {
.type = CX18_CARD_YUAN_MPC718,
.name = "Yuan MPC718",
- .comment = "Not yet supported!\n",
- .v4l2_capabilities = 0,
+ .comment = "Some Composite and S-Video inputs are currently working.\n",
+ .v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
.video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
+ { CX18_CARD_INPUT_SVIDEO1, 1,
+ CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
+ { CX18_CARD_INPUT_SVIDEO2, 2,
+ CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
+ { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO8, 0 },
- { CX18_CARD_INPUT_LINE_IN1,
- CX23418_AUDIO_SERIAL, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 },
},
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX23418_AUDIO_SERIAL, 0 },
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
.tuners = {
/* XC3028 tuner */
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index bccb67f0db1..dc2dd945d4c 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -36,36 +36,6 @@
#define CX18_CARD_INPUT_COMPOSITE2 5
#define CX18_CARD_INPUT_COMPOSITE3 6
-enum cx34180_video_input {
- /* Composite video inputs In1-In8 */
- CX23418_COMPOSITE1 = 1,
- CX23418_COMPOSITE2,
- CX23418_COMPOSITE3,
- CX23418_COMPOSITE4,
- CX23418_COMPOSITE5,
- CX23418_COMPOSITE6,
- CX23418_COMPOSITE7,
- CX23418_COMPOSITE8,
-
- /* S-Video inputs consist of one luma input (In1-In4) ORed with one
- chroma input (In5-In8) */
- CX23418_SVIDEO_LUMA1 = 0x10,
- CX23418_SVIDEO_LUMA2 = 0x20,
- CX23418_SVIDEO_LUMA3 = 0x30,
- CX23418_SVIDEO_LUMA4 = 0x40,
- CX23418_SVIDEO_CHROMA4 = 0x400,
- CX23418_SVIDEO_CHROMA5 = 0x500,
- CX23418_SVIDEO_CHROMA6 = 0x600,
- CX23418_SVIDEO_CHROMA7 = 0x700,
- CX23418_SVIDEO_CHROMA8 = 0x800,
-
- /* S-Video aliases for common luma/chroma combinations */
- CX23418_SVIDEO1 = 0x510,
- CX23418_SVIDEO2 = 0x620,
- CX23418_SVIDEO3 = 0x730,
- CX23418_SVIDEO4 = 0x840,
-};
-
/* audio inputs */
#define CX18_CARD_INPUT_AUD_TUNER 1
#define CX18_CARD_INPUT_LINE_IN1 2
@@ -75,16 +45,6 @@ enum cx34180_video_input {
#define CX18_CARD_MAX_AUDIO_INPUTS 3
#define CX18_CARD_MAX_TUNERS 2
-enum cx23418_audio_input {
- /* Audio inputs: serial or In4-In8 */
- CX23418_AUDIO_SERIAL,
- CX23418_AUDIO4 = 4,
- CX23418_AUDIO5,
- CX23418_AUDIO6,
- CX23418_AUDIO7,
- CX23418_AUDIO8,
-};
-
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE)
@@ -118,6 +78,13 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
u32 initial_value;
};
+struct cx18_gpio_i2c_slave_reset {
+ u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
+ u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
+ int msecs_asserted; /* time period reset must remain asserted */
+ int msecs_recovery; /* time after deassert for chips to be ready */
+};
+
struct cx18_card_tuner {
v4l2_std_id std; /* standard for which the tuner is suitable */
int tuner; /* tuner ID (from tuner.h) */
@@ -154,7 +121,8 @@ struct cx18_card {
/* GPIO card-specific settings */
u8 xceive_pin; /* XCeive tuner GPIO reset pin */
- struct cx18_gpio_init gpio_init;
+ struct cx18_gpio_init gpio_init;
+ struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
struct cx18_card_tuner_i2c *i2c;
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index c9744173f96..cae38985b13 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -69,11 +69,21 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux;
struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
struct cx18 *cx = stream->cx;
- int ret = -EINVAL;
+ int ret;
u32 v;
CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
feed->pid, feed->index);
+
+ mutex_lock(&cx->serialize_lock);
+ ret = cx18_init_on_first_open(cx);
+ mutex_unlock(&cx->serialize_lock);
+ if (ret) {
+ CX18_ERR("Failed to initialize firmware starting DVB feed\n");
+ return ret;
+ }
+ ret = -EINVAL;
+
switch (cx->card->type) {
case CX18_CARD_HVR_1600_ESMT:
case CX18_CARD_HVR_1600_SAMSUNG:
@@ -101,6 +111,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
if (stream->dvb.feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n");
ret = cx18_start_v4l2_encode_stream(stream);
+ if (ret < 0) {
+ CX18_DEBUG_INFO(
+ "Failed to start Transport DMA\n");
+ stream->dvb.feeding--;
+ }
} else
ret = 0;
mutex_unlock(&stream->dvb.feedlock);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index ceb63653c92..b302833f6f9 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -53,10 +53,34 @@ static void gpio_write(struct cx18 *cx)
write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
CX18_REG_GPIO_OUT1);
write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
- write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
+ write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
CX18_REG_GPIO_OUT2);
}
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+{
+ const struct cx18_gpio_i2c_slave_reset *p;
+
+ p = &cx->card->gpio_i2c_slave_reset;
+
+ if ((p->active_lo_mask | p->active_hi_mask) == 0)
+ return;
+
+ /* Assuming that the masks are a subset of the bits in gpio_dir */
+
+ /* Assert */
+ cx->gpio_val =
+ (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
+ gpio_write(cx);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+
+ /* Deassert */
+ cx->gpio_val =
+ (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
+ gpio_write(cx);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+}
+
void cx18_gpio_init(struct cx18 *cx)
{
cx->gpio_dir = cx->card->gpio_init.direction;
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index 41bac8856b5..525c328f748 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -21,4 +21,5 @@
*/
void cx18_gpio_init(struct cx18 *cx);
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 1d6c51a7531..680bc4e35b7 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -405,6 +405,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
+ cx18_reset_i2c_slaves_gpio(cx);
+
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);
}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 607efdcd22f..1da6f134888 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -433,7 +433,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
int chroma = vid_input & 0xf00;
if ((vid_input & ~0xff0) ||
- luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
+ luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
v4l_err(client, "0x%04x is not a valid video input!\n",
vid_input);
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index e976fc6bef7..80c8883e54b 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -332,6 +332,12 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
+ if (!chip) {
+ printk(KERN_ERR "BUG: cx88 can't find device struct."
+ " Can't proceed with open\n");
+ return -ENODEV;
+ }
+
err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
if (err < 0)
goto _error;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 92b2a6db4fd..3c006103c1e 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -268,6 +268,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("opening device and trying to acquire exclusive lock\n");
+ if (!dev) {
+ printk(KERN_ERR "BUG: em28xx can't find device struct."
+ " Can't proceed with open\n");
+ return -ENODEV;
+ }
+
/* Sets volume, mute, etc */
dev->mute = 0;
@@ -415,6 +421,12 @@ static int em28xx_audio_init(struct em28xx *dev)
static int devnr;
int ret, err;
+ if (dev->has_audio_class) {
+ /* This device does not support the extension (in this case
+ the device is expecting the snd-usb-audio module */
+ return 0;
+ }
+
printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "
"non standard usbaudio\n");
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
@@ -458,6 +470,12 @@ static int em28xx_audio_fini(struct em28xx *dev)
if (dev == NULL)
return 0;
+ if (dev->has_audio_class) {
+ /* This device does not support the extension (in this case
+ the device is expecting the snd-usb-audio module */
+ return 0;
+ }
+
if (dev->adev) {
snd_card_free(dev->adev->sndcard);
kfree(dev->adev);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3e4f3c7e92e..8cbda43727c 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -157,6 +157,7 @@ struct em28xx_board em28xx_boards[] = {
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_XC2028,
.mts_firmware = 1,
+ .has_dvb = 1,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -524,6 +525,9 @@ void em28xx_pre_card_setup(struct em28xx *dev)
rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
if (rc > 0) {
switch (rc) {
+ case CHIP_ID_EM2860:
+ em28xx_info("chip ID is em2860\n");
+ break;
case CHIP_ID_EM2883:
em28xx_info("chip ID is em2882/em2883\n");
dev->wait_after_write = 0;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 8cf4983f003..0b2333ee07f 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -382,6 +382,11 @@ static int dvb_init(struct em28xx *dev)
int result = 0;
struct em28xx_dvb *dvb;
+ if (!dev->has_dvb) {
+ /* This device does not support the extension */
+ return 0;
+ }
+
dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
if (dvb == NULL) {
@@ -444,6 +449,11 @@ out_free:
static int dvb_fini(struct em28xx *dev)
{
+ if (!dev->has_dvb) {
+ /* This device does not support the extension */
+ return 0;
+ }
+
if (dev->dvb) {
unregister_dvb(dev->dvb);
dev->dvb = NULL;
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 9058bed0795..fac1ab23f62 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -84,5 +84,6 @@
/* FIXME: Need to be populated with the other chip ID's */
enum em28xx_chip_id {
+ CHIP_ID_EM2860 = 34,
CHIP_ID_EM2883 = 36,
};
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index fb163ecd921..285bc62bbe4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1848,32 +1848,28 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock);
int em28xx_register_extension(struct em28xx_ops *ops)
{
- struct em28xx *h, *dev = NULL;
-
- list_for_each_entry(h, &em28xx_devlist, devlist)
- dev = h;
+ struct em28xx *dev = NULL;
mutex_lock(&em28xx_extension_devlist_lock);
list_add_tail(&ops->next, &em28xx_extension_devlist);
- if (dev)
- ops->init(dev);
-
+ list_for_each_entry(dev, &em28xx_devlist, devlist) {
+ if (dev)
+ ops->init(dev);
+ }
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
mutex_unlock(&em28xx_extension_devlist_lock);
-
return 0;
}
EXPORT_SYMBOL(em28xx_register_extension);
void em28xx_unregister_extension(struct em28xx_ops *ops)
{
- struct em28xx *h, *dev = NULL;
-
- list_for_each_entry(h, &em28xx_devlist, devlist)
- dev = h;
+ struct em28xx *dev = NULL;
- if (dev)
- ops->fini(dev);
+ list_for_each_entry(dev, &em28xx_devlist, devlist) {
+ if (dev)
+ ops->fini(dev);
+ }
mutex_lock(&em28xx_extension_devlist_lock);
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 7cc8e9b19fb..5ec5bb9a94d 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1019,12 +1019,12 @@ static int pxa_camera_probe(struct platform_device *pdev)
struct pxa_camera_dev *pcdev;
struct resource *res;
void __iomem *base;
- unsigned int irq;
+ int irq;
int err = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- if (!res || !irq) {
+ if (!res || irq < 0) {
err = -ENODEV;
goto exit;
}
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index ba3082422a0..f118de6e367 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -613,9 +613,15 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_card_saa7134_pcm_t *pcm;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev = saa7134->dev;
+ struct saa7134_dev *dev;
int amux, err;
+ if (!saa7134) {
+ printk(KERN_ERR "BUG: saa7134 can't find device struct."
+ " Can't proceed with open\n");
+ return -ENODEV;
+ }
+ dev = saa7134->dev;
mutex_lock(&dev->dmasound.lock);
dev->dmasound.read_count = 0;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index b111903aa32..2618cfa592e 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4114,11 +4114,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /*
- TODO:
.mpeg = SAA7134_MPEG_DVB,
- */
-
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -4157,7 +4153,7 @@ struct saa7134_board saa7134_boards[] = {
} },
.radio = {
.name = name_radio,
- .amux = LINE1,
+ .amux = TV,
},
},
[SAA7134_BOARD_AVERMEDIA_M115] = {
@@ -4167,6 +4163,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -5351,22 +5348,21 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
{
switch (command) {
case XC2028_TUNER_RESET:
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
- mdelay(250);
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0);
- mdelay(250);
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
- mdelay(250);
- saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
- saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
- saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
- saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
- saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
- 0x0001e000, 0x0001e000);
- return 0;
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
+ switch (dev->board) {
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ saa7134_set_gpio(dev, 23, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 23, 1);
+ break;
+ case SAA7134_BOARD_AVERMEDIA_A16D:
+ saa7134_set_gpio(dev, 21, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 21, 1);
+ break;
+ }
+ return 0;
}
return -EINVAL;
}
@@ -5553,9 +5549,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS:
- case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
case SAA7134_BOARD_AVERMEDIA_M115:
- case SAA7134_BOARD_AVERMEDIA_A16D:
/* power-down tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0);
@@ -5565,6 +5559,18 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
msleep(10);
break;
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ saa7134_set_gpio(dev, 23, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 23, 1);
+ break;
+ case SAA7134_BOARD_AVERMEDIA_A16D:
+ saa7134_set_gpio(dev, 21, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 21, 1);
+ msleep(1);
+ dev->has_remote = SAA7134_REMOTE_GPIO;
+ break;
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
/* power-down tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004);
@@ -5615,7 +5621,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
printk("%s: %s: hybrid analog/dvb card\n"
- "%s: Sorry, only the analog inputs are supported for now.\n",
+ "%s: Sorry, only analog s-video and composite input "
+ "are supported for now.\n",
dev->name, card(dev).name, dev->name);
break;
}
@@ -5675,6 +5682,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_AVERMEDIA_A16D:
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
ctl.demod = XC3028_FE_ZARLINK456;
break;
default:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 469f93aac00..341b101b035 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -153,12 +153,12 @@ static int mt352_aver777_init(struct dvb_frontend* fe)
return 0;
}
-static int mt352_aver_a16d_init(struct dvb_frontend *fe)
+static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe)
{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
+ static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
+ static u8 reset [] = { RESET, 0x80 };
+ static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+ static u8 agc_cfg [] = { AGC_TARGET, 0xe };
static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
mt352_write(fe, clock_config, sizeof(clock_config));
@@ -167,12 +167,9 @@ static int mt352_aver_a16d_init(struct dvb_frontend *fe)
mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
mt352_write(fe, agc_cfg, sizeof(agc_cfg));
mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
return 0;
}
-
-
static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
@@ -215,14 +212,10 @@ static struct mt352_config avermedia_777 = {
.demod_init = mt352_aver777_init,
};
-static struct mt352_config avermedia_16d = {
- .demod_address = 0xf,
- .demod_init = mt352_aver_a16d_init,
-};
-
-static struct mt352_config avermedia_e506r_mt352_dev = {
+static struct mt352_config avermedia_xc3028_mt352_dev = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
+ .demod_init = mt352_avermedia_xc3028_init,
};
/* ==================================================================
@@ -975,9 +968,10 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
- dprintk("avertv A16D dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d,
- &dev->i2c_adap);
+ dprintk("AverMedia A16D dvb setup\n");
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &avermedia_xc3028_mt352_dev,
+ &dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134:
@@ -1091,7 +1085,8 @@ static int dvb_init(struct saa7134_dev *dev)
ads_tech_duo_config.tuner_address);
goto dettach_frontend;
}
- }
+ } else
+ wprintk("failed to attach tda10046\n");
break;
case SAA7134_BOARD_TEVION_DVBT_220RF:
if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
@@ -1260,11 +1255,14 @@ static int dvb_init(struct saa7134_dev *dev)
goto dettach_frontend;
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ dprintk("AverMedia E506R dvb setup\n");
+ saa7134_set_gpio(dev, 25, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 25, 1);
dev->dvb.frontend = dvb_attach(mt352_attach,
- &avermedia_e506r_mt352_dev,
- &dev->i2c_adap);
+ &avermedia_xc3028_mt352_dev,
+ &dev->i2c_adap);
attach_xc3028 = 1;
- break;
case SAA7134_BOARD_MD7134_BRIDGE_2:
dev->dvb.frontend = dvb_attach(tda10086_attach,
&sd1878_4m, &dev->i2c_adap);
@@ -1338,7 +1336,8 @@ static int dvb_init(struct saa7134_dev *dev)
return ret;
dettach_frontend:
- dvb_frontend_detach(dev->dvb.frontend);
+ if (dev->dvb.frontend)
+ dvb_frontend_detach(dev->dvb.frontend);
dev->dvb.frontend = NULL;
return -1;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 81431ee4184..3ae71a34082 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -110,9 +110,10 @@ static int ts_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
+ mutex_lock(&dev->empress_tsq.vb_lock);
+
videobuf_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
- dev->empress_users--;
/* stop the encoder */
ts_reset_encoder(dev);
@@ -121,6 +122,10 @@ static int ts_release(struct inode *inode, struct file *file)
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
+ dev->empress_users--;
+
+ mutex_unlock(&dev->empress_tsq.vb_lock);
+
return 0;
}
@@ -218,8 +223,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv,
static int empress_g_fmt_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
@@ -232,8 +236,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv,
static int empress_s_fmt_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
@@ -247,8 +250,7 @@ static int empress_s_fmt_cap(struct file *file, void *priv,
static int empress_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_reqbufs(&dev->empress_tsq, p);
}
@@ -256,24 +258,21 @@ static int empress_reqbufs(struct file *file, void *priv,
static int empress_querybuf(struct file *file, void *priv,
struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_querybuf(&dev->empress_tsq, b);
}
static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_qbuf(&dev->empress_tsq, b);
}
static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_dqbuf(&dev->empress_tsq, b,
file->f_flags & O_NONBLOCK);
@@ -282,8 +281,7 @@ static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
static int empress_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_streamon(&dev->empress_tsq);
}
@@ -291,8 +289,7 @@ static int empress_streamon(struct file *file, void *priv,
static int empress_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
return videobuf_streamoff(&dev->empress_tsq);
}
@@ -300,8 +297,7 @@ static int empress_streamoff(struct file *file, void *priv,
static int empress_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
/* count == 0 is abused in saa6752hs.c, so that special
case is handled here explicitly. */
@@ -320,8 +316,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
static int empress_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
+ struct saa7134_dev *dev = file->private_data;
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 919632b10aa..76e6501d238 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -323,6 +323,15 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
break;
+ case SAA7134_BOARD_AVERMEDIA_A16D:
+ ir_codes = ir_codes_avermedia_a16d;
+ mask_keycode = 0x02F200;
+ mask_keydown = 0x000400;
+ polling = 50; /* ms */
+ /* Without this we won't receive key up events */
+ saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
+ saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
+ break;
case SAA7134_BOARD_KWORLD_TERMINATOR:
ir_codes = ir_codes_pixelview;
mask_keycode = 0x00001f;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a1b92446c8b..d015bfe0095 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -763,15 +763,6 @@ static struct device_driver ic_drv = {
.owner = THIS_MODULE,
};
-/*
- * Image capture host - this is a host device, not a bus device, so,
- * no bus reference, no probing.
- */
-static struct class soc_camera_host_class = {
- .owner = THIS_MODULE,
- .name = "camera_host",
-};
-
static void dummy_release(struct device *dev)
{
}
@@ -801,7 +792,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
/* Number might be equal to the platform device ID */
sprintf(ici->dev.bus_id, "camera_host%d", ici->nr);
- ici->dev.class = &soc_camera_host_class;
mutex_lock(&list_lock);
list_for_each_entry(ix, &hosts, list) {
@@ -1003,14 +993,9 @@ static int __init soc_camera_init(void)
ret = driver_register(&ic_drv);
if (ret)
goto edrvr;
- ret = class_register(&soc_camera_host_class);
- if (ret)
- goto eclr;
return 0;
-eclr:
- driver_unregister(&ic_drv);
edrvr:
bus_unregister(&soc_camera_bus_type);
return ret;
@@ -1018,7 +1003,6 @@ edrvr:
static void __exit soc_camera_exit(void)
{
- class_unregister(&soc_camera_host_class);
driver_unregister(&ic_drv);
bus_unregister(&soc_camera_bus_type);
}
diff --git a/drivers/media/video/uvc/Makefile b/drivers/media/video/uvc/Makefile
new file mode 100644
index 00000000000..968c1994eda
--- /dev/null
+++ b/drivers/media/video/uvc/Makefile
@@ -0,0 +1,3 @@
+uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
+ uvc_status.o uvc_isight.o
+obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
new file mode 100644
index 00000000000..f0ee46d1554
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -0,0 +1,1256 @@
+/*
+ * uvc_ctrl.c -- USB Video Class driver - Controls
+ *
+ * Copyright (C) 2005-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+
+#include "uvcvideo.h"
+
+#define UVC_CTRL_NDATA 2
+#define UVC_CTRL_DATA_CURRENT 0
+#define UVC_CTRL_DATA_BACKUP 1
+
+/* ------------------------------------------------------------------------
+ * Control, formats, ...
+ */
+
+static struct uvc_control_info uvc_ctrls[] = {
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_BRIGHTNESS_CONTROL,
+ .index = 0,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_CONTRAST_CONTROL,
+ .index = 1,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_HUE_CONTROL,
+ .index = 2,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_SATURATION_CONTROL,
+ .index = 3,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_SHARPNESS_CONTROL,
+ .index = 4,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_GAMMA_CONTROL,
+ .index = 5,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_BACKLIGHT_COMPENSATION_CONTROL,
+ .index = 8,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_GAIN_CONTROL,
+ .index = 9,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_POWER_LINE_FREQUENCY_CONTROL,
+ .index = 10,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_HUE_AUTO_CONTROL,
+ .index = 11,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_AE_MODE_CONTROL,
+ .index = 1,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_AE_PRIORITY_CONTROL,
+ .index = 2,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
+ .index = 3,
+ .size = 4,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_FOCUS_ABSOLUTE_CONTROL,
+ .index = 5,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+ },
+ {
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_FOCUS_AUTO_CONTROL,
+ .index = 17,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+ .index = 12,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+ .index = 6,
+ .size = 2,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+ .index = 13,
+ .size = 1,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+ | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+ },
+ {
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL,
+ .index = 7,
+ .size = 4,
+ .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+ | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+ },
+};
+
+static struct uvc_menu_info power_line_frequency_controls[] = {
+ { 0, "Disabled" },
+ { 1, "50 Hz" },
+ { 2, "60 Hz" },
+};
+
+static struct uvc_menu_info exposure_auto_controls[] = {
+ { 1, "Manual Mode" },
+ { 2, "Auto Mode" },
+ { 4, "Shutter Priority Mode" },
+ { 8, "Aperture Priority Mode" },
+};
+
+static struct uvc_control_mapping uvc_ctrl_mappings[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .name = "Brightness",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_BRIGHTNESS_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
+ },
+ {
+ .id = V4L2_CID_CONTRAST,
+ .name = "Contrast",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_CONTRAST_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_HUE,
+ .name = "Hue",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_HUE_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
+ },
+ {
+ .id = V4L2_CID_SATURATION,
+ .name = "Saturation",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_SATURATION_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .name = "Sharpness",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_SHARPNESS_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_GAMMA,
+ .name = "Gamma",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_GAMMA_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_BACKLIGHT_COMPENSATION,
+ .name = "Backlight Compensation",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_BACKLIGHT_COMPENSATION_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_GAIN,
+ .name = "Gain",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_GAIN_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .name = "Power Line Frequency",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_POWER_LINE_FREQUENCY_CONTROL,
+ .size = 2,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_MENU,
+ .data_type = UVC_CTRL_DATA_TYPE_ENUM,
+ .menu_info = power_line_frequency_controls,
+ .menu_count = ARRAY_SIZE(power_line_frequency_controls),
+ },
+ {
+ .id = V4L2_CID_HUE_AUTO,
+ .name = "Hue, Auto",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_HUE_AUTO_CONTROL,
+ .size = 1,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
+ .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
+ },
+ {
+ .id = V4L2_CID_EXPOSURE_AUTO,
+ .name = "Exposure, Auto",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_AE_MODE_CONTROL,
+ .size = 4,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_MENU,
+ .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
+ .menu_info = exposure_auto_controls,
+ .menu_count = ARRAY_SIZE(exposure_auto_controls),
+ },
+ {
+ .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
+ .name = "Exposure, Auto Priority",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_AE_PRIORITY_CONTROL,
+ .size = 1,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
+ .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
+ },
+ {
+ .id = V4L2_CID_EXPOSURE_ABSOLUTE,
+ .name = "Exposure (Absolute)",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
+ .size = 32,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .name = "White Balance Temperature, Auto",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+ .size = 1,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
+ .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
+ },
+ {
+ .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+ .name = "White Balance Temperature",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .name = "White Balance Component, Auto",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+ .size = 1,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
+ .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .name = "White Balance Blue Component",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .name = "White Balance Red Component",
+ .entity = UVC_GUID_UVC_PROCESSING,
+ .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL,
+ .size = 16,
+ .offset = 16,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
+ },
+ {
+ .id = V4L2_CID_FOCUS_ABSOLUTE,
+ .name = "Focus (absolute)",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_FOCUS_ABSOLUTE_CONTROL,
+ .size = 16,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_FOCUS_AUTO,
+ .name = "Focus, Auto",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = CT_FOCUS_AUTO_CONTROL,
+ .size = 1,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
+ .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
+ },
+};
+
+/* ------------------------------------------------------------------------
+ * Utility functions
+ */
+
+static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
+{
+ return ctrl->data + id * ctrl->info->size;
+}
+
+static inline int uvc_get_bit(const __u8 *data, int bit)
+{
+ return (data[bit >> 3] >> (bit & 7)) & 1;
+}
+
+/* Extract the bit string specified by mapping->offset and mapping->size
+ * from the little-endian data stored at 'data' and return the result as
+ * a signed 32bit integer. Sign extension will be performed if the mapping
+ * references a signed data type.
+ */
+static __s32 uvc_get_le_value(const __u8 *data,
+ struct uvc_control_mapping *mapping)
+{
+ int bits = mapping->size;
+ int offset = mapping->offset;
+ __s32 value = 0;
+ __u8 mask;
+
+ data += offset / 8;
+ offset &= 7;
+ mask = ((1LL << bits) - 1) << offset;
+
+ for (; bits > 0; data++) {
+ __u8 byte = *data & mask;
+ value |= offset > 0 ? (byte >> offset) : (byte << (-offset));
+ bits -= 8 - (offset > 0 ? offset : 0);
+ offset -= 8;
+ mask = (1 << bits) - 1;
+ }
+
+ /* Sign-extend the value if needed */
+ if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
+ value |= -(value & (1 << (mapping->size - 1)));
+
+ return value;
+}
+
+/* Set the bit string specified by mapping->offset and mapping->size
+ * in the little-endian data stored at 'data' to the value 'value'.
+ */
+static void uvc_set_le_value(__s32 value, __u8 *data,
+ struct uvc_control_mapping *mapping)
+{
+ int bits = mapping->size;
+ int offset = mapping->offset;
+ __u8 mask;
+
+ data += offset / 8;
+ offset &= 7;
+
+ for (; bits > 0; data++) {
+ mask = ((1LL << bits) - 1) << offset;
+ *data = (*data & ~mask) | ((value << offset) & mask);
+ value >>= offset ? offset : 8;
+ bits -= 8 - offset;
+ offset = 0;
+ }
+}
+
+/* ------------------------------------------------------------------------
+ * Terminal and unit management
+ */
+
+static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
+static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
+static const __u8 uvc_media_transport_input_guid[16] =
+ UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
+
+static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16])
+{
+ switch (UVC_ENTITY_TYPE(entity)) {
+ case ITT_CAMERA:
+ return memcmp(uvc_camera_guid, guid, 16) == 0;
+
+ case ITT_MEDIA_TRANSPORT_INPUT:
+ return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
+
+ case VC_PROCESSING_UNIT:
+ return memcmp(uvc_processing_guid, guid, 16) == 0;
+
+ case VC_EXTENSION_UNIT:
+ return memcmp(entity->extension.guidExtensionCode,
+ guid, 16) == 0;
+
+ default:
+ return 0;
+ }
+}
+
+/* ------------------------------------------------------------------------
+ * UVC Controls
+ */
+
+static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
+ struct uvc_control_mapping **mapping, struct uvc_control **control,
+ int next)
+{
+ struct uvc_control *ctrl;
+ struct uvc_control_mapping *map;
+ unsigned int i;
+
+ if (entity == NULL)
+ return;
+
+ for (i = 0; i < entity->ncontrols; ++i) {
+ ctrl = &entity->controls[i];
+ if (ctrl->info == NULL)
+ continue;
+
+ list_for_each_entry(map, &ctrl->info->mappings, list) {
+ if ((map->id == v4l2_id) && !next) {
+ *control = ctrl;
+ *mapping = map;
+ return;
+ }
+
+ if ((*mapping == NULL || (*mapping)->id > map->id) &&
+ (map->id > v4l2_id) && next) {
+ *control = ctrl;
+ *mapping = map;
+ }
+ }
+ }
+}
+
+struct uvc_control *uvc_find_control(struct uvc_video_device *video,
+ __u32 v4l2_id, struct uvc_control_mapping **mapping)
+{
+ struct uvc_control *ctrl = NULL;
+ struct uvc_entity *entity;
+ int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;
+
+ *mapping = NULL;
+
+ /* Mask the query flags. */
+ v4l2_id &= V4L2_CTRL_ID_MASK;
+
+ /* Find the control. */
+ __uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next);
+ if (ctrl && !next)
+ return ctrl;
+
+ list_for_each_entry(entity, &video->iterms, chain) {
+ __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
+ if (ctrl && !next)
+ return ctrl;
+ }
+
+ list_for_each_entry(entity, &video->extensions, chain) {
+ __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
+ if (ctrl && !next)
+ return ctrl;
+ }
+
+ if (ctrl == NULL && !next)
+ uvc_trace(UVC_TRACE_CONTROL, "Control 0x%08x not found.\n",
+ v4l2_id);
+
+ return ctrl;
+}
+
+int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
+ struct v4l2_queryctrl *v4l2_ctrl)
+{
+ struct uvc_control *ctrl;
+ struct uvc_control_mapping *mapping;
+ struct uvc_menu_info *menu;
+ unsigned int i;
+ __u8 data[8];
+ int ret;
+
+ ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
+ if (ctrl == NULL)
+ return -EINVAL;
+
+ v4l2_ctrl->id = mapping->id;
+ v4l2_ctrl->type = mapping->v4l2_type;
+ strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+ v4l2_ctrl->flags = 0;
+
+ if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
+ if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
+ video->dev->intfnum, ctrl->info->selector,
+ &data, ctrl->info->size)) < 0)
+ return ret;
+ v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
+ }
+
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+ v4l2_ctrl->minimum = 0;
+ v4l2_ctrl->maximum = mapping->menu_count - 1;
+ v4l2_ctrl->step = 1;
+
+ menu = mapping->menu_info;
+ for (i = 0; i < mapping->menu_count; ++i, ++menu) {
+ if (menu->value == v4l2_ctrl->default_value) {
+ v4l2_ctrl->default_value = i;
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
+ if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
+ video->dev->intfnum, ctrl->info->selector,
+ &data, ctrl->info->size)) < 0)
+ return ret;
+ v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
+ }
+ if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
+ if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
+ video->dev->intfnum, ctrl->info->selector,
+ &data, ctrl->info->size)) < 0)
+ return ret;
+ v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
+ }
+ if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
+ if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
+ video->dev->intfnum, ctrl->info->selector,
+ &data, ctrl->info->size)) < 0)
+ return ret;
+ v4l2_ctrl->step = uvc_get_le_value(data, mapping);
+ }
+
+ return 0;
+}
+
+
+/* --------------------------------------------------------------------------
+ * Control transactions
+ *
+ * To make extended set operations as atomic as the hardware allows, controls
+ * are handled using begin/commit/rollback operations.
+ *
+ * At the beginning of a set request, uvc_ctrl_begin should be called to
+ * initialize the request. This function acquires the control lock.
+ *
+ * When setting a control, the new value is stored in the control data field
+ * at position UVC_CTRL_DATA_CURRENT. The control is then marked as dirty for
+ * later processing. If the UVC and V4L2 control sizes differ, the current
+ * value is loaded from the hardware before storing the new value in the data
+ * field.
+ *
+ * After processing all controls in the transaction, uvc_ctrl_commit or
+ * uvc_ctrl_rollback must be called to apply the pending changes to the
+ * hardware or revert them. When applying changes, all controls marked as
+ * dirty will be modified in the UVC device, and the dirty flag will be
+ * cleared. When reverting controls, the control data field
+ * UVC_CTRL_DATA_CURRENT is reverted to its previous value
+ * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
+ * control lock.
+ */
+int uvc_ctrl_begin(struct uvc_video_device *video)
+{
+ return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0;
+}
+
+static int uvc_ctrl_commit_entity(struct uvc_device *dev,
+ struct uvc_entity *entity, int rollback)
+{
+ struct uvc_control *ctrl;
+ unsigned int i;
+ int ret;
+
+ if (entity == NULL)
+ return 0;
+
+ for (i = 0; i < entity->ncontrols; ++i) {
+ ctrl = &entity->controls[i];
+ if (ctrl->info == NULL || !ctrl->dirty)
+ continue;
+
+ if (!rollback)
+ ret = uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id,
+ dev->intfnum, ctrl->info->selector,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ ctrl->info->size);
+ else
+ ret = 0;
+
+ if (rollback || ret < 0)
+ memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
+ ctrl->info->size);
+
+ if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
+ ctrl->loaded = 0;
+
+ ctrl->dirty = 0;
+
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback)
+{
+ struct uvc_entity *entity;
+ int ret = 0;
+
+ /* Find the control. */
+ ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback);
+ if (ret < 0)
+ goto done;
+
+ list_for_each_entry(entity, &video->iterms, chain) {
+ ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
+ if (ret < 0)
+ goto done;
+ }
+
+ list_for_each_entry(entity, &video->extensions, chain) {
+ ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
+ if (ret < 0)
+ goto done;
+ }
+
+done:
+ mutex_unlock(&video->ctrl_mutex);
+ return ret;
+}
+
+int uvc_ctrl_get(struct uvc_video_device *video,
+ struct v4l2_ext_control *xctrl)
+{
+ struct uvc_control *ctrl;
+ struct uvc_control_mapping *mapping;
+ struct uvc_menu_info *menu;
+ unsigned int i;
+ int ret;
+
+ ctrl = uvc_find_control(video, xctrl->id, &mapping);
+ if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
+ return -EINVAL;
+
+ if (!ctrl->loaded) {
+ ret = uvc_query_ctrl(video->dev, GET_CUR, ctrl->entity->id,
+ video->dev->intfnum, ctrl->info->selector,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ ctrl->info->size);
+ if (ret < 0)
+ return ret;
+
+ if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
+ ctrl->loaded = 1;
+ }
+
+ xctrl->value = uvc_get_le_value(
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping);
+
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+ menu = mapping->menu_info;
+ for (i = 0; i < mapping->menu_count; ++i, ++menu) {
+ if (menu->value == xctrl->value) {
+ xctrl->value = i;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int uvc_ctrl_set(struct uvc_video_device *video,
+ struct v4l2_ext_control *xctrl)
+{
+ struct uvc_control *ctrl;
+ struct uvc_control_mapping *mapping;
+ s32 value = xctrl->value;
+ int ret;
+
+ ctrl = uvc_find_control(video, xctrl->id, &mapping);
+ if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
+ return -EINVAL;
+
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+ if (value < 0 || value >= mapping->menu_count)
+ return -EINVAL;
+ value = mapping->menu_info[value].value;
+ }
+
+ if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) {
+ if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) {
+ memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ 0, ctrl->info->size);
+ } else {
+ ret = uvc_query_ctrl(video->dev, GET_CUR,
+ ctrl->entity->id, video->dev->intfnum,
+ ctrl->info->selector,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ ctrl->info->size);
+ if (ret < 0)
+ return ret;
+ }
+
+ if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
+ ctrl->loaded = 1;
+ }
+
+ if (!ctrl->dirty) {
+ memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ ctrl->info->size);
+ }
+
+ uvc_set_le_value(value,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping);
+
+ ctrl->dirty = 1;
+ ctrl->modified = 1;
+ return 0;
+}
+
+/* --------------------------------------------------------------------------
+ * Dynamic controls
+ */
+
+int uvc_xu_ctrl_query(struct uvc_video_device *video,
+ struct uvc_xu_control *xctrl, int set)
+{
+ struct uvc_entity *entity;
+ struct uvc_control *ctrl = NULL;
+ unsigned int i, found = 0;
+ __u8 *data;
+ int ret;
+
+ /* Find the extension unit. */
+ list_for_each_entry(entity, &video->extensions, chain) {
+ if (entity->id == xctrl->unit)
+ break;
+ }
+
+ if (entity->id != xctrl->unit) {
+ uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
+ xctrl->unit);
+ return -EINVAL;
+ }
+
+ /* Find the control. */
+ for (i = 0; i < entity->ncontrols; ++i) {
+ ctrl = &entity->controls[i];
+ if (ctrl->info == NULL)
+ continue;
+
+ if (ctrl->info->selector == xctrl->selector) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ uvc_trace(UVC_TRACE_CONTROL,
+ "Control " UVC_GUID_FORMAT "/%u not found.\n",
+ UVC_GUID_ARGS(entity->extension.guidExtensionCode),
+ xctrl->selector);
+ return -EINVAL;
+ }
+
+ /* Validate control data size. */
+ if (ctrl->info->size != xctrl->size)
+ return -EINVAL;
+
+ if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) ||
+ (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&video->ctrl_mutex))
+ return -ERESTARTSYS;
+
+ memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ xctrl->size);
+ data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
+
+ if (set && copy_from_user(data, xctrl->data, xctrl->size)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit,
+ video->dev->intfnum, xctrl->selector, data,
+ xctrl->size);
+ if (ret < 0)
+ goto out;
+
+ if (!set && copy_to_user(xctrl->data, data, xctrl->size)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+out:
+ if (ret)
+ memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
+ xctrl->size);
+
+ mutex_unlock(&video->ctrl_mutex);
+ return ret;
+}
+
+/* --------------------------------------------------------------------------
+ * Suspend/resume
+ */
+
+/*
+ * Restore control values after resume, skipping controls that haven't been
+ * changed.
+ *
+ * TODO
+ * - Don't restore modified controls that are back to their default value.
+ * - Handle restore order (Auto-Exposure Mode should be restored before
+ * Exposure Time).
+ */
+int uvc_ctrl_resume_device(struct uvc_device *dev)
+{
+ struct uvc_control *ctrl;
+ struct uvc_entity *entity;
+ unsigned int i;
+ int ret;
+
+ /* Walk the entities list and restore controls when possible. */
+ list_for_each_entry(entity, &dev->entities, list) {
+
+ for (i = 0; i < entity->ncontrols; ++i) {
+ ctrl = &entity->controls[i];
+
+ if (ctrl->info == NULL || !ctrl->modified ||
+ (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0)
+ continue;
+
+ printk(KERN_INFO "restoring control " UVC_GUID_FORMAT
+ "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity),
+ ctrl->info->index, ctrl->info->selector);
+ ctrl->dirty = 1;
+ }
+
+ ret = uvc_ctrl_commit_entity(dev, entity, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------------
+ * Control and mapping handling
+ */
+
+static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
+ struct uvc_control_info *info)
+{
+ struct uvc_entity *entity;
+ struct uvc_control *ctrl = NULL;
+ int ret, found = 0;
+ unsigned int i;
+
+ list_for_each_entry(entity, &dev->entities, list) {
+ if (!uvc_entity_match_guid(entity, info->entity))
+ continue;
+
+ for (i = 0; i < entity->ncontrols; ++i) {
+ ctrl = &entity->controls[i];
+ if (ctrl->index == info->index) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found)
+ return;
+
+ if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) {
+ /* Check if the device control information and length match
+ * the user supplied information.
+ */
+ __u32 flags;
+ __le16 size;
+ __u8 inf;
+
+ if ((ret = uvc_query_ctrl(dev, GET_LEN, ctrl->entity->id,
+ dev->intfnum, info->selector, (__u8 *)&size, 2)) < 0) {
+ uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on "
+ "control " UVC_GUID_FORMAT "/%u (%d).\n",
+ UVC_GUID_ARGS(info->entity), info->selector,
+ ret);
+ return;
+ }
+
+ if (info->size != le16_to_cpu(size)) {
+ uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT
+ "/%u size doesn't match user supplied "
+ "value.\n", UVC_GUID_ARGS(info->entity),
+ info->selector);
+ return;
+ }
+
+ if ((ret = uvc_query_ctrl(dev, GET_INFO, ctrl->entity->id,
+ dev->intfnum, info->selector, &inf, 1)) < 0) {
+ uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on "
+ "control " UVC_GUID_FORMAT "/%u (%d).\n",
+ UVC_GUID_ARGS(info->entity), info->selector,
+ ret);
+ return;
+ }
+
+ flags = info->flags;
+ if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
+ ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
+ uvc_trace(UVC_TRACE_CONTROL, "Control "
+ UVC_GUID_FORMAT "/%u flags don't match "
+ "supported operations.\n",
+ UVC_GUID_ARGS(info->entity), info->selector);
+ return;
+ }
+ }
+
+ ctrl->info = info;
+ ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL);
+ uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u "
+ "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity),
+ ctrl->info->selector, dev->udev->devpath, entity->id);
+}
+
+/*
+ * Add an item to the UVC control information list, and instantiate a control
+ * structure for each device that supports the control.
+ */
+int uvc_ctrl_add_info(struct uvc_control_info *info)
+{
+ struct uvc_control_info *ctrl;
+ struct uvc_device *dev;
+ int ret = 0;
+
+ /* Find matching controls by walking the devices, entities and
+ * controls list.
+ */
+ mutex_lock(&uvc_driver.ctrl_mutex);
+
+ /* First check if the list contains a control matching the new one.
+ * Bail out if it does.
+ */
+ list_for_each_entry(ctrl, &uvc_driver.controls, list) {
+ if (memcmp(ctrl->entity, info->entity, 16))
+ continue;
+
+ if (ctrl->selector == info->selector) {
+ uvc_trace(UVC_TRACE_CONTROL, "Control "
+ UVC_GUID_FORMAT "/%u is already defined.\n",
+ UVC_GUID_ARGS(info->entity), info->selector);
+ ret = -EEXIST;
+ goto end;
+ }
+ if (ctrl->index == info->index) {
+ uvc_trace(UVC_TRACE_CONTROL, "Control "
+ UVC_GUID_FORMAT "/%u would overwrite index "
+ "%d.\n", UVC_GUID_ARGS(info->entity),
+ info->selector, info->index);
+ ret = -EEXIST;
+ goto end;
+ }
+ }
+
+ list_for_each_entry(dev, &uvc_driver.devices, list)
+ uvc_ctrl_add_ctrl(dev, info);
+
+ INIT_LIST_HEAD(&info->mappings);
+ list_add_tail(&info->list, &uvc_driver.controls);
+end:
+ mutex_unlock(&uvc_driver.ctrl_mutex);
+ return ret;
+}
+
+int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
+{
+ struct uvc_control_info *info;
+ struct uvc_control_mapping *map;
+ int ret = -EINVAL;
+
+ if (mapping->id & ~V4L2_CTRL_ID_MASK) {
+ uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with "
+ "invalid control id 0x%08x\n", mapping->name,
+ mapping->id);
+ return -EINVAL;
+ }
+
+ mutex_lock(&uvc_driver.ctrl_mutex);
+ list_for_each_entry(info, &uvc_driver.controls, list) {
+ if (memcmp(info->entity, mapping->entity, 16) ||
+ info->selector != mapping->selector)
+ continue;
+
+ if (info->size * 8 < mapping->size + mapping->offset) {
+ uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would "
+ "overflow control " UVC_GUID_FORMAT "/%u\n",
+ mapping->name, UVC_GUID_ARGS(info->entity),
+ info->selector);
+ ret = -EOVERFLOW;
+ goto end;
+ }
+
+ /* Check if the list contains a mapping matching the new one.
+ * Bail out if it does.
+ */
+ list_for_each_entry(map, &info->mappings, list) {
+ if (map->id == mapping->id) {
+ uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' is "
+ "already defined.\n", mapping->name);
+ ret = -EEXIST;
+ goto end;
+ }
+ }
+
+ mapping->ctrl = info;
+ list_add_tail(&mapping->list, &info->mappings);
+ uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control "
+ UVC_GUID_FORMAT "/%u.\n", mapping->name,
+ UVC_GUID_ARGS(info->entity), info->selector);
+
+ ret = 0;
+ break;
+ }
+end:
+ mutex_unlock(&uvc_driver.ctrl_mutex);
+ return ret;
+}
+
+/*
+ * Initialize device controls.
+ */
+int uvc_ctrl_init_device(struct uvc_device *dev)
+{
+ struct uvc_control_info *info;
+ struct uvc_control *ctrl;
+ struct uvc_entity *entity;
+ unsigned int i;
+
+ /* Walk the entities list and instantiate controls */
+ list_for_each_entry(entity, &dev->entities, list) {
+ unsigned int bControlSize = 0, ncontrols = 0;
+ __u8 *bmControls = NULL;
+
+ if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) {
+ bmControls = entity->extension.bmControls;
+ bControlSize = entity->extension.bControlSize;
+ } else if (UVC_ENTITY_TYPE(entity) == VC_PROCESSING_UNIT) {
+ bmControls = entity->processing.bmControls;
+ bControlSize = entity->processing.bControlSize;
+ } else if (UVC_ENTITY_TYPE(entity) == ITT_CAMERA) {
+ bmControls = entity->camera.bmControls;
+ bControlSize = entity->camera.bControlSize;
+ }
+
+ for (i = 0; i < bControlSize; ++i)
+ ncontrols += hweight8(bmControls[i]);
+
+ if (ncontrols == 0)
+ continue;
+
+ entity->controls = kzalloc(ncontrols*sizeof *ctrl, GFP_KERNEL);
+ if (entity->controls == NULL)
+ return -ENOMEM;
+
+ entity->ncontrols = ncontrols;
+
+ ctrl = entity->controls;
+ for (i = 0; i < bControlSize * 8; ++i) {
+ if (uvc_get_bit(bmControls, i) == 0)
+ continue;
+
+ ctrl->entity = entity;
+ ctrl->index = i;
+ ctrl++;
+ }
+ }
+
+ /* Walk the controls info list and associate them with the device
+ * controls, then add the device to the global device list. This has
+ * to be done while holding the controls lock, to make sure
+ * uvc_ctrl_add_info() will not get called in-between.
+ */
+ mutex_lock(&uvc_driver.ctrl_mutex);
+ list_for_each_entry(info, &uvc_driver.controls, list)
+ uvc_ctrl_add_ctrl(dev, info);
+
+ list_add_tail(&dev->list, &uvc_driver.devices);
+ mutex_unlock(&uvc_driver.ctrl_mutex);
+
+ return 0;
+}
+
+/*
+ * Cleanup device controls.
+ */
+void uvc_ctrl_cleanup_device(struct uvc_device *dev)
+{
+ struct uvc_entity *entity;
+ unsigned int i;
+
+ /* Remove the device from the global devices list */
+ mutex_lock(&uvc_driver.ctrl_mutex);
+ if (dev->list.next != NULL)
+ list_del(&dev->list);
+ mutex_unlock(&uvc_driver.ctrl_mutex);
+
+ list_for_each_entry(entity, &dev->entities, list) {
+ for (i = 0; i < entity->ncontrols; ++i)
+ kfree(entity->controls[i].data);
+
+ kfree(entity->controls);
+ }
+}
+
+void uvc_ctrl_init(void)
+{
+ struct uvc_control_info *ctrl = uvc_ctrls;
+ struct uvc_control_info *cend = ctrl + ARRAY_SIZE(uvc_ctrls);
+ struct uvc_control_mapping *mapping = uvc_ctrl_mappings;
+ struct uvc_control_mapping *mend =
+ mapping + ARRAY_SIZE(uvc_ctrl_mappings);
+
+ for (; ctrl < cend; ++ctrl)
+ uvc_ctrl_add_info(ctrl);
+
+ for (; mapping < mend; ++mapping)
+ uvc_ctrl_add_mapping(mapping);
+}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
new file mode 100644
index 00000000000..60ced589f89
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -0,0 +1,1955 @@
+/*
+ * uvc_driver.c -- USB Video Class driver
+ *
+ * Copyright (C) 2005-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * 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 driver aims to support video input devices compliant with the 'USB
+ * Video Class' specification.
+ *
+ * The driver doesn't support the deprecated v4l1 interface. It implements the
+ * mmap capture method only, and doesn't do any image format conversion in
+ * software. If your user-space application doesn't support YUYV or MJPEG, fix
+ * it :-). Please note that the MJPEG data have been stripped from their
+ * Huffman tables (DHT marker), you will need to add it back if your JPEG
+ * codec can't handle MJPEG data.
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+
+#include <media/v4l2-common.h>
+
+#include "uvcvideo.h"
+
+#define DRIVER_AUTHOR "Laurent Pinchart <laurent.pinchart@skynet.be>"
+#define DRIVER_DESC "USB Video Class driver"
+#ifndef DRIVER_VERSION
+#define DRIVER_VERSION "v0.1.0"
+#endif
+
+static unsigned int uvc_quirks_param;
+unsigned int uvc_trace_param;
+
+/* ------------------------------------------------------------------------
+ * Control, formats, ...
+ */
+
+static struct uvc_format_desc uvc_fmts[] = {
+ {
+ .name = "YUV 4:2:2 (YUYV)",
+ .guid = UVC_GUID_FORMAT_YUY2,
+ .fcc = V4L2_PIX_FMT_YUYV,
+ },
+ {
+ .name = "YUV 4:2:0 (NV12)",
+ .guid = UVC_GUID_FORMAT_NV12,
+ .fcc = V4L2_PIX_FMT_NV12,
+ },
+ {
+ .name = "MJPEG",
+ .guid = UVC_GUID_FORMAT_MJPEG,
+ .fcc = V4L2_PIX_FMT_MJPEG,
+ },
+ {
+ .name = "YVU 4:2:0 (YV12)",
+ .guid = UVC_GUID_FORMAT_YV12,
+ .fcc = V4L2_PIX_FMT_YVU420,
+ },
+ {
+ .name = "YUV 4:2:0 (I420)",
+ .guid = UVC_GUID_FORMAT_I420,
+ .fcc = V4L2_PIX_FMT_YUV420,
+ },
+ {
+ .name = "YUV 4:2:2 (UYVY)",
+ .guid = UVC_GUID_FORMAT_UYVY,
+ .fcc = V4L2_PIX_FMT_UYVY,
+ },
+ {
+ .name = "Greyscale",
+ .guid = UVC_GUID_FORMAT_Y800,
+ .fcc = V4L2_PIX_FMT_GREY,
+ },
+ {
+ .name = "RGB Bayer",
+ .guid = UVC_GUID_FORMAT_BY8,
+ .fcc = V4L2_PIX_FMT_SBGGR8,
+ },
+};
+
+/* ------------------------------------------------------------------------
+ * Utility functions
+ */
+
+struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
+ __u8 epaddr)
+{
+ struct usb_host_endpoint *ep;
+ unsigned int i;
+
+ for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
+ ep = &alts->endpoint[i];
+ if (ep->desc.bEndpointAddress == epaddr)
+ return ep;
+ }
+
+ return NULL;
+}
+
+static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16])
+{
+ unsigned int len = ARRAY_SIZE(uvc_fmts);
+ unsigned int i;
+
+ for (i = 0; i < len; ++i) {
+ if (memcmp(guid, uvc_fmts[i].guid, 16) == 0)
+ return &uvc_fmts[i];
+ }
+
+ return NULL;
+}
+
+static __u32 uvc_colorspace(const __u8 primaries)
+{
+ static const __u8 colorprimaries[] = {
+ 0,
+ V4L2_COLORSPACE_SRGB,
+ V4L2_COLORSPACE_470_SYSTEM_M,
+ V4L2_COLORSPACE_470_SYSTEM_BG,
+ V4L2_COLORSPACE_SMPTE170M,
+ V4L2_COLORSPACE_SMPTE240M,
+ };
+
+ if (primaries < ARRAY_SIZE(colorprimaries))
+ return colorprimaries[primaries];
+
+ return 0;
+}
+
+/* Simplify a fraction using a simple continued fraction decomposition. The
+ * idea here is to convert fractions such as 333333/10000000 to 1/30 using
+ * 32 bit arithmetic only. The algorithm is not perfect and relies upon two
+ * arbitrary parameters to remove non-significative terms from the simple
+ * continued fraction decomposition. Using 8 and 333 for n_terms and threshold
+ * respectively seems to give nice results.
+ */
+void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
+ unsigned int n_terms, unsigned int threshold)
+{
+ uint32_t *an;
+ uint32_t x, y, r;
+ unsigned int i, n;
+
+ an = kmalloc(n_terms * sizeof *an, GFP_KERNEL);
+ if (an == NULL)
+ return;
+
+ /* Convert the fraction to a simple continued fraction. See
+ * http://mathforum.org/dr.math/faq/faq.fractions.html
+ * Stop if the current term is bigger than or equal to the given
+ * threshold.
+ */
+ x = *numerator;
+ y = *denominator;
+
+ for (n = 0; n < n_terms && y != 0; ++n) {
+ an[n] = x / y;
+ if (an[n] >= threshold) {
+ if (n < 2)
+ n++;
+ break;
+ }
+
+ r = x - an[n] * y;
+ x = y;
+ y = r;
+ }
+
+ /* Expand the simple continued fraction back to an integer fraction. */
+ x = 0;
+ y = 1;
+
+ for (i = n; i > 0; --i) {
+ r = y;
+ y = an[i-1] * y + x;
+ x = r;
+ }
+
+ *numerator = y;
+ *denominator = x;
+ kfree(an);
+}
+
+/* Convert a fraction to a frame interval in 100ns multiples. The idea here is
+ * to compute numerator / denominator * 10000000 using 32 bit fixed point
+ * arithmetic only.
+ */
+uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator)
+{
+ uint32_t multiplier;
+
+ /* Saturate the result if the operation would overflow. */
+ if (denominator == 0 ||
+ numerator/denominator >= ((uint32_t)-1)/10000000)
+ return (uint32_t)-1;
+
+ /* Divide both the denominator and the multiplier by two until
+ * numerator * multiplier doesn't overflow. If anyone knows a better
+ * algorithm please let me know.
+ */
+ multiplier = 10000000;
+ while (numerator > ((uint32_t)-1)/multiplier) {
+ multiplier /= 2;
+ denominator /= 2;
+ }
+
+ return denominator ? numerator * multiplier / denominator : 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Terminal and unit management
+ */
+
+static struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
+{
+ struct uvc_entity *entity;
+
+ list_for_each_entry(entity, &dev->entities, list) {
+ if (entity->id == id)
+ return entity;
+ }
+
+ return NULL;
+}
+
+static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
+ int id, struct uvc_entity *entity)
+{
+ unsigned int i;
+
+ if (entity == NULL)
+ entity = list_entry(&dev->entities, struct uvc_entity, list);
+
+ list_for_each_entry_continue(entity, &dev->entities, list) {
+ switch (UVC_ENTITY_TYPE(entity)) {
+ case TT_STREAMING:
+ if (entity->output.bSourceID == id)
+ return entity;
+ break;
+
+ case VC_PROCESSING_UNIT:
+ if (entity->processing.bSourceID == id)
+ return entity;
+ break;
+
+ case VC_SELECTOR_UNIT:
+ for (i = 0; i < entity->selector.bNrInPins; ++i)
+ if (entity->selector.baSourceID[i] == id)
+ return entity;
+ break;
+
+ case VC_EXTENSION_UNIT:
+ for (i = 0; i < entity->extension.bNrInPins; ++i)
+ if (entity->extension.baSourceID[i] == id)
+ return entity;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+/* ------------------------------------------------------------------------
+ * Descriptors handling
+ */
+
+static int uvc_parse_format(struct uvc_device *dev,
+ struct uvc_streaming *streaming, struct uvc_format *format,
+ __u32 **intervals, unsigned char *buffer, int buflen)
+{
+ struct usb_interface *intf = streaming->intf;
+ struct usb_host_interface *alts = intf->cur_altsetting;
+ struct uvc_format_desc *fmtdesc;
+ struct uvc_frame *frame;
+ const unsigned char *start = buffer;
+ unsigned int interval;
+ unsigned int i, n;
+ __u8 ftype;
+
+ format->type = buffer[2];
+ format->index = buffer[3];
+
+ switch (buffer[2]) {
+ case VS_FORMAT_UNCOMPRESSED:
+ case VS_FORMAT_FRAME_BASED:
+ if (buflen < 27) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d FORMAT error\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ /* Find the format descriptor from its GUID. */
+ fmtdesc = uvc_format_by_guid(&buffer[5]);
+
+ if (fmtdesc != NULL) {
+ strncpy(format->name, fmtdesc->name,
+ sizeof format->name);
+ format->fcc = fmtdesc->fcc;
+ } else {
+ uvc_printk(KERN_INFO, "Unknown video format "
+ UVC_GUID_FORMAT "\n",
+ UVC_GUID_ARGS(&buffer[5]));
+ snprintf(format->name, sizeof format->name,
+ UVC_GUID_FORMAT, UVC_GUID_ARGS(&buffer[5]));
+ format->fcc = 0;
+ }
+
+ format->bpp = buffer[21];
+ if (buffer[2] == VS_FORMAT_UNCOMPRESSED) {
+ ftype = VS_FRAME_UNCOMPRESSED;
+ } else {
+ ftype = VS_FRAME_FRAME_BASED;
+ if (buffer[27])
+ format->flags = UVC_FMT_FLAG_COMPRESSED;
+ }
+ break;
+
+ case VS_FORMAT_MJPEG:
+ if (buflen < 11) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d FORMAT error\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ strncpy(format->name, "MJPEG", sizeof format->name);
+ format->fcc = V4L2_PIX_FMT_MJPEG;
+ format->flags = UVC_FMT_FLAG_COMPRESSED;
+ format->bpp = 0;
+ ftype = VS_FRAME_MJPEG;
+ break;
+
+ case VS_FORMAT_DV:
+ if (buflen < 9) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d FORMAT error\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ switch (buffer[8] & 0x7f) {
+ case 0:
+ strncpy(format->name, "SD-DV", sizeof format->name);
+ break;
+ case 1:
+ strncpy(format->name, "SDL-DV", sizeof format->name);
+ break;
+ case 2:
+ strncpy(format->name, "HD-DV", sizeof format->name);
+ break;
+ default:
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d: unknown DV format %u\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber, buffer[8]);
+ return -EINVAL;
+ }
+
+ strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+ sizeof format->name);
+
+ format->fcc = V4L2_PIX_FMT_DV;
+ format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
+ format->bpp = 0;
+ ftype = 0;
+
+ /* Create a dummy frame descriptor. */
+ frame = &format->frame[0];
+ memset(&format->frame[0], 0, sizeof format->frame[0]);
+ frame->bFrameIntervalType = 1;
+ frame->dwDefaultFrameInterval = 1;
+ frame->dwFrameInterval = *intervals;
+ *(*intervals)++ = 1;
+ format->nframes = 1;
+ break;
+
+ case VS_FORMAT_MPEG2TS:
+ case VS_FORMAT_STREAM_BASED:
+ /* Not supported yet. */
+ default:
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d unsupported format %u\n",
+ dev->udev->devnum, alts->desc.bInterfaceNumber,
+ buffer[2]);
+ return -EINVAL;
+ }
+
+ uvc_trace(UVC_TRACE_DESCR, "Found format %s.\n", format->name);
+
+ buflen -= buffer[0];
+ buffer += buffer[0];
+
+ /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
+ * based formats have frame descriptors.
+ */
+ while (buflen > 2 && buffer[2] == ftype) {
+ frame = &format->frame[format->nframes];
+
+ if (ftype != VS_FRAME_FRAME_BASED)
+ n = buflen > 25 ? buffer[25] : 0;
+ else
+ n = buflen > 21 ? buffer[21] : 0;
+
+ n = n ? n : 3;
+
+ if (buflen < 26 + 4*n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d FRAME error\n", dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ frame->bFrameIndex = buffer[3];
+ frame->bmCapabilities = buffer[4];
+ frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]);
+ frame->wHeight = le16_to_cpup((__le16 *)&buffer[7]);
+ frame->dwMinBitRate = le32_to_cpup((__le32 *)&buffer[9]);
+ frame->dwMaxBitRate = le32_to_cpup((__le32 *)&buffer[13]);
+ if (ftype != VS_FRAME_FRAME_BASED) {
+ frame->dwMaxVideoFrameBufferSize =
+ le32_to_cpup((__le32 *)&buffer[17]);
+ frame->dwDefaultFrameInterval =
+ le32_to_cpup((__le32 *)&buffer[21]);
+ frame->bFrameIntervalType = buffer[25];
+ } else {
+ frame->dwMaxVideoFrameBufferSize = 0;
+ frame->dwDefaultFrameInterval =
+ le32_to_cpup((__le32 *)&buffer[17]);
+ frame->bFrameIntervalType = buffer[21];
+ }
+ frame->dwFrameInterval = *intervals;
+
+ /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
+ * completely. Observed behaviours range from setting the
+ * value to 1.1x the actual frame size of hardwiring the
+ * 16 low bits to 0. This results in a higher than necessary
+ * memory usage as well as a wrong image size information. For
+ * uncompressed formats this can be fixed by computing the
+ * value from the frame size.
+ */
+ if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
+ frame->dwMaxVideoFrameBufferSize = format->bpp
+ * frame->wWidth * frame->wHeight / 8;
+
+ /* Some bogus devices report dwMinFrameInterval equal to
+ * dwMaxFrameInterval and have dwFrameIntervalStep set to
+ * zero. Setting all null intervals to 1 fixes the problem and
+ * some other divisions by zero which could happen.
+ */
+ for (i = 0; i < n; ++i) {
+ interval = le32_to_cpup((__le32 *)&buffer[26+4*i]);
+ *(*intervals)++ = interval ? interval : 1;
+ }
+
+ /* Make sure that the default frame interval stays between
+ * the boundaries.
+ */
+ n -= frame->bFrameIntervalType ? 1 : 2;
+ frame->dwDefaultFrameInterval =
+ min(frame->dwFrameInterval[n],
+ max(frame->dwFrameInterval[0],
+ frame->dwDefaultFrameInterval));
+
+ uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n",
+ frame->wWidth, frame->wHeight,
+ 10000000/frame->dwDefaultFrameInterval,
+ (100000000/frame->dwDefaultFrameInterval)%10);
+
+ format->nframes++;
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ if (buflen > 2 && buffer[2] == VS_STILL_IMAGE_FRAME) {
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ if (buflen > 2 && buffer[2] == VS_COLORFORMAT) {
+ if (buflen < 6) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d COLORFORMAT error\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ format->colorspace = uvc_colorspace(buffer[3]);
+
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ return buffer - start;
+}
+
+static int uvc_parse_streaming(struct uvc_device *dev,
+ struct usb_interface *intf)
+{
+ struct uvc_streaming *streaming = NULL;
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+ struct usb_host_interface *alts = &intf->altsetting[0];
+ unsigned char *_buffer, *buffer = alts->extra;
+ int _buflen, buflen = alts->extralen;
+ unsigned int nformats = 0, nframes = 0, nintervals = 0;
+ unsigned int size, i, n, p;
+ __u32 *interval;
+ __u16 psize;
+ int ret = -EINVAL;
+
+ if (intf->cur_altsetting->desc.bInterfaceSubClass
+ != SC_VIDEOSTREAMING) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a "
+ "video streaming interface\n", dev->udev->devnum,
+ intf->altsetting[0].desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d interface %d is already "
+ "claimed\n", dev->udev->devnum,
+ intf->altsetting[0].desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ streaming = kzalloc(sizeof *streaming, GFP_KERNEL);
+ if (streaming == NULL) {
+ usb_driver_release_interface(&uvc_driver.driver, intf);
+ return -EINVAL;
+ }
+
+ mutex_init(&streaming->mutex);
+ streaming->intf = usb_get_intf(intf);
+ streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
+
+ /* The Pico iMage webcam has its class-specific interface descriptors
+ * after the endpoint descriptors.
+ */
+ if (buflen == 0) {
+ for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
+ struct usb_host_endpoint *ep = &alts->endpoint[i];
+
+ if (ep->extralen == 0)
+ continue;
+
+ if (ep->extralen > 2 &&
+ ep->extra[1] == USB_DT_CS_INTERFACE) {
+ uvc_trace(UVC_TRACE_DESCR, "trying extra data "
+ "from endpoint %u.\n", i);
+ buffer = alts->endpoint[i].extra;
+ buflen = alts->endpoint[i].extralen;
+ break;
+ }
+ }
+ }
+
+ /* Skip the standard interface descriptors. */
+ while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) {
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ if (buflen <= 2) {
+ uvc_trace(UVC_TRACE_DESCR, "no class-specific streaming "
+ "interface descriptors found.\n");
+ goto error;
+ }
+
+ /* Parse the header descriptor. */
+ if (buffer[2] == VS_OUTPUT_HEADER) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+ "%d OUTPUT HEADER descriptor is not supported.\n",
+ dev->udev->devnum, alts->desc.bInterfaceNumber);
+ goto error;
+ } else if (buffer[2] == VS_INPUT_HEADER) {
+ p = buflen >= 5 ? buffer[3] : 0;
+ n = buflen >= 12 ? buffer[12] : 0;
+
+ if (buflen < 13 + p*n || buffer[2] != VS_INPUT_HEADER) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
+ "interface %d INPUT HEADER descriptor is "
+ "invalid.\n", dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ goto error;
+ }
+
+ streaming->header.bNumFormats = p;
+ streaming->header.bEndpointAddress = buffer[6];
+ streaming->header.bmInfo = buffer[7];
+ streaming->header.bTerminalLink = buffer[8];
+ streaming->header.bStillCaptureMethod = buffer[9];
+ streaming->header.bTriggerSupport = buffer[10];
+ streaming->header.bTriggerUsage = buffer[11];
+ streaming->header.bControlSize = n;
+
+ streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
+ if (streaming->header.bmaControls == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ memcpy(streaming->header.bmaControls, &buffer[13], p*n);
+ } else {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+ "%d HEADER descriptor not found.\n", dev->udev->devnum,
+ alts->desc.bInterfaceNumber);
+ goto error;
+ }
+
+ buflen -= buffer[0];
+ buffer += buffer[0];
+
+ _buffer = buffer;
+ _buflen = buflen;
+
+ /* Count the format and frame descriptors. */
+ while (_buflen > 2) {
+ switch (_buffer[2]) {
+ case VS_FORMAT_UNCOMPRESSED:
+ case VS_FORMAT_MJPEG:
+ case VS_FORMAT_FRAME_BASED:
+ nformats++;
+ break;
+
+ case VS_FORMAT_DV:
+ /* DV format has no frame descriptor. We will create a
+ * dummy frame descriptor with a dummy frame interval.
+ */
+ nformats++;
+ nframes++;
+ nintervals++;
+ break;
+
+ case VS_FORMAT_MPEG2TS:
+ case VS_FORMAT_STREAM_BASED:
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
+ "interface %d FORMAT %u is not supported.\n",
+ dev->udev->devnum,
+ alts->desc.bInterfaceNumber, _buffer[2]);
+ break;
+
+ case VS_FRAME_UNCOMPRESSED:
+ case VS_FRAME_MJPEG:
+ nframes++;
+ if (_buflen > 25)
+ nintervals += _buffer[25] ? _buffer[25] : 3;
+ break;
+
+ case VS_FRAME_FRAME_BASED:
+ nframes++;
+ if (_buflen > 21)
+ nintervals += _buffer[21] ? _buffer[21] : 3;
+ break;
+ }
+
+ _buflen -= _buffer[0];
+ _buffer += _buffer[0];
+ }
+
+ if (nformats == 0) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+ "%d has no supported formats defined.\n",
+ dev->udev->devnum, alts->desc.bInterfaceNumber);
+ goto error;
+ }
+
+ size = nformats * sizeof *format + nframes * sizeof *frame
+ + nintervals * sizeof *interval;
+ format = kzalloc(size, GFP_KERNEL);
+ if (format == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ frame = (struct uvc_frame *)&format[nformats];
+ interval = (__u32 *)&frame[nframes];
+
+ streaming->format = format;
+ streaming->nformats = nformats;
+
+ /* Parse the format descriptors. */
+ while (buflen > 2) {
+ switch (buffer[2]) {
+ case VS_FORMAT_UNCOMPRESSED:
+ case VS_FORMAT_MJPEG:
+ case VS_FORMAT_DV:
+ case VS_FORMAT_FRAME_BASED:
+ format->frame = frame;
+ ret = uvc_parse_format(dev, streaming, format,
+ &interval, buffer, buflen);
+ if (ret < 0)
+ goto error;
+
+ frame += format->nframes;
+ format++;
+
+ buflen -= ret;
+ buffer += ret;
+ continue;
+
+ default:
+ break;
+ }
+
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ /* Parse the alternate settings to find the maximum bandwidth. */
+ for (i = 0; i < intf->num_altsetting; ++i) {
+ struct usb_host_endpoint *ep;
+ alts = &intf->altsetting[i];
+ ep = uvc_find_endpoint(alts,
+ streaming->header.bEndpointAddress);
+ if (ep == NULL)
+ continue;
+
+ psize = le16_to_cpu(ep->desc.wMaxPacketSize);
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ if (psize > streaming->maxpsize)
+ streaming->maxpsize = psize;
+ }
+
+ list_add_tail(&streaming->list, &dev->streaming);
+ return 0;
+
+error:
+ usb_driver_release_interface(&uvc_driver.driver, intf);
+ usb_put_intf(intf);
+ kfree(streaming->format);
+ kfree(streaming->header.bmaControls);
+ kfree(streaming);
+ return ret;
+}
+
+/* Parse vendor-specific extensions. */
+static int uvc_parse_vendor_control(struct uvc_device *dev,
+ const unsigned char *buffer, int buflen)
+{
+ struct usb_device *udev = dev->udev;
+ struct usb_host_interface *alts = dev->intf->cur_altsetting;
+ struct uvc_entity *unit;
+ unsigned int n, p;
+ int handled = 0;
+
+ switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
+ case 0x046d: /* Logitech */
+ if (buffer[1] != 0x41 || buffer[2] != 0x01)
+ break;
+
+ /* Logitech implements several vendor specific functions
+ * through vendor specific extension units (LXU).
+ *
+ * The LXU descriptors are similar to XU descriptors
+ * (see "USB Device Video Class for Video Devices", section
+ * 3.7.2.6 "Extension Unit Descriptor") with the following
+ * differences:
+ *
+ * ----------------------------------------------------------
+ * 0 bLength 1 Number
+ * Size of this descriptor, in bytes: 24+p+n*2
+ * ----------------------------------------------------------
+ * 23+p+n bmControlsType N Bitmap
+ * Individual bits in the set are defined:
+ * 0: Absolute
+ * 1: Relative
+ *
+ * This bitset is mapped exactly the same as bmControls.
+ * ----------------------------------------------------------
+ * 23+p+n*2 bReserved 1 Boolean
+ * ----------------------------------------------------------
+ * 24+p+n*2 iExtension 1 Index
+ * Index of a string descriptor that describes this
+ * extension unit.
+ * ----------------------------------------------------------
+ */
+ p = buflen >= 22 ? buffer[21] : 0;
+ n = buflen >= 25 + p ? buffer[22+p] : 0;
+
+ if (buflen < 25 + p + 2*n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d EXTENSION_UNIT error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ break;
+ }
+
+ unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL);
+ if (unit == NULL)
+ return -ENOMEM;
+
+ unit->id = buffer[3];
+ unit->type = VC_EXTENSION_UNIT;
+ memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
+ unit->extension.bNumControls = buffer[20];
+ unit->extension.bNrInPins =
+ le16_to_cpup((__le16 *)&buffer[21]);
+ unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
+ memcpy(unit->extension.baSourceID, &buffer[22], p);
+ unit->extension.bControlSize = buffer[22+p];
+ unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
+ unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit
+ + p + n;
+ memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
+
+ if (buffer[24+p+2*n] != 0)
+ usb_string(udev, buffer[24+p+2*n], unit->name,
+ sizeof unit->name);
+ else
+ sprintf(unit->name, "Extension %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+ handled = 1;
+ break;
+ }
+
+ return handled;
+}
+
+static int uvc_parse_standard_control(struct uvc_device *dev,
+ const unsigned char *buffer, int buflen)
+{
+ struct usb_device *udev = dev->udev;
+ struct uvc_entity *unit, *term;
+ struct usb_interface *intf;
+ struct usb_host_interface *alts = dev->intf->cur_altsetting;
+ unsigned int i, n, p, len;
+ __u16 type;
+
+ switch (buffer[2]) {
+ case VC_HEADER:
+ n = buflen >= 12 ? buffer[11] : 0;
+
+ if (buflen < 12 || buflen < 12 + n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d HEADER error\n", udev->devnum,
+ alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]);
+ dev->clock_frequency = le32_to_cpup((__le32 *)&buffer[7]);
+
+ /* Parse all USB Video Streaming interfaces. */
+ for (i = 0; i < n; ++i) {
+ intf = usb_ifnum_to_if(udev, buffer[12+i]);
+ if (intf == NULL) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d "
+ "interface %d doesn't exists\n",
+ udev->devnum, i);
+ continue;
+ }
+
+ uvc_parse_streaming(dev, intf);
+ }
+ break;
+
+ case VC_INPUT_TERMINAL:
+ if (buflen < 8) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d INPUT_TERMINAL error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ /* Make sure the terminal type MSB is not null, otherwise it
+ * could be confused with a unit.
+ */
+ type = le16_to_cpup((__le16 *)&buffer[4]);
+ if ((type & 0xff00) == 0) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d INPUT_TERMINAL %d has invalid "
+ "type 0x%04x, skipping\n", udev->devnum,
+ alts->desc.bInterfaceNumber,
+ buffer[3], type);
+ return 0;
+ }
+
+ n = 0;
+ p = 0;
+ len = 8;
+
+ if (type == ITT_CAMERA) {
+ n = buflen >= 15 ? buffer[14] : 0;
+ len = 15;
+
+ } else if (type == ITT_MEDIA_TRANSPORT_INPUT) {
+ n = buflen >= 9 ? buffer[8] : 0;
+ p = buflen >= 10 + n ? buffer[9+n] : 0;
+ len = 10;
+ }
+
+ if (buflen < len + n + p) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d INPUT_TERMINAL error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ term = kzalloc(sizeof *term + n + p, GFP_KERNEL);
+ if (term == NULL)
+ return -ENOMEM;
+
+ term->id = buffer[3];
+ term->type = type | UVC_TERM_INPUT;
+
+ if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) {
+ term->camera.bControlSize = n;
+ term->camera.bmControls = (__u8 *)term + sizeof *term;
+ term->camera.wObjectiveFocalLengthMin =
+ le16_to_cpup((__le16 *)&buffer[8]);
+ term->camera.wObjectiveFocalLengthMax =
+ le16_to_cpup((__le16 *)&buffer[10]);
+ term->camera.wOcularFocalLength =
+ le16_to_cpup((__le16 *)&buffer[12]);
+ memcpy(term->camera.bmControls, &buffer[15], n);
+ } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) {
+ term->media.bControlSize = n;
+ term->media.bmControls = (__u8 *)term + sizeof *term;
+ term->media.bTransportModeSize = p;
+ term->media.bmTransportModes = (__u8 *)term
+ + sizeof *term + n;
+ memcpy(term->media.bmControls, &buffer[9], n);
+ memcpy(term->media.bmTransportModes, &buffer[10+n], p);
+ }
+
+ if (buffer[7] != 0)
+ usb_string(udev, buffer[7], term->name,
+ sizeof term->name);
+ else if (UVC_ENTITY_TYPE(term) == ITT_CAMERA)
+ sprintf(term->name, "Camera %u", buffer[3]);
+ else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT)
+ sprintf(term->name, "Media %u", buffer[3]);
+ else
+ sprintf(term->name, "Input %u", buffer[3]);
+
+ list_add_tail(&term->list, &dev->entities);
+ break;
+
+ case VC_OUTPUT_TERMINAL:
+ if (buflen < 9) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d OUTPUT_TERMINAL error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ /* Make sure the terminal type MSB is not null, otherwise it
+ * could be confused with a unit.
+ */
+ type = le16_to_cpup((__le16 *)&buffer[4]);
+ if ((type & 0xff00) == 0) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d OUTPUT_TERMINAL %d has invalid "
+ "type 0x%04x, skipping\n", udev->devnum,
+ alts->desc.bInterfaceNumber, buffer[3], type);
+ return 0;
+ }
+
+ term = kzalloc(sizeof *term, GFP_KERNEL);
+ if (term == NULL)
+ return -ENOMEM;
+
+ term->id = buffer[3];
+ term->type = type | UVC_TERM_OUTPUT;
+ term->output.bSourceID = buffer[7];
+
+ if (buffer[8] != 0)
+ usb_string(udev, buffer[8], term->name,
+ sizeof term->name);
+ else
+ sprintf(term->name, "Output %u", buffer[3]);
+
+ list_add_tail(&term->list, &dev->entities);
+ break;
+
+ case VC_SELECTOR_UNIT:
+ p = buflen >= 5 ? buffer[4] : 0;
+
+ if (buflen < 5 || buflen < 6 + p) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d SELECTOR_UNIT error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ unit = kzalloc(sizeof *unit + p, GFP_KERNEL);
+ if (unit == NULL)
+ return -ENOMEM;
+
+ unit->id = buffer[3];
+ unit->type = buffer[2];
+ unit->selector.bNrInPins = buffer[4];
+ unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
+ memcpy(unit->selector.baSourceID, &buffer[5], p);
+
+ if (buffer[5+p] != 0)
+ usb_string(udev, buffer[5+p], unit->name,
+ sizeof unit->name);
+ else
+ sprintf(unit->name, "Selector %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+ break;
+
+ case VC_PROCESSING_UNIT:
+ n = buflen >= 8 ? buffer[7] : 0;
+ p = dev->uvc_version >= 0x0110 ? 10 : 9;
+
+ if (buflen < p + n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d PROCESSING_UNIT error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ unit = kzalloc(sizeof *unit + n, GFP_KERNEL);
+ if (unit == NULL)
+ return -ENOMEM;
+
+ unit->id = buffer[3];
+ unit->type = buffer[2];
+ unit->processing.bSourceID = buffer[4];
+ unit->processing.wMaxMultiplier =
+ le16_to_cpup((__le16 *)&buffer[5]);
+ unit->processing.bControlSize = buffer[7];
+ unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
+ memcpy(unit->processing.bmControls, &buffer[8], n);
+ if (dev->uvc_version >= 0x0110)
+ unit->processing.bmVideoStandards = buffer[9+n];
+
+ if (buffer[8+n] != 0)
+ usb_string(udev, buffer[8+n], unit->name,
+ sizeof unit->name);
+ else
+ sprintf(unit->name, "Processing %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+ break;
+
+ case VC_EXTENSION_UNIT:
+ p = buflen >= 22 ? buffer[21] : 0;
+ n = buflen >= 24 + p ? buffer[22+p] : 0;
+
+ if (buflen < 24 + p + n) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
+ "interface %d EXTENSION_UNIT error\n",
+ udev->devnum, alts->desc.bInterfaceNumber);
+ return -EINVAL;
+ }
+
+ unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL);
+ if (unit == NULL)
+ return -ENOMEM;
+
+ unit->id = buffer[3];
+ unit->type = buffer[2];
+ memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
+ unit->extension.bNumControls = buffer[20];
+ unit->extension.bNrInPins =
+ le16_to_cpup((__le16 *)&buffer[21]);
+ unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
+ memcpy(unit->extension.baSourceID, &buffer[22], p);
+ unit->extension.bControlSize = buffer[22+p];
+ unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
+ memcpy(unit->extension.bmControls, &buffer[23+p], n);
+
+ if (buffer[23+p+n] != 0)
+ usb_string(udev, buffer[23+p+n], unit->name,
+ sizeof unit->name);
+ else
+ sprintf(unit->name, "Extension %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+ break;
+
+ default:
+ uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE "
+ "descriptor (%u)\n", buffer[2]);
+ break;
+ }
+
+ return 0;
+}
+
+static int uvc_parse_control(struct uvc_device *dev)
+{
+ struct usb_host_interface *alts = dev->intf->cur_altsetting;
+ unsigned char *buffer = alts->extra;
+ int buflen = alts->extralen;
+ int ret;
+
+ /* Parse the default alternate setting only, as the UVC specification
+ * defines a single alternate setting, the default alternate setting
+ * zero.
+ */
+
+ while (buflen > 2) {
+ if (uvc_parse_vendor_control(dev, buffer, buflen) ||
+ buffer[1] != USB_DT_CS_INTERFACE)
+ goto next_descriptor;
+
+ if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0)
+ return ret;
+
+next_descriptor:
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ /* Check if the optional status endpoint is present. */
+ if (alts->desc.bNumEndpoints == 1) {
+ struct usb_host_endpoint *ep = &alts->endpoint[0];
+ struct usb_endpoint_descriptor *desc = &ep->desc;
+
+ if (usb_endpoint_is_int_in(desc) &&
+ le16_to_cpu(desc->wMaxPacketSize) >= 8 &&
+ desc->bInterval != 0) {
+ uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint "
+ "(addr %02x).\n", desc->bEndpointAddress);
+ dev->int_ep = ep;
+ }
+ }
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * USB probe and disconnect
+ */
+
+/*
+ * Unregister the video devices.
+ */
+static void uvc_unregister_video(struct uvc_device *dev)
+{
+ if (dev->video.vdev) {
+ if (dev->video.vdev->minor == -1)
+ video_device_release(dev->video.vdev);
+ else
+ video_unregister_device(dev->video.vdev);
+ dev->video.vdev = NULL;
+ }
+}
+
+/*
+ * Scan the UVC descriptors to locate a chain starting at an Output Terminal
+ * and containing the following units:
+ *
+ * - a USB Streaming Output Terminal
+ * - zero or one Processing Unit
+ * - zero, one or mode single-input Selector Units
+ * - zero or one multiple-input Selector Units, provided all inputs are
+ * connected to input terminals
+ * - zero, one or mode single-input Extension Units
+ * - one Camera Input Terminal, or one or more External terminals.
+ *
+ * A side forward scan is made on each detected entity to check for additional
+ * extension units.
+ */
+static int uvc_scan_chain_entity(struct uvc_video_device *video,
+ struct uvc_entity *entity)
+{
+ switch (UVC_ENTITY_TYPE(entity)) {
+ case VC_EXTENSION_UNIT:
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" <- XU %d", entity->id);
+
+ if (entity->extension.bNrInPins != 1) {
+ uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
+ "than 1 input pin.\n", entity->id);
+ return -1;
+ }
+
+ list_add_tail(&entity->chain, &video->extensions);
+ break;
+
+ case VC_PROCESSING_UNIT:
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" <- PU %d", entity->id);
+
+ if (video->processing != NULL) {
+ uvc_trace(UVC_TRACE_DESCR, "Found multiple "
+ "Processing Units in chain.\n");
+ return -1;
+ }
+
+ video->processing = entity;
+ break;
+
+ case VC_SELECTOR_UNIT:
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" <- SU %d", entity->id);
+
+ /* Single-input selector units are ignored. */
+ if (entity->selector.bNrInPins == 1)
+ break;
+
+ if (video->selector != NULL) {
+ uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
+ "Units in chain.\n");
+ return -1;
+ }
+
+ video->selector = entity;
+ break;
+
+ case ITT_VENDOR_SPECIFIC:
+ case ITT_CAMERA:
+ case ITT_MEDIA_TRANSPORT_INPUT:
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" <- IT %d\n", entity->id);
+
+ list_add_tail(&entity->chain, &video->iterms);
+ break;
+
+ default:
+ uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type "
+ "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int uvc_scan_chain_forward(struct uvc_video_device *video,
+ struct uvc_entity *entity, struct uvc_entity *prev)
+{
+ struct uvc_entity *forward;
+ int found;
+
+ /* Forward scan */
+ forward = NULL;
+ found = 0;
+
+ while (1) {
+ forward = uvc_entity_by_reference(video->dev, entity->id,
+ forward);
+ if (forward == NULL)
+ break;
+
+ if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT ||
+ forward == prev)
+ continue;
+
+ if (forward->extension.bNrInPins != 1) {
+ uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has"
+ "more than 1 input pin.\n", entity->id);
+ return -1;
+ }
+
+ list_add_tail(&forward->chain, &video->extensions);
+ if (uvc_trace_param & UVC_TRACE_PROBE) {
+ if (!found)
+ printk(" (-> XU");
+
+ printk(" %d", forward->id);
+ found = 1;
+ }
+ }
+ if (found)
+ printk(")");
+
+ return 0;
+}
+
+static int uvc_scan_chain_backward(struct uvc_video_device *video,
+ struct uvc_entity *entity)
+{
+ struct uvc_entity *term;
+ int id = -1, i;
+
+ switch (UVC_ENTITY_TYPE(entity)) {
+ case VC_EXTENSION_UNIT:
+ id = entity->extension.baSourceID[0];
+ break;
+
+ case VC_PROCESSING_UNIT:
+ id = entity->processing.bSourceID;
+ break;
+
+ case VC_SELECTOR_UNIT:
+ /* Single-input selector units are ignored. */
+ if (entity->selector.bNrInPins == 1) {
+ id = entity->selector.baSourceID[0];
+ break;
+ }
+
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" <- IT");
+
+ video->selector = entity;
+ for (i = 0; i < entity->selector.bNrInPins; ++i) {
+ id = entity->selector.baSourceID[i];
+ term = uvc_entity_by_id(video->dev, id);
+ if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
+ uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
+ "input %d isn't connected to an "
+ "input terminal\n", entity->id, i);
+ return -1;
+ }
+
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk(" %d", term->id);
+
+ list_add_tail(&term->chain, &video->iterms);
+ uvc_scan_chain_forward(video, term, entity);
+ }
+
+ if (uvc_trace_param & UVC_TRACE_PROBE)
+ printk("\n");
+
+ id = 0;
+ break;
+ }
+
+ return id;
+}
+
+static int uvc_scan_chain(struct uvc_video_device *video)
+{
+ struct uvc_entity *entity, *prev;
+ int id;
+
+ entity = video->oterm;
+ uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
+ id = entity->output.bSourceID;
+ while (id != 0) {
+ prev = entity;
+ entity = uvc_entity_by_id(video->dev, id);
+ if (entity == NULL) {
+ uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+ "unknown entity %d.\n", id);
+ return -1;
+ }
+
+ /* Process entity */
+ if (uvc_scan_chain_entity(video, entity) < 0)
+ return -1;
+
+ /* Forward scan */
+ if (uvc_scan_chain_forward(video, entity, prev) < 0)
+ return -1;
+
+ /* Stop when a terminal is found. */
+ if (!UVC_ENTITY_IS_UNIT(entity))
+ break;
+
+ /* Backward scan */
+ id = uvc_scan_chain_backward(video, entity);
+ if (id < 0)
+ return id;
+ }
+
+ /* Initialize the video buffers queue. */
+ uvc_queue_init(&video->queue);
+
+ return 0;
+}
+
+/*
+ * Register the video devices.
+ *
+ * The driver currently supports a single video device per control interface
+ * only. The terminal and units must match the following structure:
+ *
+ * ITT_CAMERA -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
+ *
+ * The Extension Units, if present, must have a single input pin. The
+ * Processing Unit and Extension Units can be in any order. Additional
+ * Extension Units connected to the main chain as single-unit branches are
+ * also supported.
+ */
+static int uvc_register_video(struct uvc_device *dev)
+{
+ struct video_device *vdev;
+ struct uvc_entity *term;
+ int found = 0, ret;
+
+ /* Check if the control interface matches the structure we expect. */
+ list_for_each_entry(term, &dev->entities, list) {
+ struct uvc_streaming *streaming;
+
+ if (UVC_ENTITY_TYPE(term) != TT_STREAMING)
+ continue;
+
+ memset(&dev->video, 0, sizeof dev->video);
+ mutex_init(&dev->video.ctrl_mutex);
+ INIT_LIST_HEAD(&dev->video.iterms);
+ INIT_LIST_HEAD(&dev->video.extensions);
+ dev->video.oterm = term;
+ dev->video.dev = dev;
+ if (uvc_scan_chain(&dev->video) < 0)
+ continue;
+
+ list_for_each_entry(streaming, &dev->streaming, list) {
+ if (streaming->header.bTerminalLink == term->id) {
+ dev->video.streaming = streaming;
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found) {
+ uvc_printk(KERN_INFO, "No valid video chain found.\n");
+ return -1;
+ }
+
+ if (uvc_trace_param & UVC_TRACE_PROBE) {
+ uvc_printk(KERN_INFO, "Found a valid video chain (");
+ list_for_each_entry(term, &dev->video.iterms, chain) {
+ printk("%d", term->id);
+ if (term->chain.next != &dev->video.iterms)
+ printk(",");
+ }
+ printk(" -> %d).\n", dev->video.oterm->id);
+ }
+
+ /* Initialize the streaming interface with default streaming
+ * parameters.
+ */
+ if ((ret = uvc_video_init(&dev->video)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to initialize the device "
+ "(%d).\n", ret);
+ return ret;
+ }
+
+ /* Register the device with V4L. */
+ vdev = video_device_alloc();
+ if (vdev == NULL)
+ return -1;
+
+ /* We already hold a reference to dev->udev. The video device will be
+ * unregistered before the reference is released, so we don't need to
+ * get another one.
+ */
+ vdev->dev = &dev->intf->dev;
+ vdev->type = 0;
+ vdev->type2 = 0;
+ vdev->minor = -1;
+ vdev->fops = &uvc_fops;
+ vdev->release = video_device_release;
+ strncpy(vdev->name, dev->name, sizeof vdev->name);
+
+ /* Set the driver data before calling video_register_device, otherwise
+ * uvc_v4l2_open might race us.
+ *
+ * FIXME: usb_set_intfdata hasn't been called so far. Is that a
+ * problem ? Does any function which could be called here get
+ * a pointer to the usb_interface ?
+ */
+ dev->video.vdev = vdev;
+ video_set_drvdata(vdev, &dev->video);
+
+ if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) {
+ dev->video.vdev = NULL;
+ video_device_release(vdev);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Delete the UVC device.
+ *
+ * Called by the kernel when the last reference to the uvc_device structure
+ * is released.
+ *
+ * Unregistering the video devices is done here because every opened instance
+ * must be closed before the device can be unregistered. An alternative would
+ * have been to use another reference count for uvc_v4l2_open/uvc_release, and
+ * unregister the video devices on disconnect when that reference count drops
+ * to zero.
+ *
+ * As this function is called after or during disconnect(), all URBs have
+ * already been canceled by the USB core. There is no need to kill the
+ * interrupt URB manually.
+ */
+void uvc_delete(struct kref *kref)
+{
+ struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
+ struct list_head *p, *n;
+
+ /* Unregister the video device */
+ uvc_unregister_video(dev);
+ usb_put_intf(dev->intf);
+ usb_put_dev(dev->udev);
+
+ uvc_status_cleanup(dev);
+ uvc_ctrl_cleanup_device(dev);
+
+ list_for_each_safe(p, n, &dev->entities) {
+ struct uvc_entity *entity;
+ entity = list_entry(p, struct uvc_entity, list);
+ kfree(entity);
+ }
+
+ list_for_each_safe(p, n, &dev->streaming) {
+ struct uvc_streaming *streaming;
+ streaming = list_entry(p, struct uvc_streaming, list);
+ usb_driver_release_interface(&uvc_driver.driver,
+ streaming->intf);
+ usb_put_intf(streaming->intf);
+ kfree(streaming->format);
+ kfree(streaming->header.bmaControls);
+ kfree(streaming);
+ }
+
+ kfree(dev);
+}
+
+static int uvc_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct uvc_device *dev;
+ int ret;
+
+ if (id->idVendor && id->idProduct)
+ uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s "
+ "(%04x:%04x)\n", udev->devpath, id->idVendor,
+ id->idProduct);
+ else
+ uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
+ udev->devpath);
+
+ /* Allocate memory for the device and initialize it */
+ if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&dev->entities);
+ INIT_LIST_HEAD(&dev->streaming);
+ kref_init(&dev->kref);
+
+ dev->udev = usb_get_dev(udev);
+ dev->intf = usb_get_intf(intf);
+ dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
+ dev->quirks = id->driver_info | uvc_quirks_param;
+
+ if (udev->product != NULL)
+ strncpy(dev->name, udev->product, sizeof dev->name);
+ else
+ snprintf(dev->name, sizeof dev->name,
+ "UVC Camera (%04x:%04x)",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ /* Parse the Video Class control descriptor */
+ if (uvc_parse_control(dev) < 0) {
+ uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
+ "descriptors.\n");
+ goto error;
+ }
+
+ uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
+ dev->uvc_version >> 8, dev->uvc_version & 0xff,
+ udev->product ? udev->product : "<unnamed>",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ if (uvc_quirks_param != 0) {
+ uvc_printk(KERN_INFO, "Forcing device quirks 0x%x by module "
+ "parameter for testing purpose.\n", uvc_quirks_param);
+ uvc_printk(KERN_INFO, "Please report required quirks to the "
+ "linux-uvc-devel mailing list.\n");
+ }
+
+ /* Initialize controls */
+ if (uvc_ctrl_init_device(dev) < 0)
+ goto error;
+
+ /* Register the video devices */
+ if (uvc_register_video(dev) < 0)
+ goto error;
+
+ /* Save our data pointer in the interface data */
+ usb_set_intfdata(intf, dev);
+
+ /* Initialize the interrupt URB */
+ if ((ret = uvc_status_init(dev)) < 0) {
+ uvc_printk(KERN_INFO, "Unable to initialize the status "
+ "endpoint (%d), status interrupt will not be "
+ "supported.\n", ret);
+ }
+
+ uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
+ return 0;
+
+error:
+ kref_put(&dev->kref, uvc_delete);
+ return -ENODEV;
+}
+
+static void uvc_disconnect(struct usb_interface *intf)
+{
+ struct uvc_device *dev = usb_get_intfdata(intf);
+
+ /* Set the USB interface data to NULL. This can be done outside the
+ * lock, as there's no other reader.
+ */
+ usb_set_intfdata(intf, NULL);
+
+ if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING)
+ return;
+
+ /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
+ * lock is needed to prevent uvc_disconnect from releasing its
+ * reference to the uvc_device instance after uvc_v4l2_open() received
+ * the pointer to the device (video_devdata) but before it got the
+ * chance to increase the reference count (kref_get).
+ */
+ mutex_lock(&uvc_driver.open_mutex);
+
+ dev->state |= UVC_DEV_DISCONNECTED;
+ kref_put(&dev->kref, uvc_delete);
+
+ mutex_unlock(&uvc_driver.open_mutex);
+}
+
+static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct uvc_device *dev = usb_get_intfdata(intf);
+
+ uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ /* Controls are cached on the fly so they don't need to be saved. */
+ if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
+ return uvc_status_suspend(dev);
+
+ if (dev->video.streaming->intf != intf) {
+ uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB "
+ "interface mismatch.\n");
+ return -EINVAL;
+ }
+
+ return uvc_video_suspend(&dev->video);
+}
+
+static int uvc_resume(struct usb_interface *intf)
+{
+ struct uvc_device *dev = usb_get_intfdata(intf);
+ int ret;
+
+ uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) {
+ if ((ret = uvc_ctrl_resume_device(dev)) < 0)
+ return ret;
+
+ return uvc_status_resume(dev);
+ }
+
+ if (dev->video.streaming->intf != intf) {
+ uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB "
+ "interface mismatch.\n");
+ return -EINVAL;
+ }
+
+ return uvc_video_resume(&dev->video);
+}
+
+/* ------------------------------------------------------------------------
+ * Driver initialization and cleanup
+ */
+
+/*
+ * The Logitech cameras listed below have their interface class set to
+ * VENDOR_SPEC because they don't announce themselves as UVC devices, even
+ * though they are compliant.
+ */
+static struct usb_device_id uvc_ids[] = {
+ /* ALi M5606 (Clevo M540SR) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0402,
+ .idProduct = 0x5606,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Creative Live! Optia */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x041e,
+ .idProduct = 0x4057,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Microsoft Lifecam NX-6000 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x045e,
+ .idProduct = 0x00f8,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Microsoft Lifecam VX-7000 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x045e,
+ .idProduct = 0x0723,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Logitech Quickcam Fusion */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c1,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Logitech Quickcam Orbit MP */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c2,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Logitech Quickcam Pro for Notebook */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c3,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Logitech Quickcam Pro 5000 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c5,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Logitech Quickcam OEM Dell Notebook */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c6,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Logitech Quickcam OEM Cisco VT Camera II */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x046d,
+ .idProduct = 0x08c7,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0 },
+ /* Apple Built-In iSight */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x05ac,
+ .idProduct = 0x8501,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_BUILTIN_ISIGHT },
+ /* Genesys Logic USB 2.0 PC Camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x05e3,
+ .idProduct = 0x0505,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Silicon Motion SM371 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x090c,
+ .idProduct = 0xb371,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* MT6227 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0e8d,
+ .idProduct = 0x0004,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Syntek (HP Spartan) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x5212,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (Asus U3S) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x8a33,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Ecamm Pico iMage */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x18cd,
+ .idProduct = 0xcafe,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
+ /* Bodelin ProScopeHR */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_DEV_HI
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x19ab,
+ .idProduct = 0x1000,
+ .bcdDevice_hi = 0x0126,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STATUS_INTERVAL },
+ /* SiGma Micro USB Web Camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1c4f,
+ .idProduct = 0x3000,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_IGNORE_SELECTOR_UNIT},
+ /* Acer OEM Webcam - Unknown vendor */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x5986,
+ .idProduct = 0x0100,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Packard Bell OEM Webcam */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x5986,
+ .idProduct = 0x0101,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Acer Crystal Eye webcam */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x5986,
+ .idProduct = 0x0102,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Acer OrbiCam - Unknown vendor */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x5986,
+ .idProduct = 0x0200,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Generic USB Video Class */
+ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, uvc_ids);
+
+struct uvc_driver uvc_driver = {
+ .driver = {
+ .name = "uvcvideo",
+ .probe = uvc_probe,
+ .disconnect = uvc_disconnect,
+ .suspend = uvc_suspend,
+ .resume = uvc_resume,
+ .id_table = uvc_ids,
+ .supports_autosuspend = 1,
+ },
+};
+
+static int __init uvc_init(void)
+{
+ int result;
+
+ INIT_LIST_HEAD(&uvc_driver.devices);
+ INIT_LIST_HEAD(&uvc_driver.controls);
+ mutex_init(&uvc_driver.open_mutex);
+ mutex_init(&uvc_driver.ctrl_mutex);
+
+ uvc_ctrl_init();
+
+ result = usb_register(&uvc_driver.driver);
+ if (result == 0)
+ printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
+ return result;
+}
+
+static void __exit uvc_cleanup(void)
+{
+ usb_deregister(&uvc_driver.driver);
+}
+
+module_init(uvc_init);
+module_exit(uvc_cleanup);
+
+module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(quirks, "Forced device quirks");
+module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(trace, "Trace level bitmask");
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
new file mode 100644
index 00000000000..37bdefdbead
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -0,0 +1,134 @@
+/*
+ * uvc_isight.c -- USB Video Class driver - iSight support
+ *
+ * Copyright (C) 2006-2007
+ * Ivan N. Zlatev <contact@i-nz.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include "uvcvideo.h"
+
+/* Built-in iSight webcams implements most of UVC 1.0 except a
+ * different packet format. Instead of sending a header at the
+ * beginning of each isochronous transfer payload, the webcam sends a
+ * single header per image (on its own in a packet), followed by
+ * packets containing data only.
+ *
+ * Offset Size (bytes) Description
+ * ------------------------------------------------------------------
+ * 0x00 1 Header length
+ * 0x01 1 Flags (UVC-compliant)
+ * 0x02 4 Always equal to '11223344'
+ * 0x06 8 Always equal to 'deadbeefdeadface'
+ * 0x0e 16 Unknown
+ *
+ * The header can be prefixed by an optional, unknown-purpose byte.
+ */
+
+static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
+ const __u8 *data, unsigned int len)
+{
+ static const __u8 hdr[] = {
+ 0x11, 0x22, 0x33, 0x44,
+ 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xfa, 0xce
+ };
+
+ unsigned int maxlen, nbytes;
+ __u8 *mem;
+ int is_header = 0;
+
+ if (buf == NULL)
+ return 0;
+
+ if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) ||
+ (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) {
+ uvc_trace(UVC_TRACE_FRAME, "iSight header found\n");
+ is_header = 1;
+ }
+
+ /* Synchronize to the input stream by waiting for a header packet. */
+ if (buf->state != UVC_BUF_STATE_ACTIVE) {
+ if (!is_header) {
+ uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of "
+ "sync).\n");
+ return 0;
+ }
+
+ buf->state = UVC_BUF_STATE_ACTIVE;
+ }
+
+ /* Mark the buffer as done if we're at the beginning of a new frame.
+ *
+ * Empty buffers (bytesused == 0) don't trigger end of frame detection
+ * as it doesn't make sense to return an empty buffer.
+ */
+ if (is_header && buf->buf.bytesused != 0) {
+ buf->state = UVC_BUF_STATE_DONE;
+ return -EAGAIN;
+ }
+
+ /* Copy the video data to the buffer. Skip header packets, as they
+ * contain no data.
+ */
+ if (!is_header) {
+ maxlen = buf->buf.length - buf->buf.bytesused;
+ mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+ nbytes = min(len, maxlen);
+ memcpy(mem, data, nbytes);
+ buf->buf.bytesused += nbytes;
+
+ if (len > maxlen || buf->buf.bytesused == buf->buf.length) {
+ uvc_trace(UVC_TRACE_FRAME, "Frame complete "
+ "(overflow).\n");
+ buf->state = UVC_BUF_STATE_DONE;
+ }
+ }
+
+ return 0;
+}
+
+void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
+ struct uvc_buffer *buf)
+{
+ int ret, i;
+
+ for (i = 0; i < urb->number_of_packets; ++i) {
+ if (urb->iso_frame_desc[i].status < 0) {
+ uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame "
+ "lost (%d).\n",
+ urb->iso_frame_desc[i].status);
+ }
+
+ /* Decode the payload packet.
+ * uvc_video_decode is entered twice when a frame transition
+ * has been detected because the end of frame can only be
+ * reliably detected when the first packet of the new frame
+ * is processed. The first pass detects the transition and
+ * closes the previous frame's buffer, the second pass
+ * processes the data of the first payload of the new frame.
+ */
+ do {
+ ret = isight_decode(&video->queue, buf,
+ urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset,
+ urb->iso_frame_desc[i].actual_length);
+
+ if (buf == NULL)
+ break;
+
+ if (buf->state == UVC_BUF_STATE_DONE ||
+ buf->state == UVC_BUF_STATE_ERROR)
+ buf = uvc_queue_next_buffer(&video->queue, buf);
+ } while (ret == -EAGAIN);
+ }
+}
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
new file mode 100644
index 00000000000..0923f0e3b3d
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -0,0 +1,477 @@
+/*
+ * uvc_queue.c -- USB Video Class driver - Buffers management
+ *
+ * Copyright (C) 2005-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+
+#include "uvcvideo.h"
+
+/* ------------------------------------------------------------------------
+ * Video buffers queue management.
+ *
+ * Video queues is initialized by uvc_queue_init(). The function performs
+ * basic initialization of the uvc_video_queue struct and never fails.
+ *
+ * Video buffer allocation and freeing are performed by uvc_alloc_buffers and
+ * uvc_free_buffers respectively. The former acquires the video queue lock,
+ * while the later must be called with the lock held (so that allocation can
+ * free previously allocated buffers). Trying to free buffers that are mapped
+ * to user space will return -EBUSY.
+ *
+ * Video buffers are managed using two queues. However, unlike most USB video
+ * drivers which use an in queue and an out queue, we use a main queue which
+ * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
+ * queue which holds empty buffers. This design (copied from video-buf)
+ * minimizes locking in interrupt, as only one queue is shared between
+ * interrupt and user contexts.
+ *
+ * Use cases
+ * ---------
+ *
+ * Unless stated otherwise, all operations which modify the irq buffers queue
+ * are protected by the irq spinlock.
+ *
+ * 1. The user queues the buffers, starts streaming and dequeues a buffer.
+ *
+ * The buffers are added to the main and irq queues. Both operations are
+ * protected by the queue lock, and the latert is protected by the irq
+ * spinlock as well.
+ *
+ * The completion handler fetches a buffer from the irq queue and fills it
+ * with video data. If no buffer is available (irq queue empty), the handler
+ * returns immediately.
+ *
+ * When the buffer is full, the completion handler removes it from the irq
+ * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
+ * At that point, any process waiting on the buffer will be woken up. If a
+ * process tries to dequeue a buffer after it has been marked ready, the
+ * dequeing will succeed immediately.
+ *
+ * 2. Buffers are queued, user is waiting on a buffer and the device gets
+ * disconnected.
+ *
+ * When the device is disconnected, the kernel calls the completion handler
+ * with an appropriate status code. The handler marks all buffers in the
+ * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so
+ * that any process waiting on a buffer gets woken up.
+ *
+ * Waking up up the first buffer on the irq list is not enough, as the
+ * process waiting on the buffer might restart the dequeue operation
+ * immediately.
+ *
+ */
+
+void uvc_queue_init(struct uvc_video_queue *queue)
+{
+ mutex_init(&queue->mutex);
+ spin_lock_init(&queue->irqlock);
+ INIT_LIST_HEAD(&queue->mainqueue);
+ INIT_LIST_HEAD(&queue->irqqueue);
+}
+
+/*
+ * Allocate the video buffers.
+ *
+ * Pages are reserved to make sure they will not be swaped, as they will be
+ * filled in URB completion handler.
+ *
+ * Buffers will be individually mapped, so they must all be page aligned.
+ */
+int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
+ unsigned int buflength)
+{
+ unsigned int bufsize = PAGE_ALIGN(buflength);
+ unsigned int i;
+ void *mem = NULL;
+ int ret;
+
+ if (nbuffers > UVC_MAX_VIDEO_BUFFERS)
+ nbuffers = UVC_MAX_VIDEO_BUFFERS;
+
+ mutex_lock(&queue->mutex);
+
+ if ((ret = uvc_free_buffers(queue)) < 0)
+ goto done;
+
+ /* Bail out if no buffers should be allocated. */
+ if (nbuffers == 0)
+ goto done;
+
+ /* Decrement the number of buffers until allocation succeeds. */
+ for (; nbuffers > 0; --nbuffers) {
+ mem = vmalloc_32(nbuffers * bufsize);
+ if (mem != NULL)
+ break;
+ }
+
+ if (mem == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < nbuffers; ++i) {
+ memset(&queue->buffer[i], 0, sizeof queue->buffer[i]);
+ queue->buffer[i].buf.index = i;
+ queue->buffer[i].buf.m.offset = i * bufsize;
+ queue->buffer[i].buf.length = buflength;
+ queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ queue->buffer[i].buf.sequence = 0;
+ queue->buffer[i].buf.field = V4L2_FIELD_NONE;
+ queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
+ queue->buffer[i].buf.flags = 0;
+ init_waitqueue_head(&queue->buffer[i].wait);
+ }
+
+ queue->mem = mem;
+ queue->count = nbuffers;
+ queue->buf_size = bufsize;
+ ret = nbuffers;
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
+ * Free the video buffers.
+ *
+ * This function must be called with the queue lock held.
+ */
+int uvc_free_buffers(struct uvc_video_queue *queue)
+{
+ unsigned int i;
+
+ for (i = 0; i < queue->count; ++i) {
+ if (queue->buffer[i].vma_use_count != 0)
+ return -EBUSY;
+ }
+
+ if (queue->count) {
+ vfree(queue->mem);
+ queue->count = 0;
+ }
+
+ return 0;
+}
+
+static void __uvc_query_buffer(struct uvc_buffer *buf,
+ struct v4l2_buffer *v4l2_buf)
+{
+ memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);
+
+ if (buf->vma_use_count)
+ v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED;
+
+ switch (buf->state) {
+ case UVC_BUF_STATE_ERROR:
+ case UVC_BUF_STATE_DONE:
+ v4l2_buf->flags |= V4L2_BUF_FLAG_DONE;
+ break;
+ case UVC_BUF_STATE_QUEUED:
+ case UVC_BUF_STATE_ACTIVE:
+ v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
+ break;
+ case UVC_BUF_STATE_IDLE:
+ default:
+ break;
+ }
+}
+
+int uvc_query_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf)
+{
+ int ret = 0;
+
+ mutex_lock(&queue->mutex);
+ if (v4l2_buf->index >= queue->count) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
+ * Queue a video buffer. Attempting to queue a buffer that has already been
+ * queued will return -EINVAL.
+ */
+int uvc_queue_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf)
+{
+ struct uvc_buffer *buf;
+ unsigned long flags;
+ int ret = 0;
+
+ uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
+
+ if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ v4l2_buf->memory != V4L2_MEMORY_MMAP) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
+ "and/or memory (%u).\n", v4l2_buf->type,
+ v4l2_buf->memory);
+ return -EINVAL;
+ }
+
+ mutex_lock(&queue->mutex);
+ if (v4l2_buf->index >= queue->count) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ buf = &queue->buffer[v4l2_buf->index];
+ if (buf->state != UVC_BUF_STATE_IDLE) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state "
+ "(%u).\n", buf->state);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ spin_lock_irqsave(&queue->irqlock, flags);
+ if (queue->flags & UVC_QUEUE_DISCONNECTED) {
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+ ret = -ENODEV;
+ goto done;
+ }
+ buf->state = UVC_BUF_STATE_QUEUED;
+ buf->buf.bytesused = 0;
+ list_add_tail(&buf->stream, &queue->mainqueue);
+ list_add_tail(&buf->queue, &queue->irqqueue);
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
+{
+ if (nonblocking) {
+ return (buf->state != UVC_BUF_STATE_QUEUED &&
+ buf->state != UVC_BUF_STATE_ACTIVE)
+ ? 0 : -EAGAIN;
+ }
+
+ return wait_event_interruptible(buf->wait,
+ buf->state != UVC_BUF_STATE_QUEUED &&
+ buf->state != UVC_BUF_STATE_ACTIVE);
+}
+
+/*
+ * Dequeue a video buffer. If nonblocking is false, block until a buffer is
+ * available.
+ */
+int uvc_dequeue_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf, int nonblocking)
+{
+ struct uvc_buffer *buf;
+ int ret = 0;
+
+ if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ v4l2_buf->memory != V4L2_MEMORY_MMAP) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
+ "and/or memory (%u).\n", v4l2_buf->type,
+ v4l2_buf->memory);
+ return -EINVAL;
+ }
+
+ mutex_lock(&queue->mutex);
+ if (list_empty(&queue->mainqueue)) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
+ if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
+ goto done;
+
+ uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
+ buf->buf.index, buf->state, buf->buf.bytesused);
+
+ switch (buf->state) {
+ case UVC_BUF_STATE_ERROR:
+ uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data "
+ "(transmission error).\n");
+ ret = -EIO;
+ case UVC_BUF_STATE_DONE:
+ buf->state = UVC_BUF_STATE_IDLE;
+ break;
+
+ case UVC_BUF_STATE_IDLE:
+ case UVC_BUF_STATE_QUEUED:
+ case UVC_BUF_STATE_ACTIVE:
+ default:
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
+ "(driver bug?).\n", buf->state);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ list_del(&buf->stream);
+ __uvc_query_buffer(buf, v4l2_buf);
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
+ * Poll the video queue.
+ *
+ * This function implements video queue polling and is intended to be used by
+ * the device poll handler.
+ */
+unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
+ poll_table *wait)
+{
+ struct uvc_buffer *buf;
+ unsigned int mask = 0;
+
+ mutex_lock(&queue->mutex);
+ if (list_empty(&queue->mainqueue)) {
+ mask |= POLLERR;
+ goto done;
+ }
+ buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
+
+ poll_wait(file, &buf->wait, wait);
+ if (buf->state == UVC_BUF_STATE_DONE ||
+ buf->state == UVC_BUF_STATE_ERROR)
+ mask |= POLLIN | POLLRDNORM;
+
+done:
+ mutex_unlock(&queue->mutex);
+ return mask;
+}
+
+/*
+ * Enable or disable the video buffers queue.
+ *
+ * The queue must be enabled before starting video acquisition and must be
+ * disabled after stopping it. This ensures that the video buffers queue
+ * state can be properly initialized before buffers are accessed from the
+ * interrupt handler.
+ *
+ * Enabling the video queue initializes parameters (such as sequence number,
+ * sync pattern, ...). If the queue is already enabled, return -EBUSY.
+ *
+ * Disabling the video queue cancels the queue and removes all buffers from
+ * the main queue.
+ *
+ * This function can't be called from interrupt context. Use
+ * uvc_queue_cancel() instead.
+ */
+int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
+{
+ unsigned int i;
+ int ret = 0;
+
+ mutex_lock(&queue->mutex);
+ if (enable) {
+ if (uvc_queue_streaming(queue)) {
+ ret = -EBUSY;
+ goto done;
+ }
+ queue->sequence = 0;
+ queue->flags |= UVC_QUEUE_STREAMING;
+ } else {
+ uvc_queue_cancel(queue, 0);
+ INIT_LIST_HEAD(&queue->mainqueue);
+
+ for (i = 0; i < queue->count; ++i)
+ queue->buffer[i].state = UVC_BUF_STATE_IDLE;
+
+ queue->flags &= ~UVC_QUEUE_STREAMING;
+ }
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
+ * Cancel the video buffers queue.
+ *
+ * Cancelling the queue marks all buffers on the irq queue as erroneous,
+ * wakes them up and remove them from the queue.
+ *
+ * If the disconnect parameter is set, further calls to uvc_queue_buffer will
+ * fail with -ENODEV.
+ *
+ * This function acquires the irq spinlock and can be called from interrupt
+ * context.
+ */
+void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
+{
+ struct uvc_buffer *buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->irqlock, flags);
+ while (!list_empty(&queue->irqqueue)) {
+ buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
+ queue);
+ list_del(&buf->queue);
+ buf->state = UVC_BUF_STATE_ERROR;
+ wake_up(&buf->wait);
+ }
+ /* This must be protected by the irqlock spinlock to avoid race
+ * conditions between uvc_queue_buffer and the disconnection event that
+ * could result in an interruptible wait in uvc_dequeue_buffer. Do not
+ * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
+ * state outside the queue code.
+ */
+ if (disconnect)
+ queue->flags |= UVC_QUEUE_DISCONNECTED;
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+}
+
+struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
+ struct uvc_buffer *buf)
+{
+ struct uvc_buffer *nextbuf;
+ unsigned long flags;
+
+ if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
+ buf->buf.length != buf->buf.bytesused) {
+ buf->state = UVC_BUF_STATE_QUEUED;
+ buf->buf.bytesused = 0;
+ return buf;
+ }
+
+ spin_lock_irqsave(&queue->irqlock, flags);
+ list_del(&buf->queue);
+ if (!list_empty(&queue->irqqueue))
+ nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
+ queue);
+ else
+ nextbuf = NULL;
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+
+ buf->buf.sequence = queue->sequence++;
+ do_gettimeofday(&buf->buf.timestamp);
+
+ wake_up(&buf->wait);
+ return nextbuf;
+}
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
new file mode 100644
index 00000000000..be9084e5eac
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -0,0 +1,207 @@
+/*
+ * uvc_status.c -- USB Video Class driver - Status endpoint
+ *
+ * Copyright (C) 2007-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+
+#include "uvcvideo.h"
+
+/* --------------------------------------------------------------------------
+ * Input device
+ */
+static int uvc_input_init(struct uvc_device *dev)
+{
+ struct usb_device *udev = dev->udev;
+ struct input_dev *input;
+ char *phys = NULL;
+ int ret;
+
+ input = input_allocate_device();
+ if (input == NULL)
+ return -ENOMEM;
+
+ phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
+ GFP_KERNEL);
+ if (phys == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+
+ input->name = dev->name;
+ input->phys = phys;
+ usb_to_input_id(udev, &input->id);
+ input->dev.parent = &dev->intf->dev;
+
+ set_bit(EV_KEY, input->evbit);
+ set_bit(BTN_0, input->keybit);
+
+ if ((ret = input_register_device(input)) < 0)
+ goto error;
+
+ dev->input = input;
+ return 0;
+
+error:
+ input_free_device(input);
+ kfree(phys);
+ return ret;
+}
+
+static void uvc_input_cleanup(struct uvc_device *dev)
+{
+ if (dev->input)
+ input_unregister_device(dev->input);
+}
+
+/* --------------------------------------------------------------------------
+ * Status interrupt endpoint
+ */
+static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
+{
+ if (len < 3) {
+ uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event "
+ "received.\n");
+ return;
+ }
+
+ if (data[2] == 0) {
+ if (len < 4)
+ return;
+ uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
+ data[1], data[3] ? "pressed" : "released", len);
+ if (dev->input)
+ input_report_key(dev->input, BTN_0, data[3]);
+ } else {
+ uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
+ "len %d.\n", data[1], data[2], data[3], len);
+ }
+}
+
+static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len)
+{
+ char *attrs[3] = { "value", "info", "failure" };
+
+ if (len < 6 || data[2] != 0 || data[4] > 2) {
+ uvc_trace(UVC_TRACE_STATUS, "Invalid control status event "
+ "received.\n");
+ return;
+ }
+
+ uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n",
+ data[1], data[3], attrs[data[4]], len);
+}
+
+static void uvc_status_complete(struct urb *urb)
+{
+ struct uvc_device *dev = urb->context;
+ int len, ret;
+
+ switch (urb->status) {
+ case 0:
+ break;
+
+ case -ENOENT: /* usb_kill_urb() called. */
+ case -ECONNRESET: /* usb_unlink_urb() called. */
+ case -ESHUTDOWN: /* The endpoint is being disabled. */
+ case -EPROTO: /* Device is disconnected (reported by some
+ * host controller). */
+ return;
+
+ default:
+ uvc_printk(KERN_WARNING, "Non-zero status (%d) in status "
+ "completion handler.\n", urb->status);
+ return;
+ }
+
+ len = urb->actual_length;
+ if (len > 0) {
+ switch (dev->status[0] & 0x0f) {
+ case UVC_STATUS_TYPE_CONTROL:
+ uvc_event_control(dev, dev->status, len);
+ break;
+
+ case UVC_STATUS_TYPE_STREAMING:
+ uvc_event_streaming(dev, dev->status, len);
+ break;
+
+ default:
+ uvc_printk(KERN_INFO, "unknown event type %u.\n",
+ dev->status[0]);
+ break;
+ }
+ }
+
+ /* Resubmit the URB. */
+ urb->interval = dev->int_ep->desc.bInterval;
+ if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n",
+ ret);
+ }
+}
+
+int uvc_status_init(struct uvc_device *dev)
+{
+ struct usb_host_endpoint *ep = dev->int_ep;
+ unsigned int pipe;
+ int interval;
+
+ if (ep == NULL)
+ return 0;
+
+ uvc_input_init(dev);
+
+ dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (dev->int_urb == NULL)
+ return -ENOMEM;
+
+ pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
+
+ /* For high-speed interrupt endpoints, the bInterval value is used as
+ * an exponent of two. Some developers forgot about it.
+ */
+ interval = ep->desc.bInterval;
+ if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
+ (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
+ interval = fls(interval) - 1;
+
+ usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
+ dev->status, sizeof dev->status, uvc_status_complete,
+ dev, interval);
+
+ return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+}
+
+void uvc_status_cleanup(struct uvc_device *dev)
+{
+ usb_kill_urb(dev->int_urb);
+ usb_free_urb(dev->int_urb);
+ uvc_input_cleanup(dev);
+}
+
+int uvc_status_suspend(struct uvc_device *dev)
+{
+ usb_kill_urb(dev->int_urb);
+ return 0;
+}
+
+int uvc_status_resume(struct uvc_device *dev)
+{
+ if (dev->int_urb == NULL)
+ return 0;
+
+ return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
new file mode 100644
index 00000000000..2e0a66575bb
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -0,0 +1,1105 @@
+/*
+ * uvc_v4l2.c -- USB Video Class driver - V4L2 API
+ *
+ * Copyright (C) 2005-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+
+#include <media/v4l2-common.h>
+
+#include "uvcvideo.h"
+
+/* ------------------------------------------------------------------------
+ * V4L2 interface
+ */
+
+/*
+ * Mapping V4L2 controls to UVC controls can be straighforward if done well.
+ * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
+ * must be grouped (for instance the Red Balance, Blue Balance and Do White
+ * Balance V4L2 controls use the White Balance Component UVC control) or
+ * otherwise translated. The approach we take here is to use a translation
+ * table for the controls which can be mapped directly, and handle the others
+ * manually.
+ */
+static int uvc_v4l2_query_menu(struct uvc_video_device *video,
+ struct v4l2_querymenu *query_menu)
+{
+ struct uvc_menu_info *menu_info;
+ struct uvc_control_mapping *mapping;
+ struct uvc_control *ctrl;
+
+ ctrl = uvc_find_control(video, query_menu->id, &mapping);
+ if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
+ return -EINVAL;
+
+ if (query_menu->index >= mapping->menu_count)
+ return -EINVAL;
+
+ menu_info = &mapping->menu_info[query_menu->index];
+ strncpy(query_menu->name, menu_info->name, 32);
+ return 0;
+}
+
+/*
+ * Find the frame interval closest to the requested frame interval for the
+ * given frame format and size. This should be done by the device as part of
+ * the Video Probe and Commit negotiation, but some hardware don't implement
+ * that feature.
+ */
+static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
+{
+ unsigned int i;
+
+ if (frame->bFrameIntervalType) {
+ __u32 best = -1, dist;
+
+ for (i = 0; i < frame->bFrameIntervalType; ++i) {
+ dist = interval > frame->dwFrameInterval[i]
+ ? interval - frame->dwFrameInterval[i]
+ : frame->dwFrameInterval[i] - interval;
+
+ if (dist > best)
+ break;
+
+ best = dist;
+ }
+
+ interval = frame->dwFrameInterval[i-1];
+ } else {
+ const __u32 min = frame->dwFrameInterval[0];
+ const __u32 max = frame->dwFrameInterval[1];
+ const __u32 step = frame->dwFrameInterval[2];
+
+ interval = min + (interval - min + step/2) / step * step;
+ if (interval > max)
+ interval = max;
+ }
+
+ return interval;
+}
+
+static int uvc_v4l2_try_format(struct uvc_video_device *video,
+ struct v4l2_format *fmt, struct uvc_streaming_control *probe,
+ struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
+{
+ struct uvc_format *format = NULL;
+ struct uvc_frame *frame = NULL;
+ __u16 rw, rh;
+ unsigned int d, maxd;
+ unsigned int i;
+ __u32 interval;
+ int ret = 0;
+ __u8 *fcc;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
+ uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
+ fmt->fmt.pix.pixelformat,
+ fcc[0], fcc[1], fcc[2], fcc[3],
+ fmt->fmt.pix.width, fmt->fmt.pix.height);
+
+ /* Check if the hardware supports the requested format. */
+ for (i = 0; i < video->streaming->nformats; ++i) {
+ format = &video->streaming->format[i];
+ if (format->fcc == fmt->fmt.pix.pixelformat)
+ break;
+ }
+
+ if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
+ uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n",
+ fmt->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ /* Find the closest image size. The distance between image sizes is
+ * the size in pixels of the non-overlapping regions between the
+ * requested size and the frame-specified size.
+ */
+ rw = fmt->fmt.pix.width;
+ rh = fmt->fmt.pix.height;
+ maxd = (unsigned int)-1;
+
+ for (i = 0; i < format->nframes; ++i) {
+ __u16 w = format->frame[i].wWidth;
+ __u16 h = format->frame[i].wHeight;
+
+ d = min(w, rw) * min(h, rh);
+ d = w*h + rw*rh - 2*d;
+ if (d < maxd) {
+ maxd = d;
+ frame = &format->frame[i];
+ }
+
+ if (maxd == 0)
+ break;
+ }
+
+ if (frame == NULL) {
+ uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
+ fmt->fmt.pix.width, fmt->fmt.pix.height);
+ return -EINVAL;
+ }
+
+ /* Use the default frame interval. */
+ interval = frame->dwDefaultFrameInterval;
+ uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
+ "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
+ (100000000/interval)%10);
+
+ /* Set the format index, frame index and frame interval. */
+ memset(probe, 0, sizeof *probe);
+ probe->bmHint = 1; /* dwFrameInterval */
+ probe->bFormatIndex = format->index;
+ probe->bFrameIndex = frame->bFrameIndex;
+ probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
+ /* Some webcams stall the probe control set request when the
+ * dwMaxVideoFrameSize field is set to zero. The UVC specification
+ * clearly states that the field is read-only from the host, so this
+ * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
+ * the webcam to work around the problem.
+ *
+ * The workaround could probably be enabled for all webcams, so the
+ * quirk can be removed if needed. It's currently useful to detect
+ * webcam bugs and fix them before they hit the market (providing
+ * developers test their webcams with the Linux driver as well as with
+ * the Windows driver).
+ */
+ if (video->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
+ probe->dwMaxVideoFrameSize =
+ video->streaming->ctrl.dwMaxVideoFrameSize;
+
+ /* Probe the device */
+ if ((ret = uvc_probe_video(video, probe)) < 0)
+ goto done;
+
+ fmt->fmt.pix.width = frame->wWidth;
+ fmt->fmt.pix.height = frame->wHeight;
+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
+ fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
+ fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
+ fmt->fmt.pix.colorspace = format->colorspace;
+ fmt->fmt.pix.priv = 0;
+
+ if (uvc_format != NULL)
+ *uvc_format = format;
+ if (uvc_frame != NULL)
+ *uvc_frame = frame;
+
+done:
+ return ret;
+}
+
+static int uvc_v4l2_get_format(struct uvc_video_device *video,
+ struct v4l2_format *fmt)
+{
+ struct uvc_format *format = video->streaming->cur_format;
+ struct uvc_frame *frame = video->streaming->cur_frame;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (format == NULL || frame == NULL)
+ return -EINVAL;
+
+ fmt->fmt.pix.pixelformat = format->fcc;
+ fmt->fmt.pix.width = frame->wWidth;
+ fmt->fmt.pix.height = frame->wHeight;
+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
+ fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
+ fmt->fmt.pix.sizeimage = video->streaming->ctrl.dwMaxVideoFrameSize;
+ fmt->fmt.pix.colorspace = format->colorspace;
+ fmt->fmt.pix.priv = 0;
+
+ return 0;
+}
+
+static int uvc_v4l2_set_format(struct uvc_video_device *video,
+ struct v4l2_format *fmt)
+{
+ struct uvc_streaming_control probe;
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+ int ret;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (uvc_queue_streaming(&video->queue))
+ return -EBUSY;
+
+ ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame);
+ if (ret < 0)
+ return ret;
+
+ if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
+ return ret;
+
+ memcpy(&video->streaming->ctrl, &probe, sizeof probe);
+ video->streaming->cur_format = format;
+ video->streaming->cur_frame = frame;
+
+ return 0;
+}
+
+static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
+ struct v4l2_streamparm *parm)
+{
+ uint32_t numerator, denominator;
+
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ numerator = video->streaming->ctrl.dwFrameInterval;
+ denominator = 10000000;
+ uvc_simplify_fraction(&numerator, &denominator, 8, 333);
+
+ memset(parm, 0, sizeof *parm);
+ parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ parm->parm.capture.capturemode = 0;
+ parm->parm.capture.timeperframe.numerator = numerator;
+ parm->parm.capture.timeperframe.denominator = denominator;
+ parm->parm.capture.extendedmode = 0;
+ parm->parm.capture.readbuffers = 0;
+
+ return 0;
+}
+
+static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
+ struct v4l2_streamparm *parm)
+{
+ struct uvc_frame *frame = video->streaming->cur_frame;
+ struct uvc_streaming_control probe;
+ uint32_t interval;
+ int ret;
+
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (uvc_queue_streaming(&video->queue))
+ return -EBUSY;
+
+ memcpy(&probe, &video->streaming->ctrl, sizeof probe);
+ interval = uvc_fraction_to_interval(
+ parm->parm.capture.timeperframe.numerator,
+ parm->parm.capture.timeperframe.denominator);
+
+ uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
+ parm->parm.capture.timeperframe.numerator,
+ parm->parm.capture.timeperframe.denominator,
+ interval);
+ probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
+
+ /* Probe the device with the new settings. */
+ if ((ret = uvc_probe_video(video, &probe)) < 0)
+ return ret;
+
+ /* Commit the new settings. */
+ if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
+ return ret;
+
+ memcpy(&video->streaming->ctrl, &probe, sizeof probe);
+
+ /* Return the actual frame period. */
+ parm->parm.capture.timeperframe.numerator = probe.dwFrameInterval;
+ parm->parm.capture.timeperframe.denominator = 10000000;
+ uvc_simplify_fraction(&parm->parm.capture.timeperframe.numerator,
+ &parm->parm.capture.timeperframe.denominator,
+ 8, 333);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Privilege management
+ */
+
+/*
+ * Privilege management is the multiple-open implementation basis. The current
+ * implementation is completely transparent for the end-user and doesn't
+ * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
+ * Those ioctls enable finer control on the device (by making possible for a
+ * user to request exclusive access to a device), but are not mature yet.
+ * Switching to the V4L2 priority mechanism might be considered in the future
+ * if this situation changes.
+ *
+ * Each open instance of a UVC device can either be in a privileged or
+ * unprivileged state. Only a single instance can be in a privileged state at
+ * a given time. Trying to perform an operation which requires privileges will
+ * automatically acquire the required privileges if possible, or return -EBUSY
+ * otherwise. Privileges are dismissed when closing the instance.
+ *
+ * Operations which require privileges are:
+ *
+ * - VIDIOC_S_INPUT
+ * - VIDIOC_S_PARM
+ * - VIDIOC_S_FMT
+ * - VIDIOC_TRY_FMT
+ * - VIDIOC_REQBUFS
+ */
+static int uvc_acquire_privileges(struct uvc_fh *handle)
+{
+ int ret = 0;
+
+ /* Always succeed if the handle is already privileged. */
+ if (handle->state == UVC_HANDLE_ACTIVE)
+ return 0;
+
+ /* Check if the device already has a privileged handle. */
+ mutex_lock(&uvc_driver.open_mutex);
+ if (atomic_inc_return(&handle->device->active) != 1) {
+ atomic_dec(&handle->device->active);
+ ret = -EBUSY;
+ goto done;
+ }
+
+ handle->state = UVC_HANDLE_ACTIVE;
+
+done:
+ mutex_unlock(&uvc_driver.open_mutex);
+ return ret;
+}
+
+static void uvc_dismiss_privileges(struct uvc_fh *handle)
+{
+ if (handle->state == UVC_HANDLE_ACTIVE)
+ atomic_dec(&handle->device->active);
+
+ handle->state = UVC_HANDLE_PASSIVE;
+}
+
+static int uvc_has_privileges(struct uvc_fh *handle)
+{
+ return handle->state == UVC_HANDLE_ACTIVE;
+}
+
+/* ------------------------------------------------------------------------
+ * V4L2 file operations
+ */
+
+static int uvc_v4l2_open(struct inode *inode, struct file *file)
+{
+ struct video_device *vdev;
+ struct uvc_video_device *video;
+ struct uvc_fh *handle;
+ int ret = 0;
+
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
+ mutex_lock(&uvc_driver.open_mutex);
+ vdev = video_devdata(file);
+ video = video_get_drvdata(vdev);
+
+ if (video->dev->state & UVC_DEV_DISCONNECTED) {
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = usb_autopm_get_interface(video->dev->intf);
+ if (ret < 0)
+ goto done;
+
+ /* Create the device handle. */
+ handle = kzalloc(sizeof *handle, GFP_KERNEL);
+ if (handle == NULL) {
+ usb_autopm_put_interface(video->dev->intf);
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ handle->device = video;
+ handle->state = UVC_HANDLE_PASSIVE;
+ file->private_data = handle;
+
+ kref_get(&video->dev->kref);
+
+done:
+ mutex_unlock(&uvc_driver.open_mutex);
+ return ret;
+}
+
+static int uvc_v4l2_release(struct inode *inode, struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct uvc_video_device *video = video_get_drvdata(vdev);
+ struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
+
+ /* Only free resources if this is a privileged handle. */
+ if (uvc_has_privileges(handle)) {
+ uvc_video_enable(video, 0);
+
+ mutex_lock(&video->queue.mutex);
+ if (uvc_free_buffers(&video->queue) < 0)
+ uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
+ "free buffers.\n");
+ mutex_unlock(&video->queue.mutex);
+ }
+
+ /* Release the file handle. */
+ uvc_dismiss_privileges(handle);
+ kfree(handle);
+ file->private_data = NULL;
+
+ usb_autopm_put_interface(video->dev->intf);
+ kref_put(&video->dev->kref, uvc_delete);
+ return 0;
+}
+
+static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct uvc_video_device *video = video_get_drvdata(vdev);
+ struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+ int ret = 0;
+
+ if (uvc_trace_param & UVC_TRACE_IOCTL)
+ v4l_printk_ioctl(cmd);
+
+ switch (cmd) {
+ /* Query capabilities */
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *cap = arg;
+
+ memset(cap, 0, sizeof *cap);
+ strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
+ strncpy(cap->card, vdev->name, 32);
+ strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
+ sizeof cap->bus_info);
+ cap->version = DRIVER_VERSION_NUMBER;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
+ | V4L2_CAP_STREAMING;
+ break;
+ }
+
+ /* Get, Set & Query control */
+ case VIDIOC_QUERYCTRL:
+ return uvc_query_v4l2_ctrl(video, arg);
+
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ struct v4l2_ext_control xctrl;
+
+ memset(&xctrl, 0, sizeof xctrl);
+ xctrl.id = ctrl->id;
+
+ uvc_ctrl_begin(video);
+ ret = uvc_ctrl_get(video, &xctrl);
+ uvc_ctrl_rollback(video);
+ if (ret >= 0)
+ ctrl->value = xctrl.value;
+ break;
+ }
+
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ struct v4l2_ext_control xctrl;
+
+ memset(&xctrl, 0, sizeof xctrl);
+ xctrl.id = ctrl->id;
+ xctrl.value = ctrl->value;
+
+ uvc_ctrl_begin(video);
+ ret = uvc_ctrl_set(video, &xctrl);
+ if (ret < 0) {
+ uvc_ctrl_rollback(video);
+ return ret;
+ }
+ ret = uvc_ctrl_commit(video);
+ break;
+ }
+
+ case VIDIOC_QUERYMENU:
+ return uvc_v4l2_query_menu(video, arg);
+
+ case VIDIOC_G_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls *ctrls = arg;
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ unsigned int i;
+
+ uvc_ctrl_begin(video);
+ for (i = 0; i < ctrls->count; ++ctrl, ++i) {
+ ret = uvc_ctrl_get(video, ctrl);
+ if (ret < 0) {
+ uvc_ctrl_rollback(video);
+ ctrls->error_idx = i;
+ return ret;
+ }
+ }
+ ctrls->error_idx = 0;
+ ret = uvc_ctrl_rollback(video);
+ break;
+ }
+
+ case VIDIOC_S_EXT_CTRLS:
+ case VIDIOC_TRY_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls *ctrls = arg;
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ unsigned int i;
+
+ ret = uvc_ctrl_begin(video);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ctrls->count; ++ctrl, ++i) {
+ ret = uvc_ctrl_set(video, ctrl);
+ if (ret < 0) {
+ uvc_ctrl_rollback(video);
+ ctrls->error_idx = i;
+ return ret;
+ }
+ }
+
+ ctrls->error_idx = 0;
+
+ if (cmd == VIDIOC_S_EXT_CTRLS)
+ ret = uvc_ctrl_commit(video);
+ else
+ ret = uvc_ctrl_rollback(video);
+ break;
+ }
+
+ /* Get, Set & Enum input */
+ case VIDIOC_ENUMINPUT:
+ {
+ const struct uvc_entity *selector = video->selector;
+ struct v4l2_input *input = arg;
+ struct uvc_entity *iterm = NULL;
+ u32 index = input->index;
+ int pin = 0;
+
+ if (selector == NULL ||
+ (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+ if (index != 0)
+ return -EINVAL;
+ iterm = list_first_entry(&video->iterms,
+ struct uvc_entity, chain);
+ pin = iterm->id;
+ } else if (pin < selector->selector.bNrInPins) {
+ pin = selector->selector.baSourceID[index];
+ list_for_each_entry(iterm, video->iterms.next, chain) {
+ if (iterm->id == pin)
+ break;
+ }
+ }
+
+ if (iterm == NULL || iterm->id != pin)
+ return -EINVAL;
+
+ memset(input, 0, sizeof *input);
+ input->index = index;
+ strncpy(input->name, iterm->name, sizeof input->name);
+ if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ break;
+ }
+
+ case VIDIOC_G_INPUT:
+ {
+ u8 input;
+
+ if (video->selector == NULL ||
+ (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+ *(int *)arg = 0;
+ break;
+ }
+
+ ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id,
+ video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
+ &input, 1);
+ if (ret < 0)
+ return ret;
+
+ *(int *)arg = input - 1;
+ break;
+ }
+
+ case VIDIOC_S_INPUT:
+ {
+ u8 input = *(u32 *)arg + 1;
+
+ if ((ret = uvc_acquire_privileges(handle)) < 0)
+ return ret;
+
+ if (video->selector == NULL ||
+ (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+ if (input != 1)
+ return -EINVAL;
+ break;
+ }
+
+ if (input > video->selector->selector.bNrInPins)
+ return -EINVAL;
+
+ return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
+ video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
+ &input, 1);
+ }
+
+ /* Try, Get, Set & Enum format */
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc *fmt = arg;
+ struct uvc_format *format;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fmt->index >= video->streaming->nformats)
+ return -EINVAL;
+
+ format = &video->streaming->format[fmt->index];
+ fmt->flags = 0;
+ if (format->flags & UVC_FMT_FLAG_COMPRESSED)
+ fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ strncpy(fmt->description, format->name,
+ sizeof fmt->description);
+ fmt->description[sizeof fmt->description - 1] = 0;
+ fmt->pixelformat = format->fcc;
+ break;
+ }
+
+ case VIDIOC_TRY_FMT:
+ {
+ struct uvc_streaming_control probe;
+
+ if ((ret = uvc_acquire_privileges(handle)) < 0)
+ return ret;
+
+ return uvc_v4l2_try_format(video, arg, &probe, NULL, NULL);
+ }
+
+ case VIDIOC_S_FMT:
+ if ((ret = uvc_acquire_privileges(handle)) < 0)
+ return ret;
+
+ return uvc_v4l2_set_format(video, arg);
+
+ case VIDIOC_G_FMT:
+ return uvc_v4l2_get_format(video, arg);
+
+ /* Frame size enumeration */
+ case VIDIOC_ENUM_FRAMESIZES:
+ {
+ struct v4l2_frmsizeenum *fsize = arg;
+ struct uvc_format *format = NULL;
+ struct uvc_frame *frame;
+ int i;
+
+ /* Look for the given pixel format */
+ for (i = 0; i < video->streaming->nformats; i++) {
+ if (video->streaming->format[i].fcc ==
+ fsize->pixel_format) {
+ format = &video->streaming->format[i];
+ break;
+ }
+ }
+ if (format == NULL)
+ return -EINVAL;
+
+ if (fsize->index >= format->nframes)
+ return -EINVAL;
+
+ frame = &format->frame[fsize->index];
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = frame->wWidth;
+ fsize->discrete.height = frame->wHeight;
+ break;
+ }
+
+ /* Frame interval enumeration */
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ {
+ struct v4l2_frmivalenum *fival = arg;
+ struct uvc_format *format = NULL;
+ struct uvc_frame *frame = NULL;
+ int i;
+
+ /* Look for the given pixel format and frame size */
+ for (i = 0; i < video->streaming->nformats; i++) {
+ if (video->streaming->format[i].fcc ==
+ fival->pixel_format) {
+ format = &video->streaming->format[i];
+ break;
+ }
+ }
+ if (format == NULL)
+ return -EINVAL;
+
+ for (i = 0; i < format->nframes; i++) {
+ if (format->frame[i].wWidth == fival->width &&
+ format->frame[i].wHeight == fival->height) {
+ frame = &format->frame[i];
+ break;
+ }
+ }
+ if (frame == NULL)
+ return -EINVAL;
+
+ if (frame->bFrameIntervalType) {
+ if (fival->index >= frame->bFrameIntervalType)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator =
+ frame->dwFrameInterval[fival->index];
+ fival->discrete.denominator = 10000000;
+ uvc_simplify_fraction(&fival->discrete.numerator,
+ &fival->discrete.denominator, 8, 333);
+ } else {
+ fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+ fival->stepwise.min.numerator =
+ frame->dwFrameInterval[0];
+ fival->stepwise.min.denominator = 10000000;
+ fival->stepwise.max.numerator =
+ frame->dwFrameInterval[1];
+ fival->stepwise.max.denominator = 10000000;
+ fival->stepwise.step.numerator =
+ frame->dwFrameInterval[2];
+ fival->stepwise.step.denominator = 10000000;
+ uvc_simplify_fraction(&fival->stepwise.min.numerator,
+ &fival->stepwise.min.denominator, 8, 333);
+ uvc_simplify_fraction(&fival->stepwise.max.numerator,
+ &fival->stepwise.max.denominator, 8, 333);
+ uvc_simplify_fraction(&fival->stepwise.step.numerator,
+ &fival->stepwise.step.denominator, 8, 333);
+ }
+ break;
+ }
+
+ /* Get & Set streaming parameters */
+ case VIDIOC_G_PARM:
+ return uvc_v4l2_get_streamparm(video, arg);
+
+ case VIDIOC_S_PARM:
+ if ((ret = uvc_acquire_privileges(handle)) < 0)
+ return ret;
+
+ return uvc_v4l2_set_streamparm(video, arg);
+
+ /* Cropping and scaling */
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap *ccap = arg;
+ struct uvc_frame *frame = video->streaming->cur_frame;
+
+ if (ccap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ ccap->bounds.left = 0;
+ ccap->bounds.top = 0;
+ ccap->bounds.width = frame->wWidth;
+ ccap->bounds.height = frame->wHeight;
+
+ ccap->defrect = ccap->bounds;
+
+ ccap->pixelaspect.numerator = 1;
+ ccap->pixelaspect.denominator = 1;
+ break;
+ }
+
+ case VIDIOC_G_CROP:
+ case VIDIOC_S_CROP:
+ return -EINVAL;
+
+ /* Buffers & streaming */
+ case VIDIOC_REQBUFS:
+ {
+ struct v4l2_requestbuffers *rb = arg;
+ unsigned int bufsize =
+ video->streaming->ctrl.dwMaxVideoFrameSize;
+
+ if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ rb->memory != V4L2_MEMORY_MMAP)
+ return -EINVAL;
+
+ if ((ret = uvc_acquire_privileges(handle)) < 0)
+ return ret;
+
+ ret = uvc_alloc_buffers(&video->queue, rb->count, bufsize);
+ if (ret < 0)
+ return ret;
+
+ if (!(video->streaming->cur_format->flags &
+ UVC_FMT_FLAG_COMPRESSED))
+ video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
+
+ rb->count = ret;
+ ret = 0;
+ break;
+ }
+
+ case VIDIOC_QUERYBUF:
+ {
+ struct v4l2_buffer *buf = arg;
+
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (!uvc_has_privileges(handle))
+ return -EBUSY;
+
+ return uvc_query_buffer(&video->queue, buf);
+ }
+
+ case VIDIOC_QBUF:
+ if (!uvc_has_privileges(handle))
+ return -EBUSY;
+
+ return uvc_queue_buffer(&video->queue, arg);
+
+ case VIDIOC_DQBUF:
+ if (!uvc_has_privileges(handle))
+ return -EBUSY;
+
+ return uvc_dequeue_buffer(&video->queue, arg,
+ file->f_flags & O_NONBLOCK);
+
+ case VIDIOC_STREAMON:
+ {
+ int *type = arg;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (!uvc_has_privileges(handle))
+ return -EBUSY;
+
+ if ((ret = uvc_video_enable(video, 1)) < 0)
+ return ret;
+ break;
+ }
+
+ case VIDIOC_STREAMOFF:
+ {
+ int *type = arg;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (!uvc_has_privileges(handle))
+ return -EBUSY;
+
+ return uvc_video_enable(video, 0);
+ }
+
+ /* Analog video standards make no sense for digital cameras. */
+ case VIDIOC_ENUMSTD:
+ case VIDIOC_QUERYSTD:
+ case VIDIOC_G_STD:
+ case VIDIOC_S_STD:
+
+ case VIDIOC_OVERLAY:
+
+ case VIDIOC_ENUMAUDIO:
+ case VIDIOC_ENUMAUDOUT:
+
+ case VIDIOC_ENUMOUTPUT:
+ uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
+ return -EINVAL;
+
+ /* Dynamic controls. */
+ case UVCIOC_CTRL_ADD:
+ {
+ struct uvc_xu_control_info *xinfo = arg;
+ struct uvc_control_info *info;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ info = kmalloc(sizeof *info, GFP_KERNEL);
+ if (info == NULL)
+ return -ENOMEM;
+
+ memcpy(info->entity, xinfo->entity, sizeof info->entity);
+ info->index = xinfo->index;
+ info->selector = xinfo->selector;
+ info->size = xinfo->size;
+ info->flags = xinfo->flags;
+
+ info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
+ UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF;
+
+ ret = uvc_ctrl_add_info(info);
+ if (ret < 0)
+ kfree(info);
+ break;
+ }
+
+ case UVCIOC_CTRL_MAP:
+ {
+ struct uvc_xu_control_mapping *xmap = arg;
+ struct uvc_control_mapping *map;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ map = kmalloc(sizeof *map, GFP_KERNEL);
+ if (map == NULL)
+ return -ENOMEM;
+
+ map->id = xmap->id;
+ memcpy(map->name, xmap->name, sizeof map->name);
+ memcpy(map->entity, xmap->entity, sizeof map->entity);
+ map->selector = xmap->selector;
+ map->size = xmap->size;
+ map->offset = xmap->offset;
+ map->v4l2_type = xmap->v4l2_type;
+ map->data_type = xmap->data_type;
+
+ ret = uvc_ctrl_add_mapping(map);
+ if (ret < 0)
+ kfree(map);
+ break;
+ }
+
+ case UVCIOC_CTRL_GET:
+ return uvc_xu_ctrl_query(video, arg, 0);
+
+ case UVCIOC_CTRL_SET:
+ return uvc_xu_ctrl_query(video, arg, 1);
+
+ default:
+ if ((ret = v4l_compat_translate_ioctl(inode, file, cmd, arg,
+ uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
+ uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
+ cmd);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int uvc_v4l2_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_ioctl\n");
+ return video_usercopy(inode, file, cmd, arg, uvc_v4l2_do_ioctl);
+}
+
+static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
+ return -ENODEV;
+}
+
+/*
+ * VMA operations.
+ */
+static void uvc_vm_open(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count++;
+}
+
+static void uvc_vm_close(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count--;
+}
+
+static struct vm_operations_struct uvc_vm_ops = {
+ .open = uvc_vm_open,
+ .close = uvc_vm_close,
+};
+
+static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct uvc_video_device *video = video_get_drvdata(vdev);
+ struct uvc_buffer *buffer;
+ struct page *page;
+ unsigned long addr, start, size;
+ unsigned int i;
+ int ret = 0;
+
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
+
+ start = vma->vm_start;
+ size = vma->vm_end - vma->vm_start;
+
+ mutex_lock(&video->queue.mutex);
+
+ for (i = 0; i < video->queue.count; ++i) {
+ buffer = &video->queue.buffer[i];
+ if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+ break;
+ }
+
+ if (i == video->queue.count || size != video->queue.buf_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /*
+ * VM_IO marks the area as being an mmaped region for I/O to a
+ * device. It also prevents the region from being core dumped.
+ */
+ vma->vm_flags |= VM_IO;
+
+ addr = (unsigned long)video->queue.mem + buffer->buf.m.offset;
+ while (size > 0) {
+ page = vmalloc_to_page((void *)addr);
+ if ((ret = vm_insert_page(vma, start, page)) < 0)
+ goto done;
+
+ start += PAGE_SIZE;
+ addr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vma->vm_ops = &uvc_vm_ops;
+ vma->vm_private_data = buffer;
+ uvc_vm_open(vma);
+
+done:
+ mutex_unlock(&video->queue.mutex);
+ return ret;
+}
+
+static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct uvc_video_device *video = video_get_drvdata(vdev);
+
+ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
+
+ return uvc_queue_poll(&video->queue, file, wait);
+}
+
+struct file_operations uvc_fops = {
+ .owner = THIS_MODULE,
+ .open = uvc_v4l2_open,
+ .release = uvc_v4l2_release,
+ .ioctl = uvc_v4l2_ioctl,
+ .compat_ioctl = v4l_compat_ioctl32,
+ .llseek = no_llseek,
+ .read = uvc_v4l2_read,
+ .mmap = uvc_v4l2_mmap,
+ .poll = uvc_v4l2_poll,
+};
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
new file mode 100644
index 00000000000..6faf1fb2161
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -0,0 +1,934 @@
+/*
+ * uvc_video.c -- USB Video Class driver - Video handling
+ *
+ * Copyright (C) 2005-2008
+ * Laurent Pinchart (laurent.pinchart@skynet.be)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+#include <asm/unaligned.h>
+
+#include <media/v4l2-common.h>
+
+#include "uvcvideo.h"
+
+/* ------------------------------------------------------------------------
+ * UVC Controls
+ */
+
+static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
+ __u8 intfnum, __u8 cs, void *data, __u16 size,
+ int timeout)
+{
+ __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+ unsigned int pipe;
+ int ret;
+
+ pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
+ : usb_sndctrlpipe(dev->udev, 0);
+ type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
+
+ ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8,
+ unit << 8 | intfnum, data, size, timeout);
+
+ if (ret != size) {
+ uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
+ "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
+ size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
+ __u8 intfnum, __u8 cs, void *data, __u16 size)
+{
+ return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
+ UVC_CTRL_CONTROL_TIMEOUT);
+}
+
+static void uvc_fixup_buffer_size(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl)
+{
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+
+ if (ctrl->bFormatIndex <= 0 ||
+ ctrl->bFormatIndex > video->streaming->nformats)
+ return;
+
+ format = &video->streaming->format[ctrl->bFormatIndex - 1];
+
+ if (ctrl->bFrameIndex <= 0 ||
+ ctrl->bFrameIndex > format->nframes)
+ return;
+
+ frame = &format->frame[ctrl->bFrameIndex - 1];
+
+ if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
+ (ctrl->dwMaxVideoFrameSize == 0 &&
+ video->dev->uvc_version < 0x0110))
+ ctrl->dwMaxVideoFrameSize =
+ frame->dwMaxVideoFrameBufferSize;
+}
+
+static int uvc_get_video_ctrl(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl, int probe, __u8 query)
+{
+ __u8 data[34];
+ __u8 size;
+ int ret;
+
+ size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
+ ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
+ probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
+ UVC_CTRL_STREAMING_TIMEOUT);
+
+ if (ret < 0)
+ return ret;
+
+ ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
+ ctrl->bFormatIndex = data[2];
+ ctrl->bFrameIndex = data[3];
+ ctrl->dwFrameInterval = le32_to_cpup((__le32 *)&data[4]);
+ ctrl->wKeyFrameRate = le16_to_cpup((__le16 *)&data[8]);
+ ctrl->wPFrameRate = le16_to_cpup((__le16 *)&data[10]);
+ ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]);
+ ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]);
+ ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]);
+ ctrl->dwMaxVideoFrameSize =
+ le32_to_cpu(get_unaligned((__le32 *)&data[18]));
+ ctrl->dwMaxPayloadTransferSize =
+ le32_to_cpu(get_unaligned((__le32 *)&data[22]));
+
+ if (size == 34) {
+ ctrl->dwClockFrequency =
+ le32_to_cpu(get_unaligned((__le32 *)&data[26]));
+ ctrl->bmFramingInfo = data[30];
+ ctrl->bPreferedVersion = data[31];
+ ctrl->bMinVersion = data[32];
+ ctrl->bMaxVersion = data[33];
+ } else {
+ ctrl->dwClockFrequency = video->dev->clock_frequency;
+ ctrl->bmFramingInfo = 0;
+ ctrl->bPreferedVersion = 0;
+ ctrl->bMinVersion = 0;
+ ctrl->bMaxVersion = 0;
+ }
+
+ /* Some broken devices return a null or wrong dwMaxVideoFrameSize.
+ * Try to get the value from the format and frame descriptor.
+ */
+ uvc_fixup_buffer_size(video, ctrl);
+
+ return 0;
+}
+
+int uvc_set_video_ctrl(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl, int probe)
+{
+ __u8 data[34];
+ __u8 size;
+
+ size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
+ memset(data, 0, sizeof data);
+
+ *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
+ data[2] = ctrl->bFormatIndex;
+ data[3] = ctrl->bFrameIndex;
+ *(__le32 *)&data[4] = cpu_to_le32(ctrl->dwFrameInterval);
+ *(__le16 *)&data[8] = cpu_to_le16(ctrl->wKeyFrameRate);
+ *(__le16 *)&data[10] = cpu_to_le16(ctrl->wPFrameRate);
+ *(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
+ *(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
+ *(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
+ /* Note: Some of the fields below are not required for IN devices (see
+ * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
+ * devices is added in the future. */
+ put_unaligned(cpu_to_le32(ctrl->dwMaxVideoFrameSize),
+ (__le32 *)&data[18]);
+ put_unaligned(cpu_to_le32(ctrl->dwMaxPayloadTransferSize),
+ (__le32 *)&data[22]);
+
+ if (size == 34) {
+ put_unaligned(cpu_to_le32(ctrl->dwClockFrequency),
+ (__le32 *)&data[26]);
+ data[30] = ctrl->bmFramingInfo;
+ data[31] = ctrl->bPreferedVersion;
+ data[32] = ctrl->bMinVersion;
+ data[33] = ctrl->bMaxVersion;
+ }
+
+ return __uvc_query_ctrl(video->dev, SET_CUR, 0,
+ video->streaming->intfnum,
+ probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
+ UVC_CTRL_STREAMING_TIMEOUT);
+}
+
+int uvc_probe_video(struct uvc_video_device *video,
+ struct uvc_streaming_control *probe)
+{
+ struct uvc_streaming_control probe_min, probe_max;
+ __u16 bandwidth;
+ unsigned int i;
+ int ret;
+
+ mutex_lock(&video->streaming->mutex);
+
+ /* Perform probing. The device should adjust the requested values
+ * according to its capabilities. However, some devices, namely the
+ * first generation UVC Logitech webcams, don't implement the Video
+ * Probe control properly, and just return the needed bandwidth. For
+ * that reason, if the needed bandwidth exceeds the maximum available
+ * bandwidth, try to lower the quality.
+ */
+ if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0)
+ goto done;
+
+ /* Get the minimum and maximum values for compression settings. */
+ if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) {
+ ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN);
+ if (ret < 0)
+ goto done;
+ ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX);
+ if (ret < 0)
+ goto done;
+
+ probe->wCompQuality = probe_max.wCompQuality;
+ }
+
+ for (i = 0; i < 2; ++i) {
+ if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0 ||
+ (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+ goto done;
+
+ if (video->streaming->intf->num_altsetting == 1)
+ break;
+
+ bandwidth = probe->dwMaxPayloadTransferSize;
+ if (bandwidth <= video->streaming->maxpsize)
+ break;
+
+ if (video->dev->quirks & UVC_QUIRK_PROBE_MINMAX) {
+ ret = -ENOSPC;
+ goto done;
+ }
+
+ /* TODO: negotiate compression parameters */
+ probe->wKeyFrameRate = probe_min.wKeyFrameRate;
+ probe->wPFrameRate = probe_min.wPFrameRate;
+ probe->wCompQuality = probe_max.wCompQuality;
+ probe->wCompWindowSize = probe_min.wCompWindowSize;
+ }
+
+done:
+ mutex_unlock(&video->streaming->mutex);
+ return ret;
+}
+
+/* ------------------------------------------------------------------------
+ * Video codecs
+ */
+
+/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
+#define UVC_STREAM_EOH (1 << 7)
+#define UVC_STREAM_ERR (1 << 6)
+#define UVC_STREAM_STI (1 << 5)
+#define UVC_STREAM_RES (1 << 4)
+#define UVC_STREAM_SCR (1 << 3)
+#define UVC_STREAM_PTS (1 << 2)
+#define UVC_STREAM_EOF (1 << 1)
+#define UVC_STREAM_FID (1 << 0)
+
+/* Video payload decoding is handled by uvc_video_decode_start(),
+ * uvc_video_decode_data() and uvc_video_decode_end().
+ *
+ * uvc_video_decode_start is called with URB data at the start of a bulk or
+ * isochronous payload. It processes header data and returns the header size
+ * in bytes if successful. If an error occurs, it returns a negative error
+ * code. The following error codes have special meanings.
+ *
+ * - EAGAIN informs the caller that the current video buffer should be marked
+ * as done, and that the function should be called again with the same data
+ * and a new video buffer. This is used when end of frame conditions can be
+ * reliably detected at the beginning of the next frame only.
+ *
+ * If an error other than -EAGAIN is returned, the caller will drop the current
+ * payload. No call to uvc_video_decode_data and uvc_video_decode_end will be
+ * made until the next payload. -ENODATA can be used to drop the current
+ * payload if no other error code is appropriate.
+ *
+ * uvc_video_decode_data is called for every URB with URB data. It copies the
+ * data to the video buffer.
+ *
+ * uvc_video_decode_end is called with header data at the end of a bulk or
+ * isochronous payload. It performs any additional header data processing and
+ * returns 0 or a negative error code if an error occured. As header data have
+ * already been processed by uvc_video_decode_start, this functions isn't
+ * required to perform sanity checks a second time.
+ *
+ * For isochronous transfers where a payload is always transfered in a single
+ * URB, the three functions will be called in a row.
+ *
+ * To let the decoder process header data and update its internal state even
+ * when no video buffer is available, uvc_video_decode_start must be prepared
+ * to be called with a NULL buf parameter. uvc_video_decode_data and
+ * uvc_video_decode_end will never be called with a NULL buffer.
+ */
+static int uvc_video_decode_start(struct uvc_video_device *video,
+ struct uvc_buffer *buf, const __u8 *data, int len)
+{
+ __u8 fid;
+
+ /* Sanity checks:
+ * - packet must be at least 2 bytes long
+ * - bHeaderLength value must be at least 2 bytes (see above)
+ * - bHeaderLength value can't be larger than the packet size.
+ */
+ if (len < 2 || data[0] < 2 || data[0] > len)
+ return -EINVAL;
+
+ /* Skip payloads marked with the error bit ("error frames"). */
+ if (data[1] & UVC_STREAM_ERR) {
+ uvc_trace(UVC_TRACE_FRAME, "Dropping payload (error bit "
+ "set).\n");
+ return -ENODATA;
+ }
+
+ fid = data[1] & UVC_STREAM_FID;
+
+ /* Store the payload FID bit and return immediately when the buffer is
+ * NULL.
+ */
+ if (buf == NULL) {
+ video->last_fid = fid;
+ return -ENODATA;
+ }
+
+ /* Synchronize to the input stream by waiting for the FID bit to be
+ * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
+ * queue->last_fid is initialized to -1, so the first isochronous
+ * frame will always be in sync.
+ *
+ * If the device doesn't toggle the FID bit, invert video->last_fid
+ * when the EOF bit is set to force synchronisation on the next packet.
+ */
+ if (buf->state != UVC_BUF_STATE_ACTIVE) {
+ if (fid == video->last_fid) {
+ uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
+ "sync).\n");
+ if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) &&
+ (data[1] & UVC_STREAM_EOF))
+ video->last_fid ^= UVC_STREAM_FID;
+ return -ENODATA;
+ }
+
+ /* TODO: Handle PTS and SCR. */
+ buf->state = UVC_BUF_STATE_ACTIVE;
+ }
+
+ /* Mark the buffer as done if we're at the beginning of a new frame.
+ * End of frame detection is better implemented by checking the EOF
+ * bit (FID bit toggling is delayed by one frame compared to the EOF
+ * bit), but some devices don't set the bit at end of frame (and the
+ * last payload can be lost anyway). We thus must check if the FID has
+ * been toggled.
+ *
+ * queue->last_fid is initialized to -1, so the first isochronous
+ * frame will never trigger an end of frame detection.
+ *
+ * Empty buffers (bytesused == 0) don't trigger end of frame detection
+ * as it doesn't make sense to return an empty buffer. This also
+ * avoids detecting and of frame conditions at FID toggling if the
+ * previous payload had the EOF bit set.
+ */
+ if (fid != video->last_fid && buf->buf.bytesused != 0) {
+ uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
+ "toggled).\n");
+ buf->state = UVC_BUF_STATE_DONE;
+ return -EAGAIN;
+ }
+
+ video->last_fid = fid;
+
+ return data[0];
+}
+
+static void uvc_video_decode_data(struct uvc_video_device *video,
+ struct uvc_buffer *buf, const __u8 *data, int len)
+{
+ struct uvc_video_queue *queue = &video->queue;
+ unsigned int maxlen, nbytes;
+ void *mem;
+
+ if (len <= 0)
+ return;
+
+ /* Copy the video data to the buffer. */
+ maxlen = buf->buf.length - buf->buf.bytesused;
+ mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+ nbytes = min((unsigned int)len, maxlen);
+ memcpy(mem, data, nbytes);
+ buf->buf.bytesused += nbytes;
+
+ /* Complete the current frame if the buffer size was exceeded. */
+ if (len > maxlen) {
+ uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
+ buf->state = UVC_BUF_STATE_DONE;
+ }
+}
+
+static void uvc_video_decode_end(struct uvc_video_device *video,
+ struct uvc_buffer *buf, const __u8 *data, int len)
+{
+ /* Mark the buffer as done if the EOF marker is set. */
+ if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) {
+ uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
+ if (data[0] == len)
+ uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
+ buf->state = UVC_BUF_STATE_DONE;
+ if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
+ video->last_fid ^= UVC_STREAM_FID;
+ }
+}
+
+/* ------------------------------------------------------------------------
+ * URB handling
+ */
+
+/*
+ * Completion handler for video URBs.
+ */
+static void uvc_video_decode_isoc(struct urb *urb,
+ struct uvc_video_device *video, struct uvc_buffer *buf)
+{
+ u8 *mem;
+ int ret, i;
+
+ for (i = 0; i < urb->number_of_packets; ++i) {
+ if (urb->iso_frame_desc[i].status < 0) {
+ uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame "
+ "lost (%d).\n", urb->iso_frame_desc[i].status);
+ continue;
+ }
+
+ /* Decode the payload header. */
+ mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ do {
+ ret = uvc_video_decode_start(video, buf, mem,
+ urb->iso_frame_desc[i].actual_length);
+ if (ret == -EAGAIN)
+ buf = uvc_queue_next_buffer(&video->queue, buf);
+ } while (ret == -EAGAIN);
+
+ if (ret < 0)
+ continue;
+
+ /* Decode the payload data. */
+ uvc_video_decode_data(video, buf, mem + ret,
+ urb->iso_frame_desc[i].actual_length - ret);
+
+ /* Process the header again. */
+ uvc_video_decode_end(video, buf, mem, ret);
+
+ if (buf->state == UVC_BUF_STATE_DONE ||
+ buf->state == UVC_BUF_STATE_ERROR)
+ buf = uvc_queue_next_buffer(&video->queue, buf);
+ }
+}
+
+static void uvc_video_decode_bulk(struct urb *urb,
+ struct uvc_video_device *video, struct uvc_buffer *buf)
+{
+ u8 *mem;
+ int len, ret;
+
+ mem = urb->transfer_buffer;
+ len = urb->actual_length;
+ video->bulk.payload_size += len;
+
+ /* If the URB is the first of its payload, decode and save the
+ * header.
+ */
+ if (video->bulk.header_size == 0) {
+ do {
+ ret = uvc_video_decode_start(video, buf, mem, len);
+ if (ret == -EAGAIN)
+ buf = uvc_queue_next_buffer(&video->queue, buf);
+ } while (ret == -EAGAIN);
+
+ /* If an error occured skip the rest of the payload. */
+ if (ret < 0 || buf == NULL) {
+ video->bulk.skip_payload = 1;
+ return;
+ }
+
+ video->bulk.header_size = ret;
+ memcpy(video->bulk.header, mem, video->bulk.header_size);
+
+ mem += ret;
+ len -= ret;
+ }
+
+ /* The buffer queue might have been cancelled while a bulk transfer
+ * was in progress, so we can reach here with buf equal to NULL. Make
+ * sure buf is never dereferenced if NULL.
+ */
+
+ /* Process video data. */
+ if (!video->bulk.skip_payload && buf != NULL)
+ uvc_video_decode_data(video, buf, mem, len);
+
+ /* Detect the payload end by a URB smaller than the maximum size (or
+ * a payload size equal to the maximum) and process the header again.
+ */
+ if (urb->actual_length < urb->transfer_buffer_length ||
+ video->bulk.payload_size >= video->bulk.max_payload_size) {
+ if (!video->bulk.skip_payload && buf != NULL) {
+ uvc_video_decode_end(video, buf, video->bulk.header,
+ video->bulk.header_size);
+ if (buf->state == UVC_BUF_STATE_DONE ||
+ buf->state == UVC_BUF_STATE_ERROR)
+ buf = uvc_queue_next_buffer(&video->queue, buf);
+ }
+
+ video->bulk.header_size = 0;
+ video->bulk.skip_payload = 0;
+ video->bulk.payload_size = 0;
+ }
+}
+
+static void uvc_video_complete(struct urb *urb)
+{
+ struct uvc_video_device *video = urb->context;
+ struct uvc_video_queue *queue = &video->queue;
+ struct uvc_buffer *buf = NULL;
+ unsigned long flags;
+ int ret;
+
+ switch (urb->status) {
+ case 0:
+ break;
+
+ default:
+ uvc_printk(KERN_WARNING, "Non-zero status (%d) in video "
+ "completion handler.\n", urb->status);
+
+ case -ENOENT: /* usb_kill_urb() called. */
+ if (video->frozen)
+ return;
+
+ case -ECONNRESET: /* usb_unlink_urb() called. */
+ case -ESHUTDOWN: /* The endpoint is being disabled. */
+ uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
+ return;
+ }
+
+ spin_lock_irqsave(&queue->irqlock, flags);
+ if (!list_empty(&queue->irqqueue))
+ buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
+ queue);
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+
+ video->decode(urb, video, buf);
+
+ if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
+ ret);
+ }
+}
+
+/*
+ * Uninitialize isochronous/bulk URBs and free transfer buffers.
+ */
+static void uvc_uninit_video(struct uvc_video_device *video)
+{
+ struct urb *urb;
+ unsigned int i;
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ if ((urb = video->urb[i]) == NULL)
+ continue;
+
+ usb_kill_urb(urb);
+ /* urb->transfer_buffer_length is not touched by USB core, so
+ * we can use it here as the buffer length.
+ */
+ if (video->urb_buffer[i]) {
+ usb_buffer_free(video->dev->udev,
+ urb->transfer_buffer_length,
+ video->urb_buffer[i], urb->transfer_dma);
+ video->urb_buffer[i] = NULL;
+ }
+
+ usb_free_urb(urb);
+ video->urb[i] = NULL;
+ }
+}
+
+/*
+ * Initialize isochronous URBs and allocate transfer buffers. The packet size
+ * is given by the endpoint.
+ */
+static int uvc_init_video_isoc(struct uvc_video_device *video,
+ struct usb_host_endpoint *ep)
+{
+ struct urb *urb;
+ unsigned int npackets, i, j;
+ __u16 psize;
+ __u32 size;
+
+ /* Compute the number of isochronous packets to allocate by dividing
+ * the maximum video frame size by the packet size. Limit the result
+ * to UVC_MAX_ISO_PACKETS.
+ */
+ psize = le16_to_cpu(ep->desc.wMaxPacketSize);
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+
+ size = video->streaming->ctrl.dwMaxVideoFrameSize;
+ if (size > UVC_MAX_FRAME_SIZE)
+ return -EINVAL;
+
+ npackets = (size + psize - 1) / psize;
+ if (npackets > UVC_MAX_ISO_PACKETS)
+ npackets = UVC_MAX_ISO_PACKETS;
+
+ size = npackets * psize;
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ urb = usb_alloc_urb(npackets, GFP_KERNEL);
+ if (urb == NULL) {
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+ size, GFP_KERNEL, &urb->transfer_dma);
+ if (video->urb_buffer[i] == NULL) {
+ usb_free_urb(urb);
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ urb->dev = video->dev->udev;
+ urb->context = video;
+ urb->pipe = usb_rcvisocpipe(video->dev->udev,
+ ep->desc.bEndpointAddress);
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = ep->desc.bInterval;
+ urb->transfer_buffer = video->urb_buffer[i];
+ urb->complete = uvc_video_complete;
+ urb->number_of_packets = npackets;
+ urb->transfer_buffer_length = size;
+
+ for (j = 0; j < npackets; ++j) {
+ urb->iso_frame_desc[j].offset = j * psize;
+ urb->iso_frame_desc[j].length = psize;
+ }
+
+ video->urb[i] = urb;
+ }
+
+ return 0;
+}
+
+/*
+ * Initialize bulk URBs and allocate transfer buffers. The packet size is
+ * given by the endpoint.
+ */
+static int uvc_init_video_bulk(struct uvc_video_device *video,
+ struct usb_host_endpoint *ep)
+{
+ struct urb *urb;
+ unsigned int pipe, i;
+ __u16 psize;
+ __u32 size;
+
+ /* Compute the bulk URB size. Some devices set the maximum payload
+ * size to a value too high for memory-constrained devices. We must
+ * then transfer the payload accross multiple URBs. To be consistant
+ * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
+ * URB.
+ */
+ psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
+ size = video->streaming->ctrl.dwMaxPayloadTransferSize;
+ video->bulk.max_payload_size = size;
+ if (size > psize * UVC_MAX_ISO_PACKETS)
+ size = psize * UVC_MAX_ISO_PACKETS;
+
+ pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (urb == NULL) {
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+ size, GFP_KERNEL, &urb->transfer_dma);
+ if (video->urb_buffer[i] == NULL) {
+ usb_free_urb(urb);
+ uvc_uninit_video(video);
+ return -ENOMEM;
+ }
+
+ usb_fill_bulk_urb(urb, video->dev->udev, pipe,
+ video->urb_buffer[i], size, uvc_video_complete,
+ video);
+ urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+
+ video->urb[i] = urb;
+ }
+
+ return 0;
+}
+
+/*
+ * Initialize isochronous/bulk URBs and allocate transfer buffers.
+ */
+static int uvc_init_video(struct uvc_video_device *video)
+{
+ struct usb_interface *intf = video->streaming->intf;
+ struct usb_host_interface *alts;
+ struct usb_host_endpoint *ep = NULL;
+ int intfnum = video->streaming->intfnum;
+ unsigned int bandwidth, psize, i;
+ int ret;
+
+ video->last_fid = -1;
+ video->bulk.header_size = 0;
+ video->bulk.skip_payload = 0;
+ video->bulk.payload_size = 0;
+
+ if (intf->num_altsetting > 1) {
+ /* Isochronous endpoint, select the alternate setting. */
+ bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize;
+
+ if (bandwidth == 0) {
+ uvc_printk(KERN_WARNING, "device %s requested null "
+ "bandwidth, defaulting to lowest.\n",
+ video->vdev->name);
+ bandwidth = 1;
+ }
+
+ for (i = 0; i < intf->num_altsetting; ++i) {
+ alts = &intf->altsetting[i];
+ ep = uvc_find_endpoint(alts,
+ video->streaming->header.bEndpointAddress);
+ if (ep == NULL)
+ continue;
+
+ /* Check if the bandwidth is high enough. */
+ psize = le16_to_cpu(ep->desc.wMaxPacketSize);
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ if (psize >= bandwidth)
+ break;
+ }
+
+ if (i >= intf->num_altsetting)
+ return -EIO;
+
+ if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0)
+ return ret;
+
+ ret = uvc_init_video_isoc(video, ep);
+ } else {
+ /* Bulk endpoint, proceed to URB initialization. */
+ ep = uvc_find_endpoint(&intf->altsetting[0],
+ video->streaming->header.bEndpointAddress);
+ if (ep == NULL)
+ return -EIO;
+
+ ret = uvc_init_video_bulk(video, ep);
+ }
+
+ if (ret < 0)
+ return ret;
+
+ /* Submit the URBs. */
+ for (i = 0; i < UVC_URBS; ++i) {
+ if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) {
+ uvc_printk(KERN_ERR, "Failed to submit URB %u "
+ "(%d).\n", i, ret);
+ uvc_uninit_video(video);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------------
+ * Suspend/resume
+ */
+
+/*
+ * Stop streaming without disabling the video queue.
+ *
+ * To let userspace applications resume without trouble, we must not touch the
+ * video buffers in any way. We mark the device as frozen to make sure the URB
+ * completion handler won't try to cancel the queue when we kill the URBs.
+ */
+int uvc_video_suspend(struct uvc_video_device *video)
+{
+ if (!uvc_queue_streaming(&video->queue))
+ return 0;
+
+ video->frozen = 1;
+ uvc_uninit_video(video);
+ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
+ return 0;
+}
+
+/*
+ * Reconfigure the video interface and restart streaming if it was enable
+ * before suspend.
+ *
+ * If an error occurs, disable the video queue. This will wake all pending
+ * buffers, making sure userspace applications are notified of the problem
+ * instead of waiting forever.
+ */
+int uvc_video_resume(struct uvc_video_device *video)
+{
+ int ret;
+
+ video->frozen = 0;
+
+ if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) {
+ uvc_queue_enable(&video->queue, 0);
+ return ret;
+ }
+
+ if (!uvc_queue_streaming(&video->queue))
+ return 0;
+
+ if ((ret = uvc_init_video(video)) < 0)
+ uvc_queue_enable(&video->queue, 0);
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------
+ * Video device
+ */
+
+/*
+ * Initialize the UVC video device by retrieving the default format and
+ * committing it.
+ *
+ * Some cameras (namely the Fuji Finepix) set the format and frame
+ * indexes to zero. The UVC standard doesn't clearly make this a spec
+ * violation, so try to silently fix the values if possible.
+ *
+ * This function is called before registering the device with V4L.
+ */
+int uvc_video_init(struct uvc_video_device *video)
+{
+ struct uvc_streaming_control *probe = &video->streaming->ctrl;
+ struct uvc_format *format = NULL;
+ struct uvc_frame *frame = NULL;
+ unsigned int i;
+ int ret;
+
+ if (video->streaming->nformats == 0) {
+ uvc_printk(KERN_INFO, "No supported video formats found.\n");
+ return -EINVAL;
+ }
+
+ /* Alternate setting 0 should be the default, yet the XBox Live Vision
+ * Cam (and possibly other devices) crash or otherwise misbehave if
+ * they don't receive a SET_INTERFACE request before any other video
+ * control request.
+ */
+ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
+
+ /* Some webcams don't suport GET_DEF request on the probe control. We
+ * fall back to GET_CUR if GET_DEF fails.
+ */
+ if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
+ (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+ return ret;
+
+ /* Check if the default format descriptor exists. Use the first
+ * available format otherwise.
+ */
+ for (i = video->streaming->nformats; i > 0; --i) {
+ format = &video->streaming->format[i-1];
+ if (format->index == probe->bFormatIndex)
+ break;
+ }
+
+ if (format->nframes == 0) {
+ uvc_printk(KERN_INFO, "No frame descriptor found for the "
+ "default format.\n");
+ return -EINVAL;
+ }
+
+ /* Zero bFrameIndex might be correct. Stream-based formats (including
+ * MPEG-2 TS and DV) do not support frames but have a dummy frame
+ * descriptor with bFrameIndex set to zero. If the default frame
+ * descriptor is not found, use the first avalable frame.
+ */
+ for (i = format->nframes; i > 0; --i) {
+ frame = &format->frame[i-1];
+ if (frame->bFrameIndex == probe->bFrameIndex)
+ break;
+ }
+
+ /* Commit the default settings. */
+ probe->bFormatIndex = format->index;
+ probe->bFrameIndex = frame->bFrameIndex;
+ if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
+ return ret;
+
+ video->streaming->cur_format = format;
+ video->streaming->cur_frame = frame;
+ atomic_set(&video->active, 0);
+
+ /* Select the video decoding function */
+ if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
+ video->decode = uvc_video_decode_isight;
+ else if (video->streaming->intf->num_altsetting > 1)
+ video->decode = uvc_video_decode_isoc;
+ else
+ video->decode = uvc_video_decode_bulk;
+
+ return 0;
+}
+
+/*
+ * Enable or disable the video stream.
+ */
+int uvc_video_enable(struct uvc_video_device *video, int enable)
+{
+ int ret;
+
+ if (!enable) {
+ uvc_uninit_video(video);
+ usb_set_interface(video->dev->udev,
+ video->streaming->intfnum, 0);
+ uvc_queue_enable(&video->queue, 0);
+ return 0;
+ }
+
+ if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
+ return ret;
+
+ return uvc_init_video(video);
+}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
new file mode 100644
index 00000000000..a995a780db1
--- /dev/null
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -0,0 +1,796 @@
+#ifndef _USB_VIDEO_H_
+#define _USB_VIDEO_H_
+
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+
+
+/*
+ * Dynamic controls
+ */
+
+/* Data types for UVC control data */
+#define UVC_CTRL_DATA_TYPE_RAW 0
+#define UVC_CTRL_DATA_TYPE_SIGNED 1
+#define UVC_CTRL_DATA_TYPE_UNSIGNED 2
+#define UVC_CTRL_DATA_TYPE_BOOLEAN 3
+#define UVC_CTRL_DATA_TYPE_ENUM 4
+#define UVC_CTRL_DATA_TYPE_BITMASK 5
+
+/* Control flags */
+#define UVC_CONTROL_SET_CUR (1 << 0)
+#define UVC_CONTROL_GET_CUR (1 << 1)
+#define UVC_CONTROL_GET_MIN (1 << 2)
+#define UVC_CONTROL_GET_MAX (1 << 3)
+#define UVC_CONTROL_GET_RES (1 << 4)
+#define UVC_CONTROL_GET_DEF (1 << 5)
+/* Control should be saved at suspend and restored at resume. */
+#define UVC_CONTROL_RESTORE (1 << 6)
+/* Control can be updated by the camera. */
+#define UVC_CONTROL_AUTO_UPDATE (1 << 7)
+
+#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
+ UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
+ UVC_CONTROL_GET_DEF)
+
+struct uvc_xu_control_info {
+ __u8 entity[16];
+ __u8 index;
+ __u8 selector;
+ __u16 size;
+ __u32 flags;
+};
+
+struct uvc_xu_control_mapping {
+ __u32 id;
+ __u8 name[32];
+ __u8 entity[16];
+ __u8 selector;
+
+ __u8 size;
+ __u8 offset;
+ enum v4l2_ctrl_type v4l2_type;
+ __u32 data_type;
+};
+
+struct uvc_xu_control {
+ __u8 unit;
+ __u8 selector;
+ __u16 size;
+ __u8 __user *data;
+};
+
+#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
+#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
+#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
+#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
+
+#ifdef __KERNEL__
+
+#include <linux/poll.h>
+
+/* --------------------------------------------------------------------------
+ * UVC constants
+ */
+
+#define SC_UNDEFINED 0x00
+#define SC_VIDEOCONTROL 0x01
+#define SC_VIDEOSTREAMING 0x02
+#define SC_VIDEO_INTERFACE_COLLECTION 0x03
+
+#define PC_PROTOCOL_UNDEFINED 0x00
+
+#define CS_UNDEFINED 0x20
+#define CS_DEVICE 0x21
+#define CS_CONFIGURATION 0x22
+#define CS_STRING 0x23
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
+
+/* VideoControl class specific interface descriptor */
+#define VC_DESCRIPTOR_UNDEFINED 0x00
+#define VC_HEADER 0x01
+#define VC_INPUT_TERMINAL 0x02
+#define VC_OUTPUT_TERMINAL 0x03
+#define VC_SELECTOR_UNIT 0x04
+#define VC_PROCESSING_UNIT 0x05
+#define VC_EXTENSION_UNIT 0x06
+
+/* VideoStreaming class specific interface descriptor */
+#define VS_UNDEFINED 0x00
+#define VS_INPUT_HEADER 0x01
+#define VS_OUTPUT_HEADER 0x02
+#define VS_STILL_IMAGE_FRAME 0x03
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED 0x05
+#define VS_FORMAT_MJPEG 0x06
+#define VS_FRAME_MJPEG 0x07
+#define VS_FORMAT_MPEG2TS 0x0a
+#define VS_FORMAT_DV 0x0c
+#define VS_COLORFORMAT 0x0d
+#define VS_FORMAT_FRAME_BASED 0x10
+#define VS_FRAME_FRAME_BASED 0x11
+#define VS_FORMAT_STREAM_BASED 0x12
+
+/* Endpoint type */
+#define EP_UNDEFINED 0x00
+#define EP_GENERAL 0x01
+#define EP_ENDPOINT 0x02
+#define EP_INTERRUPT 0x03
+
+/* Request codes */
+#define RC_UNDEFINED 0x00
+#define SET_CUR 0x01
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_LEN 0x85
+#define GET_INFO 0x86
+#define GET_DEF 0x87
+
+/* VideoControl interface controls */
+#define VC_CONTROL_UNDEFINED 0x00
+#define VC_VIDEO_POWER_MODE_CONTROL 0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
+
+/* Terminal controls */
+#define TE_CONTROL_UNDEFINED 0x00
+
+/* Selector Unit controls */
+#define SU_CONTROL_UNDEFINED 0x00
+#define SU_INPUT_SELECT_CONTROL 0x01
+
+/* Camera Terminal controls */
+#define CT_CONTROL_UNDEFINED 0x00
+#define CT_SCANNING_MODE_CONTROL 0x01
+#define CT_AE_MODE_CONTROL 0x02
+#define CT_AE_PRIORITY_CONTROL 0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
+#define CT_FOCUS_RELATIVE_CONTROL 0x07
+#define CT_FOCUS_AUTO_CONTROL 0x08
+#define CT_IRIS_ABSOLUTE_CONTROL 0x09
+#define CT_IRIS_RELATIVE_CONTROL 0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
+#define CT_ZOOM_RELATIVE_CONTROL 0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
+#define CT_PANTILT_RELATIVE_CONTROL 0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
+#define CT_ROLL_RELATIVE_CONTROL 0x10
+#define CT_PRIVACY_CONTROL 0x11
+
+/* Processing Unit controls */
+#define PU_CONTROL_UNDEFINED 0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
+#define PU_BRIGHTNESS_CONTROL 0x02
+#define PU_CONTRAST_CONTROL 0x03
+#define PU_GAIN_CONTROL 0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
+#define PU_HUE_CONTROL 0x06
+#define PU_SATURATION_CONTROL 0x07
+#define PU_SHARPNESS_CONTROL 0x08
+#define PU_GAMMA_CONTROL 0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
+#define PU_HUE_AUTO_CONTROL 0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
+
+#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01
+#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02
+#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03
+
+/* VideoStreaming interface controls */
+#define VS_CONTROL_UNDEFINED 0x00
+#define VS_PROBE_CONTROL 0x01
+#define VS_COMMIT_CONTROL 0x02
+#define VS_STILL_PROBE_CONTROL 0x03
+#define VS_STILL_COMMIT_CONTROL 0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define VS_SYNC_DELAY_CONTROL 0x09
+
+#define TT_VENDOR_SPECIFIC 0x0100
+#define TT_STREAMING 0x0101
+
+/* Input Terminal types */
+#define ITT_VENDOR_SPECIFIC 0x0200
+#define ITT_CAMERA 0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
+
+/* Output Terminal types */
+#define OTT_VENDOR_SPECIFIC 0x0300
+#define OTT_DISPLAY 0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
+
+/* External Terminal types */
+#define EXTERNAL_VENDOR_SPECIFIC 0x0400
+#define COMPOSITE_CONNECTOR 0x0401
+#define SVIDEO_CONNECTOR 0x0402
+#define COMPONENT_CONNECTOR 0x0403
+
+#define UVC_TERM_INPUT 0x0000
+#define UVC_TERM_OUTPUT 0x8000
+
+#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
+#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
+#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0)
+#define UVC_ENTITY_IS_ITERM(entity) \
+ (((entity)->type & 0x8000) == UVC_TERM_INPUT)
+#define UVC_ENTITY_IS_OTERM(entity) \
+ (((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
+
+#define UVC_STATUS_TYPE_CONTROL 1
+#define UVC_STATUS_TYPE_STREAMING 2
+
+/* ------------------------------------------------------------------------
+ * GUIDs
+ */
+#define UVC_GUID_UVC_CAMERA \
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
+#define UVC_GUID_UVC_OUTPUT \
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
+#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
+#define UVC_GUID_UVC_PROCESSING \
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}
+#define UVC_GUID_UVC_SELECTOR \
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
+
+#define UVC_GUID_LOGITECH_DEV_INFO \
+ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
+ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e}
+#define UVC_GUID_LOGITECH_USER_HW \
+ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
+ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f}
+#define UVC_GUID_LOGITECH_VIDEO \
+ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
+ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50}
+#define UVC_GUID_LOGITECH_MOTOR \
+ {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
+ 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56}
+
+#define UVC_GUID_FORMAT_MJPEG \
+ { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_YUY2 \
+ { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_NV12 \
+ { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_YV12 \
+ { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_I420 \
+ { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_UYVY \
+ { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y800 \
+ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_BY8 \
+ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+
+
+/* ------------------------------------------------------------------------
+ * Driver specific constants.
+ */
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0)
+
+/* Number of isochronous URBs. */
+#define UVC_URBS 5
+/* Maximum number of packets per isochronous URB. */
+#define UVC_MAX_ISO_PACKETS 40
+/* Maximum frame size in bytes, for sanity checking. */
+#define UVC_MAX_FRAME_SIZE (16*1024*1024)
+/* Maximum number of video buffers. */
+#define UVC_MAX_VIDEO_BUFFERS 32
+
+#define UVC_CTRL_CONTROL_TIMEOUT 300
+#define UVC_CTRL_STREAMING_TIMEOUT 1000
+
+/* Devices quirks */
+#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
+#define UVC_QUIRK_PROBE_MINMAX 0x00000002
+#define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004
+#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
+#define UVC_QUIRK_STREAM_NO_FID 0x00000010
+#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
+
+/* Format flags */
+#define UVC_FMT_FLAG_COMPRESSED 0x00000001
+#define UVC_FMT_FLAG_STREAM 0x00000002
+
+/* ------------------------------------------------------------------------
+ * Structures.
+ */
+
+struct uvc_device;
+
+/* TODO: Put the most frequently accessed fields at the beginning of
+ * structures to maximize cache efficiency.
+ */
+struct uvc_streaming_control {
+ __u16 bmHint;
+ __u8 bFormatIndex;
+ __u8 bFrameIndex;
+ __u32 dwFrameInterval;
+ __u16 wKeyFrameRate;
+ __u16 wPFrameRate;
+ __u16 wCompQuality;
+ __u16 wCompWindowSize;
+ __u16 wDelay;
+ __u32 dwMaxVideoFrameSize;
+ __u32 dwMaxPayloadTransferSize;
+ __u32 dwClockFrequency;
+ __u8 bmFramingInfo;
+ __u8 bPreferedVersion;
+ __u8 bMinVersion;
+ __u8 bMaxVersion;
+};
+
+struct uvc_menu_info {
+ __u32 value;
+ __u8 name[32];
+};
+
+struct uvc_control_info {
+ struct list_head list;
+ struct list_head mappings;
+
+ __u8 entity[16];
+ __u8 index;
+ __u8 selector;
+
+ __u16 size;
+ __u32 flags;
+};
+
+struct uvc_control_mapping {
+ struct list_head list;
+
+ struct uvc_control_info *ctrl;
+
+ __u32 id;
+ __u8 name[32];
+ __u8 entity[16];
+ __u8 selector;
+
+ __u8 size;
+ __u8 offset;
+ enum v4l2_ctrl_type v4l2_type;
+ __u32 data_type;
+
+ struct uvc_menu_info *menu_info;
+ __u32 menu_count;
+};
+
+struct uvc_control {
+ struct uvc_entity *entity;
+ struct uvc_control_info *info;
+
+ __u8 index; /* Used to match the uvc_control entry with a
+ uvc_control_info. */
+ __u8 dirty : 1,
+ loaded : 1,
+ modified : 1;
+
+ __u8 *data;
+};
+
+struct uvc_format_desc {
+ char *name;
+ __u8 guid[16];
+ __u32 fcc;
+};
+
+/* The term 'entity' refers to both UVC units and UVC terminals.
+ *
+ * The type field is either the terminal type (wTerminalType in the terminal
+ * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor).
+ * As the bDescriptorSubtype field is one byte long, the type value will
+ * always have a null MSB for units. All terminal types defined by the UVC
+ * specification have a non-null MSB, so it is safe to use the MSB to
+ * differentiate between units and terminals as long as the descriptor parsing
+ * code makes sure terminal types have a non-null MSB.
+ *
+ * For terminals, the type's most significant bit stores the terminal
+ * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should
+ * always be accessed with the UVC_ENTITY_* macros and never directly.
+ */
+
+struct uvc_entity {
+ struct list_head list; /* Entity as part of a UVC device. */
+ struct list_head chain; /* Entity as part of a video device
+ * chain. */
+ __u8 id;
+ __u16 type;
+ char name[64];
+
+ union {
+ struct {
+ __u16 wObjectiveFocalLengthMin;
+ __u16 wObjectiveFocalLengthMax;
+ __u16 wOcularFocalLength;
+ __u8 bControlSize;
+ __u8 *bmControls;
+ } camera;
+
+ struct {
+ __u8 bControlSize;
+ __u8 *bmControls;
+ __u8 bTransportModeSize;
+ __u8 *bmTransportModes;
+ } media;
+
+ struct {
+ __u8 bSourceID;
+ } output;
+
+ struct {
+ __u8 bSourceID;
+ __u16 wMaxMultiplier;
+ __u8 bControlSize;
+ __u8 *bmControls;
+ __u8 bmVideoStandards;
+ } processing;
+
+ struct {
+ __u8 bNrInPins;
+ __u8 *baSourceID;
+ } selector;
+
+ struct {
+ __u8 guidExtensionCode[16];
+ __u8 bNumControls;
+ __u8 bNrInPins;
+ __u8 *baSourceID;
+ __u8 bControlSize;
+ __u8 *bmControls;
+ __u8 *bmControlsType;
+ } extension;
+ };
+
+ unsigned int ncontrols;
+ struct uvc_control *controls;
+};
+
+struct uvc_frame {
+ __u8 bFrameIndex;
+ __u8 bmCapabilities;
+ __u16 wWidth;
+ __u16 wHeight;
+ __u32 dwMinBitRate;
+ __u32 dwMaxBitRate;
+ __u32 dwMaxVideoFrameBufferSize;
+ __u8 bFrameIntervalType;
+ __u32 dwDefaultFrameInterval;
+ __u32 *dwFrameInterval;
+};
+
+struct uvc_format {
+ __u8 type;
+ __u8 index;
+ __u8 bpp;
+ __u8 colorspace;
+ __u32 fcc;
+ __u32 flags;
+
+ char name[32];
+
+ unsigned int nframes;
+ struct uvc_frame *frame;
+};
+
+struct uvc_streaming_header {
+ __u8 bNumFormats;
+ __u8 bEndpointAddress;
+ __u8 bTerminalLink;
+ __u8 bControlSize;
+ __u8 *bmaControls;
+ /* The following fields are used by input headers only. */
+ __u8 bmInfo;
+ __u8 bStillCaptureMethod;
+ __u8 bTriggerSupport;
+ __u8 bTriggerUsage;
+};
+
+struct uvc_streaming {
+ struct list_head list;
+
+ struct usb_interface *intf;
+ int intfnum;
+ __u16 maxpsize;
+
+ struct uvc_streaming_header header;
+
+ unsigned int nformats;
+ struct uvc_format *format;
+
+ struct uvc_streaming_control ctrl;
+ struct uvc_format *cur_format;
+ struct uvc_frame *cur_frame;
+
+ struct mutex mutex;
+};
+
+enum uvc_buffer_state {
+ UVC_BUF_STATE_IDLE = 0,
+ UVC_BUF_STATE_QUEUED = 1,
+ UVC_BUF_STATE_ACTIVE = 2,
+ UVC_BUF_STATE_DONE = 3,
+ UVC_BUF_STATE_ERROR = 4,
+};
+
+struct uvc_buffer {
+ unsigned long vma_use_count;
+ struct list_head stream;
+
+ /* Touched by interrupt handler. */
+ struct v4l2_buffer buf;
+ struct list_head queue;
+ wait_queue_head_t wait;
+ enum uvc_buffer_state state;
+};
+
+#define UVC_QUEUE_STREAMING (1 << 0)
+#define UVC_QUEUE_DISCONNECTED (1 << 1)
+#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2)
+
+struct uvc_video_queue {
+ void *mem;
+ unsigned int flags;
+ __u32 sequence;
+
+ unsigned int count;
+ unsigned int buf_size;
+ struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS];
+ struct mutex mutex; /* protects buffers and mainqueue */
+ spinlock_t irqlock; /* protects irqqueue */
+
+ struct list_head mainqueue;
+ struct list_head irqqueue;
+};
+
+struct uvc_video_device {
+ struct uvc_device *dev;
+ struct video_device *vdev;
+ atomic_t active;
+ unsigned int frozen : 1;
+
+ struct list_head iterms;
+ struct uvc_entity *oterm;
+ struct uvc_entity *processing;
+ struct uvc_entity *selector;
+ struct list_head extensions;
+ struct mutex ctrl_mutex;
+
+ struct uvc_video_queue queue;
+
+ /* Video streaming object, must always be non-NULL. */
+ struct uvc_streaming *streaming;
+
+ void (*decode) (struct urb *urb, struct uvc_video_device *video,
+ struct uvc_buffer *buf);
+
+ /* Context data used by the bulk completion handler. */
+ struct {
+ __u8 header[256];
+ unsigned int header_size;
+ int skip_payload;
+ __u32 payload_size;
+ __u32 max_payload_size;
+ } bulk;
+
+ struct urb *urb[UVC_URBS];
+ char *urb_buffer[UVC_URBS];
+
+ __u8 last_fid;
+};
+
+enum uvc_device_state {
+ UVC_DEV_DISCONNECTED = 1,
+};
+
+struct uvc_device {
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ __u32 quirks;
+ int intfnum;
+ char name[32];
+
+ enum uvc_device_state state;
+ struct kref kref;
+ struct list_head list;
+
+ /* Video control interface */
+ __u16 uvc_version;
+ __u32 clock_frequency;
+
+ struct list_head entities;
+
+ struct uvc_video_device video;
+
+ /* Status Interrupt Endpoint */
+ struct usb_host_endpoint *int_ep;
+ struct urb *int_urb;
+ __u8 status[16];
+ struct input_dev *input;
+
+ /* Video Streaming interfaces */
+ struct list_head streaming;
+};
+
+enum uvc_handle_state {
+ UVC_HANDLE_PASSIVE = 0,
+ UVC_HANDLE_ACTIVE = 1,
+};
+
+struct uvc_fh {
+ struct uvc_video_device *device;
+ enum uvc_handle_state state;
+};
+
+struct uvc_driver {
+ struct usb_driver driver;
+
+ struct mutex open_mutex; /* protects from open/disconnect race */
+
+ struct list_head devices; /* struct uvc_device list */
+ struct list_head controls; /* struct uvc_control_info list */
+ struct mutex ctrl_mutex; /* protects controls and devices
+ lists */
+};
+
+/* ------------------------------------------------------------------------
+ * Debugging, printing and logging
+ */
+
+#define UVC_TRACE_PROBE (1 << 0)
+#define UVC_TRACE_DESCR (1 << 1)
+#define UVC_TRACE_CONTROL (1 << 2)
+#define UVC_TRACE_FORMAT (1 << 3)
+#define UVC_TRACE_CAPTURE (1 << 4)
+#define UVC_TRACE_CALLS (1 << 5)
+#define UVC_TRACE_IOCTL (1 << 6)
+#define UVC_TRACE_FRAME (1 << 7)
+#define UVC_TRACE_SUSPEND (1 << 8)
+#define UVC_TRACE_STATUS (1 << 9)
+
+extern unsigned int uvc_trace_param;
+
+#define uvc_trace(flag, msg...) \
+ do { \
+ if (uvc_trace_param & flag) \
+ printk(KERN_DEBUG "uvcvideo: " msg); \
+ } while (0)
+
+#define uvc_printk(level, msg...) \
+ printk(level "uvcvideo: " msg)
+
+#define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
+ "%02x%02x%02x%02x%02x%02x"
+#define UVC_GUID_ARGS(guid) \
+ (guid)[3], (guid)[2], (guid)[1], (guid)[0], \
+ (guid)[5], (guid)[4], \
+ (guid)[7], (guid)[6], \
+ (guid)[8], (guid)[9], \
+ (guid)[10], (guid)[11], (guid)[12], \
+ (guid)[13], (guid)[14], (guid)[15]
+
+/* --------------------------------------------------------------------------
+ * Internal functions.
+ */
+
+/* Core driver */
+extern struct uvc_driver uvc_driver;
+extern void uvc_delete(struct kref *kref);
+
+/* Video buffers queue management. */
+extern void uvc_queue_init(struct uvc_video_queue *queue);
+extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
+ unsigned int nbuffers, unsigned int buflength);
+extern int uvc_free_buffers(struct uvc_video_queue *queue);
+extern int uvc_query_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf);
+extern int uvc_queue_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf);
+extern int uvc_dequeue_buffer(struct uvc_video_queue *queue,
+ struct v4l2_buffer *v4l2_buf, int nonblocking);
+extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
+extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
+extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
+ struct uvc_buffer *buf);
+extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
+ struct file *file, poll_table *wait);
+static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
+{
+ return queue->flags & UVC_QUEUE_STREAMING;
+}
+
+/* V4L2 interface */
+extern struct file_operations uvc_fops;
+
+/* Video */
+extern int uvc_video_init(struct uvc_video_device *video);
+extern int uvc_video_suspend(struct uvc_video_device *video);
+extern int uvc_video_resume(struct uvc_video_device *video);
+extern int uvc_video_enable(struct uvc_video_device *video, int enable);
+extern int uvc_probe_video(struct uvc_video_device *video,
+ struct uvc_streaming_control *probe);
+extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
+ __u8 intfnum, __u8 cs, void *data, __u16 size);
+extern int uvc_set_video_ctrl(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl, int probe);
+
+/* Status */
+extern int uvc_status_init(struct uvc_device *dev);
+extern void uvc_status_cleanup(struct uvc_device *dev);
+extern int uvc_status_suspend(struct uvc_device *dev);
+extern int uvc_status_resume(struct uvc_device *dev);
+
+/* Controls */
+extern struct uvc_control *uvc_find_control(struct uvc_video_device *video,
+ __u32 v4l2_id, struct uvc_control_mapping **mapping);
+extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
+ struct v4l2_queryctrl *v4l2_ctrl);
+
+extern int uvc_ctrl_add_info(struct uvc_control_info *info);
+extern int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping);
+extern int uvc_ctrl_init_device(struct uvc_device *dev);
+extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
+extern int uvc_ctrl_resume_device(struct uvc_device *dev);
+extern void uvc_ctrl_init(void);
+
+extern int uvc_ctrl_begin(struct uvc_video_device *video);
+extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback);
+static inline int uvc_ctrl_commit(struct uvc_video_device *video)
+{
+ return __uvc_ctrl_commit(video, 0);
+}
+static inline int uvc_ctrl_rollback(struct uvc_video_device *video)
+{
+ return __uvc_ctrl_commit(video, 1);
+}
+
+extern int uvc_ctrl_get(struct uvc_video_device *video,
+ struct v4l2_ext_control *xctrl);
+extern int uvc_ctrl_set(struct uvc_video_device *video,
+ struct v4l2_ext_control *xctrl);
+
+extern int uvc_xu_ctrl_query(struct uvc_video_device *video,
+ struct uvc_xu_control *ctrl, int set);
+
+/* Utility functions */
+extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
+ unsigned int n_terms, unsigned int threshold);
+extern uint32_t uvc_fraction_to_interval(uint32_t numerator,
+ uint32_t denominator);
+extern struct usb_host_endpoint *uvc_find_endpoint(
+ struct usb_host_interface *alts, __u8 epaddr);
+
+/* Quirks support */
+void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
+ struct uvc_buffer *buf);
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 31e8af0ba27..67a661cf521 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -51,12 +51,51 @@
#define VIDEO_NUM_DEVICES 256
#define VIDEO_NAME "video4linux"
+struct std_descr {
+ v4l2_std_id std;
+ const char *descr;
+};
+
+static const struct std_descr standards[] = {
+ { V4L2_STD_NTSC, "NTSC" },
+ { V4L2_STD_NTSC_M, "NTSC-M" },
+ { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
+ { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
+ { V4L2_STD_NTSC_443, "NTSC-443" },
+ { V4L2_STD_PAL, "PAL" },
+ { V4L2_STD_PAL_BG, "PAL-BG" },
+ { V4L2_STD_PAL_B, "PAL-B" },
+ { V4L2_STD_PAL_B1, "PAL-B1" },
+ { V4L2_STD_PAL_G, "PAL-G" },
+ { V4L2_STD_PAL_H, "PAL-H" },
+ { V4L2_STD_PAL_I, "PAL-I" },
+ { V4L2_STD_PAL_DK, "PAL-DK" },
+ { V4L2_STD_PAL_D, "PAL-D" },
+ { V4L2_STD_PAL_D1, "PAL-D1" },
+ { V4L2_STD_PAL_K, "PAL-K" },
+ { V4L2_STD_PAL_M, "PAL-M" },
+ { V4L2_STD_PAL_N, "PAL-N" },
+ { V4L2_STD_PAL_Nc, "PAL-Nc" },
+ { V4L2_STD_PAL_60, "PAL-60" },
+ { V4L2_STD_SECAM, "SECAM" },
+ { V4L2_STD_SECAM_B, "SECAM-B" },
+ { V4L2_STD_SECAM_G, "SECAM-G" },
+ { V4L2_STD_SECAM_H, "SECAM-H" },
+ { V4L2_STD_SECAM_DK, "SECAM-DK" },
+ { V4L2_STD_SECAM_D, "SECAM-D" },
+ { V4L2_STD_SECAM_K, "SECAM-K" },
+ { V4L2_STD_SECAM_K1, "SECAM-K1" },
+ { V4L2_STD_SECAM_L, "SECAM-L" },
+ { V4L2_STD_SECAM_LC, "SECAM-Lc" },
+ { 0, "Unknown" }
+};
+
/* video4linux standard ID conversion to standard name
*/
-char *v4l2_norm_to_name(v4l2_std_id id)
+const char *v4l2_norm_to_name(v4l2_std_id id)
{
- char *name;
u32 myid = id;
+ int i;
/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
64 bit comparations. So, on that architecture, with some gcc
@@ -64,110 +103,17 @@ char *v4l2_norm_to_name(v4l2_std_id id)
*/
BUG_ON(myid != id);
- switch (myid) {
- case V4L2_STD_PAL:
- name = "PAL";
- break;
- case V4L2_STD_PAL_BG:
- name = "PAL-BG";
- break;
- case V4L2_STD_PAL_DK:
- name = "PAL-DK";
- break;
- case V4L2_STD_PAL_B:
- name = "PAL-B";
- break;
- case V4L2_STD_PAL_B1:
- name = "PAL-B1";
- break;
- case V4L2_STD_PAL_G:
- name = "PAL-G";
- break;
- case V4L2_STD_PAL_H:
- name = "PAL-H";
- break;
- case V4L2_STD_PAL_I:
- name = "PAL-I";
- break;
- case V4L2_STD_PAL_D:
- name = "PAL-D";
- break;
- case V4L2_STD_PAL_D1:
- name = "PAL-D1";
- break;
- case V4L2_STD_PAL_K:
- name = "PAL-K";
- break;
- case V4L2_STD_PAL_M:
- name = "PAL-M";
- break;
- case V4L2_STD_PAL_N:
- name = "PAL-N";
- break;
- case V4L2_STD_PAL_Nc:
- name = "PAL-Nc";
- break;
- case V4L2_STD_PAL_60:
- name = "PAL-60";
- break;
- case V4L2_STD_NTSC:
- name = "NTSC";
- break;
- case V4L2_STD_NTSC_M:
- name = "NTSC-M";
- break;
- case V4L2_STD_NTSC_M_JP:
- name = "NTSC-M-JP";
- break;
- case V4L2_STD_NTSC_443:
- name = "NTSC-443";
- break;
- case V4L2_STD_NTSC_M_KR:
- name = "NTSC-M-KR";
- break;
- case V4L2_STD_SECAM:
- name = "SECAM";
- break;
- case V4L2_STD_SECAM_DK:
- name = "SECAM-DK";
- break;
- case V4L2_STD_SECAM_B:
- name = "SECAM-B";
- break;
- case V4L2_STD_SECAM_D:
- name = "SECAM-D";
- break;
- case V4L2_STD_SECAM_G:
- name = "SECAM-G";
- break;
- case V4L2_STD_SECAM_H:
- name = "SECAM-H";
- break;
- case V4L2_STD_SECAM_K:
- name = "SECAM-K";
- break;
- case V4L2_STD_SECAM_K1:
- name = "SECAM-K1";
- break;
- case V4L2_STD_SECAM_L:
- name = "SECAM-L";
- break;
- case V4L2_STD_SECAM_LC:
- name = "SECAM-LC";
- break;
- default:
- name = "Unknown";
- break;
- }
-
- return name;
+ for (i = 0; standards[i].std; i++)
+ if (myid == standards[i].std)
+ break;
+ return standards[i].descr;
}
EXPORT_SYMBOL(v4l2_norm_to_name);
/* Fill in the fields of a v4l2_standard structure according to the
'id' and 'transmission' parameters. Returns negative on error. */
int v4l2_video_std_construct(struct v4l2_standard *vs,
- int id, char *name)
+ int id, const char *name)
{
u32 index = vs->index;
@@ -1218,95 +1164,40 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMSTD:
{
struct v4l2_standard *p = arg;
- v4l2_std_id id = vfd->tvnorms,curr_id=0;
- unsigned int index = p->index,i;
-
- if (index<0) {
- ret=-EINVAL;
- break;
- }
-
- /* Return norm array on a canonical way */
- for (i=0;i<= index && id; i++) {
- if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
- curr_id = V4L2_STD_PAL;
- } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
- curr_id = V4L2_STD_PAL_BG;
- } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
- curr_id = V4L2_STD_PAL_DK;
- } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
- curr_id = V4L2_STD_PAL_B;
- } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
- curr_id = V4L2_STD_PAL_B1;
- } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
- curr_id = V4L2_STD_PAL_G;
- } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
- curr_id = V4L2_STD_PAL_H;
- } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
- curr_id = V4L2_STD_PAL_I;
- } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
- curr_id = V4L2_STD_PAL_D;
- } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
- curr_id = V4L2_STD_PAL_D1;
- } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
- curr_id = V4L2_STD_PAL_K;
- } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
- curr_id = V4L2_STD_PAL_M;
- } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
- curr_id = V4L2_STD_PAL_N;
- } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
- curr_id = V4L2_STD_PAL_Nc;
- } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
- curr_id = V4L2_STD_PAL_60;
- } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
- curr_id = V4L2_STD_NTSC;
- } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
- curr_id = V4L2_STD_NTSC_M;
- } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
- curr_id = V4L2_STD_NTSC_M_JP;
- } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
- curr_id = V4L2_STD_NTSC_443;
- } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
- curr_id = V4L2_STD_NTSC_M_KR;
- } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
- curr_id = V4L2_STD_SECAM;
- } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
- curr_id = V4L2_STD_SECAM_DK;
- } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
- curr_id = V4L2_STD_SECAM_B;
- } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
- curr_id = V4L2_STD_SECAM_D;
- } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
- curr_id = V4L2_STD_SECAM_G;
- } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
- curr_id = V4L2_STD_SECAM_H;
- } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
- curr_id = V4L2_STD_SECAM_K;
- } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
- curr_id = V4L2_STD_SECAM_K1;
- } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
- curr_id = V4L2_STD_SECAM_L;
- } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
- curr_id = V4L2_STD_SECAM_LC;
- } else {
+ v4l2_std_id id = vfd->tvnorms, curr_id = 0;
+ unsigned int index = p->index, i, j = 0;
+ const char *descr = "";
+
+ /* Return norm array in a canonical way */
+ for (i = 0; i <= index && id; i++) {
+ /* last std value in the standards array is 0, so this
+ while always ends there since (id & 0) == 0. */
+ while ((id & standards[j].std) != standards[j].std)
+ j++;
+ curr_id = standards[j].std;
+ descr = standards[j].descr;
+ j++;
+ if (curr_id == 0)
break;
- }
- id &= ~curr_id;
+ if (curr_id != V4L2_STD_PAL &&
+ curr_id != V4L2_STD_SECAM &&
+ curr_id != V4L2_STD_NTSC)
+ id &= ~curr_id;
}
- if (i<=index)
+ if (i <= index)
return -EINVAL;
- v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
+ v4l2_video_std_construct(p, curr_id, descr);
p->index = index;
- dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
+ dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
"framelines=%d\n", p->index,
(unsigned long long)p->id, p->name,
p->frameperiod.numerator,
p->frameperiod.denominator,
p->framelines);
- ret=0;
+ ret = 0;
break;
}
case VIDIOC_G_STD:
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 845be1864f6..5ff9a58b613 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -327,13 +327,14 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
int hmax = buf->vb.height;
int wmax = buf->vb.width;
struct timeval ts;
- char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
+ char *tmpbuf;
void *vbuf = videobuf_to_vmalloc(&buf->vb);
- if (!tmpbuf)
+ if (!vbuf)
return;
- if (!vbuf)
+ tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
+ if (!tmpbuf)
return;
for (h = 0; h < hmax; h++) {
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 95f33e87a99..c4349c746cb 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -1017,8 +1017,8 @@ static int imxmci_probe(struct platform_device *pdev)
host->imask = IMXMCI_INT_MASK_DEFAULT;
MMC_INT_MASK = host->imask;
-
- if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){
+ host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
+ if(host->dma < 0) {
dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
ret = -EBUSY;
goto out;
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index c12d8056beb..68eec6c6c51 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -60,13 +60,22 @@ struct omapflash_info {
static void omap_set_vpp(struct map_info *map, int enable)
{
static int count;
-
- if (enable) {
- if (count++ == 0)
- OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP;
- } else {
- if (count && (--count == 0))
- OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP;
+ u32 l;
+
+ if (cpu_class_is_omap1()) {
+ if (enable) {
+ if (count++ == 0) {
+ l = omap_readl(EMIFS_CONFIG);
+ l |= OMAP_EMIFS_CONFIG_WP;
+ omap_writel(l, EMIFS_CONFIG);
+ }
+ } else {
+ if (count && (--count == 0)) {
+ l = omap_readl(EMIFS_CONFIG);
+ l &= ~OMAP_EMIFS_CONFIG_WP;
+ omap_writel(l, EMIFS_CONFIG);
+ }
+ }
}
}
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 2edda8cc7f9..aabad8ce745 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1768,9 +1768,10 @@ vortex_timer(unsigned long data)
case XCVR_MII: case XCVR_NWAY:
{
ok = 1;
- spin_lock_bh(&vp->lock);
+ /* Interrupts are already disabled */
+ spin_lock(&vp->lock);
vortex_check_media(dev, 0);
- spin_unlock_bh(&vp->lock);
+ spin_unlock(&vp->lock);
}
break;
default: /* Other media types handled by Tx timeouts. */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f4182cfffe9..45a41b597da 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -217,7 +217,7 @@ config MII
config MACB
tristate "Atmel MACB support"
- depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9
+ depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
select PHYLIB
help
The Atmel MACB ethernet interface is found on many AT32 and AT91
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 00081d2b9cd..e9d15eccad0 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -647,7 +647,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
struct ei_device *ei_local;
struct net_device *dev;
struct etherh_priv *eh;
- int i, ret;
+ int ret;
DECLARE_MAC_BUF(mac);
etherh_banner();
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index f3cba5e24ec..1037b133231 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1803,6 +1803,8 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
if (rx->prev->skb) {
struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
put_unaligned_le32(rx->dma_addr, &prev_rfd->link);
+ pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
+ sizeof(struct rfd), PCI_DMA_TODEVICE);
}
return 0;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 701531e72e7..a3f6a9c72ec 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -347,7 +347,7 @@ e1000_set_tso(struct net_device *netdev, u32 data)
else
netdev->features &= ~NETIF_F_TSO;
- if (data)
+ if (data && (adapter->hw.mac_type > e1000_82547_rev_2))
netdev->features |= NETIF_F_TSO6;
else
netdev->features &= ~NETIF_F_TSO6;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index cab1835173c..648a87bbf46 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2535,7 +2535,8 @@ void e1000e_down(struct e1000_adapter *adapter)
adapter->link_speed = 0;
adapter->link_duplex = 0;
- e1000e_reset(adapter);
+ if (!pci_channel_offline(adapter->pdev))
+ e1000e_reset(adapter);
e1000_clean_tx_ring(adapter);
e1000_clean_rx_ring(adapter);
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 0b94833e23f..e8cfadefa4b 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -1077,8 +1077,6 @@ static inline void rx_off(struct scc_priv *priv)
static void start_timer(struct scc_priv *priv, int t, int r15)
{
- unsigned long flags;
-
outb(priv->tmr_mode, priv->tmr_ctrl);
if (t == 0) {
tm_isr(priv);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index ae398f04c7b..e79a26a886c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -718,7 +718,8 @@ void igb_down(struct igb_adapter *adapter)
adapter->link_speed = 0;
adapter->link_duplex = 0;
- igb_reset(adapter);
+ if (!pci_channel_offline(adapter->pdev))
+ igb_reset(adapter);
igb_clean_all_tx_rings(adapter);
igb_clean_all_rx_rings(adapter);
}
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 679a0826780..2c03f4e2ccc 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1271,7 +1271,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
- endframeLen = framelen - jumbo->current_size;
+ endframelen = framelen - jumbo->current_size;
/*
if (framelen > IPG_RXFRAG_SIZE)
framelen=IPG_RXFRAG_SIZE;
@@ -1279,8 +1279,8 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
if (framelen > IPG_RXSUPPORT_SIZE)
dev_kfree_skb_irq(jumbo->skb);
else {
- memcpy(skb_put(jumbo->skb, endframeLen),
- skb->data, endframeLen);
+ memcpy(skb_put(jumbo->skb, endframelen),
+ skb->data, endframelen);
jumbo->skb->protocol =
eth_type_trans(jumbo->skb, dev);
@@ -1352,16 +1352,16 @@ static int ipg_nic_rx(struct net_device *dev)
switch (ipg_nic_rx_check_frame_type(dev)) {
case FRAME_WITH_START_WITH_END:
- ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry);
+ ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry);
break;
case FRAME_WITH_START:
- ipg_nic_rx_with_start(dev, tp, rxfd, entry);
+ ipg_nic_rx_with_start(dev, sp, rxfd, entry);
break;
case FRAME_WITH_END:
- ipg_nic_rx_with_end(dev, tp, rxfd, entry);
+ ipg_nic_rx_with_end(dev, sp, rxfd, entry);
break;
case FRAME_NO_START_NO_END:
- ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry);
+ ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry);
break;
}
}
@@ -1808,7 +1808,7 @@ static int ipg_nic_open(struct net_device *dev)
/* initialize JUMBO Frame control variable */
sp->jumbo.found_start = 0;
sp->jumbo.current_size = 0;
- sp->jumbo.skb = 0;
+ sp->jumbo.skb = NULL;
dev->mtu = IPG_TXFRAG_SIZE;
#endif
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7b859220c25..8f046090115 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1969,7 +1969,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- ixgbe_reset(adapter);
+ if (!pci_channel_offline(adapter->pdev))
+ ixgbe_reset(adapter);
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 6797ed069f1..63cd67b931e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -71,14 +71,18 @@ static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data);
/* PCI Device ID Table */
+#define ENTRY(device) \
+ {PCI_DEVICE(0x4040, (device)), \
+ .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
+
static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(0x4040, 0x0001), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0002), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0003), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0004), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0005), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0024), PCI_DEVICE_CLASS(0x020000, ~0)},
- {PCI_DEVICE(0x4040, 0x0025), PCI_DEVICE_CLASS(0x020000, ~0)},
+ ENTRY(0x0001),
+ ENTRY(0x0002),
+ ENTRY(0x0003),
+ ENTRY(0x0004),
+ ENTRY(0x0005),
+ ENTRY(0x0024),
+ ENTRY(0x0025),
{0,}
};
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index ce95c5d168f..70d012e90dc 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -525,12 +525,14 @@ static int axnet_open(struct net_device *dev)
int ret;
axnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
+ unsigned int nic_base = dev->base_addr;
DEBUG(2, "axnet_open('%s')\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
+ outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev);
if (ret)
return ret;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index fd8158a86f6..2d4c4ad89b8 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -969,6 +969,7 @@ static int pcnet_open(struct net_device *dev)
int ret;
pcnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
+ unsigned int nic_base = dev->base_addr;
DEBUG(2, "pcnet_open('%s')\n", dev->name);
@@ -976,6 +977,8 @@ static int pcnet_open(struct net_device *dev)
return -ENODEV;
set_misc_reg(dev);
+
+ outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
if (ret)
return ret;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index b7f7b2227d5..bccee68bd48 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -3701,7 +3701,9 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset)
printk(KERN_ERR PFX
"%s: Driver up/down cycle failed, "
"closing device\n",qdev->ndev->name);
+ rtnl_lock();
dev_close(qdev->ndev);
+ rtnl_unlock();
return -1;
}
return 0;
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 858b191517b..504a48ff73c 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -273,7 +273,7 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
dma_addr_t mapping = desc_dma;
while (size-- > 0) {
- mapping += sizeof(sizeof(*desc));
+ mapping += sizeof(*desc);
desc->ndesc = cpu_to_le32(mapping);
desc->vndescp = desc + 1;
desc++;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index b5c1e663417..ae7b697456b 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2625,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring)
rxdp1->Buffer0_ptr = pci_map_single
(ring->pdev, skb->data, size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
- if( (rxdp1->Buffer0_ptr == 0) ||
- (rxdp1->Buffer0_ptr ==
- DMA_ERROR_CODE))
+ if(pci_dma_mapping_error(rxdp1->Buffer0_ptr))
goto pci_map_failed;
rxdp->Control_2 =
@@ -2657,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring)
skb->data = (void *) (unsigned long)tmp;
skb_reset_tail_pointer(skb);
+ /* AK: check is wrong. 0 can be valid dma address */
if (!(rxdp3->Buffer0_ptr))
rxdp3->Buffer0_ptr =
pci_map_single(ring->pdev, ba->ba_0,
@@ -2665,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring)
pci_dma_sync_single_for_device(ring->pdev,
(dma_addr_t) rxdp3->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer0_ptr == 0) ||
- (rxdp3->Buffer0_ptr == DMA_ERROR_CODE))
+ if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
goto pci_map_failed;
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
@@ -2681,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring)
(ring->pdev, skb->data, ring->mtu + 4,
PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer2_ptr == 0) ||
- (rxdp3->Buffer2_ptr == DMA_ERROR_CODE))
+ if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
goto pci_map_failed;
+ /* AK: check is wrong */
if (!rxdp3->Buffer1_ptr)
rxdp3->Buffer1_ptr =
pci_map_single(ring->pdev,
ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer1_ptr == 0) ||
- (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
pci_unmap_single
(ring->pdev,
(dma_addr_t)(unsigned long)
@@ -4264,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
txdp->Buffer_Pointer = pci_map_single(sp->pdev,
fifo->ufo_in_band_v,
sizeof(u64), PCI_DMA_TODEVICE);
- if((txdp->Buffer_Pointer == 0) ||
- (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ if (pci_dma_mapping_error(txdp->Buffer_Pointer))
goto pci_map_failed;
txdp++;
}
txdp->Buffer_Pointer = pci_map_single
(sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
- if((txdp->Buffer_Pointer == 0) ||
- (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ if (pci_dma_mapping_error(txdp->Buffer_Pointer))
goto pci_map_failed;
txdp->Host_Control = (unsigned long) skb;
@@ -6884,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
pci_map_single( sp->pdev, (*skb)->data,
size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
- if( (rxdp1->Buffer0_ptr == 0) ||
- (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) {
+ if (pci_dma_mapping_error(rxdp1->Buffer0_ptr))
goto memalloc_failed;
- }
rxdp->Host_Control = (unsigned long) (*skb);
}
} else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
@@ -6913,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
pci_map_single(sp->pdev, (*skb)->data,
dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer2_ptr == 0) ||
- (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) {
+ if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
goto memalloc_failed;
- }
rxdp3->Buffer0_ptr = *temp0 =
pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer0_ptr == 0) ||
- (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
+ if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) {
pci_unmap_single (sp->pdev,
(dma_addr_t)rxdp3->Buffer2_ptr,
dev->mtu + 4, PCI_DMA_FROMDEVICE);
@@ -6933,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
rxdp3->Buffer1_ptr = *temp1 =
pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- if( (rxdp3->Buffer1_ptr == 0) ||
- (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
pci_unmap_single (sp->pdev,
(dma_addr_t)rxdp3->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 4706f7f9acb..1827b6686c9 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -75,10 +75,6 @@ static int debug_level = ERR_DBG;
/* DEBUG message print. */
#define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args)
-#ifndef DMA_ERROR_CODE
-#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
-#endif
-
/* Protocol assist features of the NIC */
#define L3_CKSUM_OK 0xFFFF
#define L4_CKSUM_OK 0xFFFF
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 10e4e85da3f..b07b8cbadea 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1394,6 +1394,7 @@ tc35815_open(struct net_device *dev)
tc35815_chip_init(dev);
spin_unlock_irq(&lp->lock);
+ netif_carrier_off(dev);
/* schedule a link state check */
phy_start(lp->phy_dev);
@@ -1735,7 +1736,6 @@ tc35815_rx(struct net_device *dev)
skb = lp->rx_skbs[cur_bd].skb;
prefetch(skb->data);
lp->rx_skbs[cur_bd].skb = NULL;
- lp->fbl_count--;
pci_unmap_single(lp->pci_dev,
lp->rx_skbs[cur_bd].skb_dma,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
@@ -1791,6 +1791,7 @@ tc35815_rx(struct net_device *dev)
#ifdef TC35815_USE_PACKEDBUFFER
while (lp->fbl_curid != id)
#else
+ lp->fbl_count--;
while (lp->fbl_count < RX_BUF_NUM)
#endif
{
@@ -2453,6 +2454,7 @@ static int tc35815_resume(struct pci_dev *pdev)
return 0;
pci_set_power_state(pdev, PCI_D0);
tc35815_restart(dev);
+ netif_carrier_off(dev);
if (lp->phy_dev)
phy_start(lp->phy_dev);
netif_device_attach(dev);
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 249e18053d5..069f8bb0a99 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -32,6 +32,7 @@
#include <linux/x25.h>
#include <linux/lapb.h>
#include <linux/init.h>
+#include <linux/rtnetlink.h>
#include "x25_asy.h"
#include <net/x25device.h>
@@ -601,8 +602,10 @@ static void x25_asy_close_tty(struct tty_struct *tty)
if (!sl || sl->magic != X25_ASY_MAGIC)
return;
+ rtnl_lock();
if (sl->dev->flags & IFF_UP)
dev_close(sl->dev);
+ rtnl_unlock();
tty->disc_data = NULL;
sl->tty = NULL;
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index 36a9c42df83..76f4c7bad8b 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -72,6 +72,9 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
struct b43_wldev *dev = led->dev;
bool radio_enabled;
+ if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED))
+ return;
+
/* Checking the radio-enabled status here is slightly racy,
* but we want to avoid the locking overhead and we don't care
* whether the LED has the wrong state for a second. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index fa4b0d8b74a..a7082779308 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2883,12 +2883,11 @@ static int b43_op_tx(struct ieee80211_hw *hw,
if (unlikely(skb->len < 2 + 2 + 6)) {
/* Too short, this can't be a valid frame. */
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
+ goto drop_packet;
}
B43_WARN_ON(skb_shinfo(skb)->nr_frags);
if (unlikely(!dev))
- return NETDEV_TX_BUSY;
+ goto drop_packet;
/* Transmissions on seperate queues can run concurrently. */
read_lock_irqsave(&wl->tx_lock, flags);
@@ -2904,7 +2903,12 @@ static int b43_op_tx(struct ieee80211_hw *hw,
read_unlock_irqrestore(&wl->tx_lock, flags);
if (unlikely(err))
- return NETDEV_TX_BUSY;
+ goto drop_packet;
+ return NETDEV_TX_OK;
+
+drop_packet:
+ /* We can not transmit this packet. Drop it. */
+ dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index c990f87b107..93ddc1cbcc8 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -876,6 +876,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
if (!ring)
goto out;
ring->type = type;
+ ring->dev = dev;
nr_slots = B43legacy_RXRING_SLOTS;
if (for_tx)
@@ -922,7 +923,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
DMA_TO_DEVICE);
}
- ring->dev = dev;
ring->nr_slots = nr_slots;
ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
ring->index = controller_index;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 204077c1387..3e612d0a13e 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
} else
err = b43legacy_dma_tx(dev, skb, ctl);
out:
- if (unlikely(err))
- return NETDEV_TX_BUSY;
+ if (unlikely(err)) {
+ /* Drop the packet. */
+ dev_kfree_skb_any(skb);
+ }
return NETDEV_TX_OK;
}
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 4fd73809602..020f450e9db 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -64,7 +64,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr_4addr *fhdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -83,8 +83,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fhdr = (struct ieee80211_hdr_4addr *) skb->data;
+ fc = le16_to_cpu(fhdr->frame_ctl);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
printk(KERN_DEBUG "%s: dropped management frame with header "
@@ -551,7 +551,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
/* RA (or BSSID) is not ours - drop */
- PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with "
+ PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with "
"not own or broadcast %s=%s\n",
local->dev->name,
fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 0acd9589c48..ab981afd481 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1930,7 +1930,7 @@ static void handle_pspoll(local_info_t *local,
PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n");
return;
}
- aid &= ~BIT(15) & ~BIT(14);
+ aid &= ~(BIT(15) | BIT(14));
if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid);
return;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index ed4317a17cb..80039a0ae02 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -533,10 +533,10 @@ static void prism2_detach(struct pcmcia_device *link)
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define CFG_CHECK2(fn, retf) \
-do { int ret = (retf); \
-if (ret != 0) { \
- PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
- cs_error(link, fn, ret); \
+do { int _ret = (retf); \
+if (_ret != 0) { \
+ PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
+ cs_error(link, fn, _ret); \
goto next_entry; \
} \
} while (0)
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index cdf90c40f11..936f52e3d95 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2835,7 +2835,7 @@ static void hostap_passive_scan(unsigned long data)
{
local_info_t *local = (local_info_t *) data;
struct net_device *dev = local->dev;
- u16 channel;
+ u16 chan;
if (local->passive_scan_interval <= 0)
return;
@@ -2872,11 +2872,11 @@ static void hostap_passive_scan(unsigned long data)
printk(KERN_DEBUG "%s: passive scan channel %d\n",
dev->name, local->passive_scan_channel);
- channel = local->passive_scan_channel;
+ chan = local->passive_scan_channel;
local->passive_scan_state = PASSIVE_SCAN_WAIT;
local->passive_scan_timer.expires = jiffies + HZ / 10;
} else {
- channel = local->channel;
+ chan = local->channel;
local->passive_scan_state = PASSIVE_SCAN_LISTEN;
local->passive_scan_timer.expires = jiffies +
local->passive_scan_interval * HZ;
@@ -2884,9 +2884,9 @@ static void hostap_passive_scan(unsigned long data)
if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
(HFA384X_TEST_CHANGE_CHANNEL << 8),
- channel, NULL, 0))
+ chan, NULL, 0))
printk(KERN_ERR "%s: passive scan channel set %d "
- "failed\n", dev->name, channel);
+ "failed\n", dev->name, chan);
add_timer(&local->passive_scan_timer);
}
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index f7aec9309d0..a38e85f334d 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -594,7 +594,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
}
-int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+static int hostap_80211_header_parse(const struct sk_buff *skb,
+ unsigned char *haddr)
{
struct hostap_interface *iface = netdev_priv(skb->dev);
local_info_t *local = iface->local;
@@ -857,7 +858,6 @@ const struct header_ops hostap_80211_ops = {
.rebuild = eth_rebuild_header,
.cache = eth_header_cache,
.cache_update = eth_header_cache_update,
-
.parse = hostap_80211_header_parse,
};
EXPORT_SYMBOL(hostap_80211_ops);
@@ -1150,7 +1150,6 @@ EXPORT_SYMBOL(hostap_set_roaming);
EXPORT_SYMBOL(hostap_set_auth_algs);
EXPORT_SYMBOL(hostap_dump_rx_header);
EXPORT_SYMBOL(hostap_dump_tx_header);
-EXPORT_SYMBOL(hostap_80211_header_parse);
EXPORT_SYMBOL(hostap_80211_get_hdrlen);
EXPORT_SYMBOL(hostap_get_stats);
EXPORT_SYMBOL(hostap_setup_dev);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 13925b627e3..b1b3c523185 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2227,7 +2227,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
}
IWL_DEBUG_INFO("Starting scan...\n");
- priv->scan_bands = 2;
+ if (priv->cfg->sku & IWL_SKU_G)
+ priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+ if (priv->cfg->sku & IWL_SKU_A)
+ priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
set_bit(STATUS_SCANNING, &priv->status);
priv->scan_start = jiffies;
priv->scan_pass_start = priv->scan_start;
@@ -3352,13 +3355,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
cancel_delayed_work(&priv->scan_check);
IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands == 2) ? "2.4" : "5.2",
+ (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+ "2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
(priv->scan_pass_start, jiffies)));
- /* Remove this scanned band from the list
- * of pending bands to scan */
- priv->scan_bands--;
+ /* Remove this scanned band from the list of pending
+ * bands to scan, band G precedes A in order of scanning
+ * as seen in iwl3945_bg_request_scan */
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+ else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
/* If a request to abort was given, or the scan did not succeed
* then we reset the scan state machine and terminate,
@@ -4972,7 +4980,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+ IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
scan_ch->channel);
continue;
}
@@ -6315,21 +6323,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
/* flags + rate selection */
- switch (priv->scan_bands) {
- case 2:
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
scan->good_CRC_th = 0;
band = IEEE80211_BAND_2GHZ;
- break;
-
- case 1:
+ } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
- break;
-
- default:
+ } else {
IWL_WARNING("Invalid scan band count\n");
goto done;
}
@@ -6770,7 +6773,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
conf->channel->hw_value);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
+ IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
conf->channel->hw_value, conf->channel->band);
IWL_DEBUG_MAC80211("leave - invalid channel\n");
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 883b42f7e99..5ed16ce7846 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1774,7 +1774,10 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv)
}
IWL_DEBUG_INFO("Starting scan...\n");
- priv->scan_bands = 2;
+ if (priv->cfg->sku & IWL_SKU_G)
+ priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+ if (priv->cfg->sku & IWL_SKU_A)
+ priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
set_bit(STATUS_SCANNING, &priv->status);
priv->scan_start = jiffies;
priv->scan_pass_start = priv->scan_start;
@@ -3023,8 +3026,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
if (index != -1) {
- int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
#ifdef CONFIG_IWL4965_HT
+ int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
+
if (tid != MAX_TID_COUNT)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
@@ -3276,13 +3280,18 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
cancel_delayed_work(&priv->scan_check);
IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands == 2) ? "2.4" : "5.2",
+ (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+ "2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
(priv->scan_pass_start, jiffies)));
- /* Remove this scanned band from the list
- * of pending bands to scan */
- priv->scan_bands--;
+ /* Remove this scanned band from the list of pending
+ * bands to scan, band G precedes A in order of scanning
+ * as seen in iwl_bg_request_scan */
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+ else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
/* If a request to abort was given, or the scan did not succeed
* then we reset the scan state machine and terminate,
@@ -3292,7 +3301,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
} else {
/* If there are more bands on this scan pass reschedule */
- if (priv->scan_bands > 0)
+ if (priv->scan_bands)
goto reschedule;
}
@@ -4635,10 +4644,9 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);
- ch_info = iwl_get_channel_info(priv, band,
- scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+ IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
scan_ch->channel);
continue;
}
@@ -5830,8 +5838,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
- switch (priv->scan_bands) {
- case 2:
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
scan->tx_cmd.rate_n_flags =
iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
@@ -5839,17 +5846,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
scan->good_CRC_th = 0;
band = IEEE80211_BAND_2GHZ;
- break;
-
- case 1:
+ } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
scan->tx_cmd.rate_n_flags =
iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
RATE_MCS_ANT_B_MSK);
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
- break;
-
- default:
+ } else {
IWL_WARNING("Invalid scan band count\n");
goto done;
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 762e85bef55..e43bae97ed8 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
- avs->mactime = cpu_to_be64(le64_to_cpu(clock));
+ avs->mactime = cpu_to_be64(clock);
avs->hosttime = cpu_to_be64(jiffies);
avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */
avs->channel = cpu_to_be32(channel_of_freq(freq));
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index fdbd0ef2be4..61e59c17a60 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt2500usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
- mutex_unlock(&rt2x00dev->usb_cache_mutex);
- return;
- }
+ if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+ goto exit_fail;
/*
* Write the data into the BBP.
@@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ return;
+
+exit_fail:
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
}
static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt2500usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
- return;
- }
+ if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+ goto exit_fail;
/*
* Write the request into the BBP.
@@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt2500usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
- *value = 0xff;
- mutex_unlock(&rt2x00dev->usb_cache_mutex);
- return;
- }
+ if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+ goto exit_fail;
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ return;
+
+exit_fail:
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
+ *value = 0xff;
}
static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 611d9832059..b4bf1e09cf9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -821,6 +821,7 @@ struct rt2x00_dev {
/*
* Scheduled work.
*/
+ struct workqueue_struct *workqueue;
struct work_struct intf_work;
struct work_struct filter_work;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 2673d568bca..c997d4f28ab 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -75,7 +75,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00lib_reset_link_tuner(rt2x00dev);
- queue_delayed_work(rt2x00dev->hw->workqueue,
+ queue_delayed_work(rt2x00dev->workqueue,
&rt2x00dev->link.work, LINK_TUNE_INTERVAL);
}
@@ -137,14 +137,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Stop all scheduled work.
- */
- if (work_pending(&rt2x00dev->intf_work))
- cancel_work_sync(&rt2x00dev->intf_work);
- if (work_pending(&rt2x00dev->filter_work))
- cancel_work_sync(&rt2x00dev->filter_work);
-
- /*
* Stop the TX queues.
*/
ieee80211_stop_queues(rt2x00dev->hw);
@@ -398,8 +390,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev->link.count++;
- queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work,
- LINK_TUNE_INTERVAL);
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
}
static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -433,6 +425,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
spin_unlock(&intf->lock);
+ /*
+ * It is possible the radio was disabled while the work had been
+ * scheduled. If that happens we should return here immediately,
+ * note that in the spinlock protected area above the delayed_flags
+ * have been cleared correctly.
+ */
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
if (delayed_flags & DELAYED_UPDATE_BEACON) {
skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control);
if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
@@ -441,7 +442,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
}
if (delayed_flags & DELAYED_CONFIG_ERP)
- rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf);
+ rt2x00lib_config_erp(rt2x00dev, intf, &conf);
if (delayed_flags & DELAYED_LED_ASSOC)
rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
@@ -487,7 +488,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter,
rt2x00dev);
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
}
EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
@@ -1130,6 +1131,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
/*
* Initialize configuration work.
*/
+ rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib");
+ if (!rt2x00dev->workqueue)
+ goto exit;
+
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
@@ -1190,6 +1195,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
rt2x00leds_unregister(rt2x00dev);
/*
+ * Stop all queued work. Note that most tasks will already be halted
+ * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
+ */
+ flush_workqueue(rt2x00dev->workqueue);
+ destroy_workqueue(rt2x00dev->workqueue);
+
+ /*
* Free ieee80211_hw memory.
*/
rt2x00lib_remove_hw(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 87e280a2197..9cb023edd2e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -428,7 +428,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
else
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work);
}
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
@@ -509,7 +509,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
if (delayed) {
intf->delayed_flags |= delayed;
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
}
spin_unlock(&intf->lock);
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index fff8386e816..83cc0147f69 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt73usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
- mutex_unlock(&rt2x00dev->usb_cache_mutex);
- return;
- }
+ if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+ goto exit_fail;
/*
* Write the data into the BBP.
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ return;
+
+exit_fail:
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
}
static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt73usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
- mutex_unlock(&rt2x00dev->usb_cache_mutex);
- return;
- }
+ if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+ goto exit_fail;
/*
* Write the request into the BBP.
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt73usb_bbp_check(rt2x00dev);
- if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
- ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
- *value = 0xff;
- return;
- }
+ if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+ goto exit_fail;
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ return;
+
+exit_fail:
+ mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+ ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
+ *value = 0xff;
}
static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index ec8f7002b09..39bb96b413e 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -178,8 +178,7 @@ static int pci_vpd_pci22_read(struct pci_dev *dev, int pos, int size,
int ret;
int begin, end, i;
- if (pos < 0 || pos > PCI_VPD_PCI22_SIZE ||
- size > PCI_VPD_PCI22_SIZE - pos)
+ if (pos < 0 || pos > vpd->base.len || size > vpd->base.len - pos)
return -EINVAL;
if (size == 0)
return 0;
@@ -223,8 +222,8 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size,
u32 val;
int ret;
- if (pos < 0 || pos > PCI_VPD_PCI22_SIZE || pos & 3 ||
- size > PCI_VPD_PCI22_SIZE - pos || size < 4)
+ if (pos < 0 || pos > vpd->base.len || pos & 3 ||
+ size > vpd->base.len - pos || size < 4)
return -EINVAL;
val = (u8) *buf++;
@@ -255,11 +254,6 @@ out:
return 4;
}
-static int pci_vpd_pci22_get_size(struct pci_dev *dev)
-{
- return PCI_VPD_PCI22_SIZE;
-}
-
static void pci_vpd_pci22_release(struct pci_dev *dev)
{
kfree(container_of(dev->vpd, struct pci_vpd_pci22, base));
@@ -268,7 +262,6 @@ static void pci_vpd_pci22_release(struct pci_dev *dev)
static struct pci_vpd_ops pci_vpd_pci22_ops = {
.read = pci_vpd_pci22_read,
.write = pci_vpd_pci22_write,
- .get_size = pci_vpd_pci22_get_size,
.release = pci_vpd_pci22_release,
};
@@ -284,6 +277,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
if (!vpd)
return -ENOMEM;
+ vpd->base.len = PCI_VPD_PCI22_SIZE;
vpd->base.ops = &pci_vpd_pci22_ops;
spin_lock_init(&vpd->lock);
vpd->cap = cap;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 648596d469f..91156f85a92 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -700,9 +700,10 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
cleanup_p2p_bridge, NULL, NULL);
- if (!(bridge = acpiphp_handle_to_bridge(handle)))
- return AE_OK;
- cleanup_bridge(bridge);
+ bridge = acpiphp_handle_to_bridge(handle);
+ if (bridge)
+ cleanup_bridge(bridge);
+
return AE_OK;
}
@@ -715,9 +716,19 @@ static void remove_bridge(acpi_handle handle)
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
(u32)1, cleanup_p2p_bridge, NULL, NULL);
+ /*
+ * On root bridges with hotplug slots directly underneath (ie,
+ * no p2p bridge inbetween), we call cleanup_bridge().
+ *
+ * The else clause cleans up root bridges that either had no
+ * hotplug slots at all, or had a p2p bridge underneath.
+ */
bridge = acpiphp_handle_to_bridge(handle);
if (bridge)
cleanup_bridge(bridge);
+ else
+ acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_bridge);
}
static struct pci_dev * get_apic_pci_info(acpi_handle handle)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6f3c7446c32..9c718583a23 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -736,9 +736,9 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
if (attr) {
pdev->vpd->attr = attr;
- attr->size = pdev->vpd->ops->get_size(pdev);
+ attr->size = pdev->vpd->len;
attr->attr.name = "vpd";
- attr->attr.mode = S_IRUGO | S_IWUSR;
+ attr->attr.mode = S_IRUSR | S_IWUSR;
attr->read = pci_read_vpd;
attr->write = pci_write_vpd;
retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0a497c1b422..00408c97e5f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -21,11 +21,11 @@ extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val);
struct pci_vpd_ops {
int (*read)(struct pci_dev *dev, int pos, int size, char *buf);
int (*write)(struct pci_dev *dev, int pos, int size, const char *buf);
- int (*get_size)(struct pci_dev *dev);
void (*release)(struct pci_dev *dev);
};
struct pci_vpd {
+ unsigned int len;
struct pci_vpd_ops *ops;
struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
};
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index dabb563f51d..a3497dc6ebc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1670,6 +1670,48 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
+/*
+ * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
+ * VPD end tag will hang the device. This problem was initially
+ * observed when a vpd entry was created in sysfs
+ * ('/sys/bus/pci/devices/<id>/vpd'). A read to this sysfs entry
+ * will dump 32k of data. Reading a full 32k will cause an access
+ * beyond the VPD end tag causing the device to hang. Once the device
+ * is hung, the bnx2 driver will not be able to reset the device.
+ * We believe that it is legal to read beyond the end tag and
+ * therefore the solution is to limit the read/write length.
+ */
+static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
+{
+ /* Only disable the VPD capability for 5706, 5708, and 5709 rev. A */
+ if ((dev->device == PCI_DEVICE_ID_NX2_5706) ||
+ (dev->device == PCI_DEVICE_ID_NX2_5708) ||
+ ((dev->device == PCI_DEVICE_ID_NX2_5709) &&
+ (dev->revision & 0xf0) == 0x0)) {
+ if (dev->vpd)
+ dev->vpd->len = 0x80;
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5706,
+ quirk_brcm_570x_limit_vpd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5706S,
+ quirk_brcm_570x_limit_vpd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5708,
+ quirk_brcm_570x_limit_vpd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5708S,
+ quirk_brcm_570x_limit_vpd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5709,
+ quirk_brcm_570x_limit_vpd);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM,
+ PCI_DEVICE_ID_NX2_5709S,
+ quirk_brcm_570x_limit_vpd);
+
#ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting
* PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 46314b42076..569b746b573 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -38,19 +38,19 @@
#define CF_BASE 0xfffe2800
/* status; read after IRQ */
-#define CF_STATUS_REG __REG16(CF_BASE + 0x00)
+#define CF_STATUS (CF_BASE + 0x00)
# define CF_STATUS_BAD_READ (1 << 2)
# define CF_STATUS_BAD_WRITE (1 << 1)
# define CF_STATUS_CARD_DETECT (1 << 0)
/* which chipselect (CS0..CS3) is used for CF (active low) */
-#define CF_CFG_REG __REG16(CF_BASE + 0x02)
+#define CF_CFG (CF_BASE + 0x02)
/* card reset */
-#define CF_CONTROL_REG __REG16(CF_BASE + 0x04)
+#define CF_CONTROL (CF_BASE + 0x04)
# define CF_CONTROL_RESET (1 << 0)
-#define omap_cf_present() (!(CF_STATUS_REG & CF_STATUS_CARD_DETECT))
+#define omap_cf_present() (!(omap_readw(CF_STATUS) & CF_STATUS_CARD_DETECT))
/*--------------------------------------------------------------------------*/
@@ -139,11 +139,11 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
return -EINVAL;
}
- control = CF_CONTROL_REG;
+ control = omap_readw(CF_CONTROL);
if (s->flags & SS_RESET)
- CF_CONTROL_REG = CF_CONTROL_RESET;
+ omap_writew(CF_CONTROL_RESET, CF_CONTROL);
else
- CF_CONTROL_REG = 0;
+ omap_writew(0, CF_CONTROL);
pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
@@ -270,7 +270,7 @@ static int __init omap_cf_probe(struct platform_device *pdev)
omap_cfg_reg(V10_1610_CF_IREQ);
omap_cfg_reg(W10_1610_CF_RESET);
- CF_CFG_REG = ~(1 << seg);
+ omap_writew(~(1 << seg), CF_CFG);
pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq);
@@ -279,14 +279,15 @@ static int __init omap_cf_probe(struct platform_device *pdev)
* CF/PCMCIA variants...
*/
pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name,
- seg, EMIFS_CCS(seg), EMIFS_ACS(seg));
- EMIFS_CCS(seg) = 0x0004a1b3; /* synch mode 4 etc */
- EMIFS_ACS(seg) = 0x00000000; /* OE hold/setup */
+ seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg)));
+ omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */
+ omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */
/* CF uses armxor_ck, which is "always" available */
pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name,
- CF_STATUS_REG, CF_CFG_REG, CF_CONTROL_REG,
+ omap_readw(CF_STATUS), omap_readw(CF_CFG),
+ omap_readw(CF_CONTROL),
omap_cf_present() ? "present" : "(not present)");
cf->socket.owner = THIS_MODULE;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4949dc4859b..fc85bf2e4a9 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -469,6 +469,16 @@ config RTC_DRV_VR41XX
To compile this driver as a module, choose M here: the
module will be called rtc-vr41xx.
+config RTC_DRV_PL030
+ tristate "ARM AMBA PL030 RTC"
+ depends on ARM_AMBA
+ help
+ If you say Y here you will get access to ARM AMBA
+ PrimeCell PL030 RTC found on certain ARM SOCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rtc-pl030.
+
config RTC_DRV_PL031
tristate "ARM AMBA PL031 RTC"
depends on ARM_AMBA
@@ -495,12 +505,13 @@ config RTC_DRV_AT91RM9200
this is powered by the backup power supply.
config RTC_DRV_AT91SAM9
- tristate "AT91SAM9x"
+ tristate "AT91SAM9x/AT91CAP9"
depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40)
help
- RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer).
- These timers are powered by the backup power supply (such as a
- small coin cell battery), but do not need to be used as RTCs.
+ RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT
+ (Real Time Timer). These timers are powered by the backup power
+ supply (such as a small coin cell battery), but do not need to
+ be used as RTCs.
(On AT91SAM9rl chips you probably want to use the dedicated RTC
module and leave the RTT available for other uses.)
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b6e14d51670..b5d9d67df88 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
+obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 39e64ab1ecb..9c3db934cc2 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -29,10 +29,6 @@
#include <linux/completion.h>
#include <asm/uaccess.h>
-#include <asm/rtc.h>
-
-#include <asm/mach/time.h>
-
#include <asm/arch/at91_rtc.h>
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 38d8742a4bd..f0246ef413a 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/ioctl.h>
-#include <asm/mach/time.h>
#include <asm/arch/board.h>
#include <asm/arch/at91_rtt.h>
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 58f81c77494..eb23d8423f4 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -22,7 +22,6 @@
#include <linux/platform_device.h>
#include <asm/io.h>
-#include <asm/mach/time.h>
/* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
new file mode 100644
index 00000000000..8448eeb9d67
--- /dev/null
+++ b/drivers/rtc/rtc-pl030.c
@@ -0,0 +1,217 @@
+/*
+ * linux/drivers/rtc/rtc-pl030.c
+ *
+ * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+
+#define RTC_DR (0)
+#define RTC_MR (4)
+#define RTC_STAT (8)
+#define RTC_EOI (8)
+#define RTC_LR (12)
+#define RTC_CR (16)
+#define RTC_CR_MIE (1 << 0)
+
+struct pl030_rtc {
+ struct rtc_device *rtc;
+ void __iomem *base;
+};
+
+static irqreturn_t pl030_interrupt(int irq, void *dev_id)
+{
+ struct pl030_rtc *rtc = dev_id;
+ writel(0, rtc->base + RTC_EOI);
+ return IRQ_HANDLED;
+}
+
+static int pl030_open(struct device *dev)
+{
+ return 0;
+}
+
+static void pl030_release(struct device *dev)
+{
+}
+
+static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pl030_rtc *rtc = dev_get_drvdata(dev);
+
+ rtc_time_to_tm(readl(rtc->base + RTC_MR), &alrm->time);
+ return 0;
+}
+
+static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pl030_rtc *rtc = dev_get_drvdata(dev);
+ unsigned long time;
+ int ret;
+
+ /*
+ * At the moment, we can only deal with non-wildcarded alarm times.
+ */
+ ret = rtc_valid_tm(&alrm->time);
+ if (ret == 0)
+ ret = rtc_tm_to_time(&alrm->time, &time);
+ if (ret == 0)
+ writel(time, rtc->base + RTC_MR);
+ return ret;
+}
+
+static int pl030_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pl030_rtc *rtc = dev_get_drvdata(dev);
+
+ rtc_time_to_tm(readl(rtc->base + RTC_DR), tm);
+
+ return 0;
+}
+
+/*
+ * Set the RTC time. Unfortunately, we can't accurately set
+ * the point at which the counter updates.
+ *
+ * Also, since RTC_LR is transferred to RTC_CR on next rising
+ * edge of the 1Hz clock, we must write the time one second
+ * in advance.
+ */
+static int pl030_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pl030_rtc *rtc = dev_get_drvdata(dev);
+ unsigned long time;
+ int ret;
+
+ ret = rtc_tm_to_time(tm, &time);
+ if (ret == 0)
+ writel(time + 1, rtc->base + RTC_LR);
+
+ return ret;
+}
+
+static const struct rtc_class_ops pl030_ops = {
+ .open = pl030_open,
+ .release = pl030_release,
+ .ioctl = pl030_ioctl,
+ .read_time = pl030_read_time,
+ .set_time = pl030_set_time,
+ .read_alarm = pl030_read_alarm,
+ .set_alarm = pl030_set_alarm,
+};
+
+static int pl030_probe(struct amba_device *dev, void *id)
+{
+ struct pl030_rtc *rtc;
+ int ret;
+
+ ret = amba_request_regions(dev, NULL);
+ if (ret)
+ goto err_req;
+
+ rtc = kmalloc(sizeof(*rtc), GFP_KERNEL);
+ if (!rtc) {
+ ret = -ENOMEM;
+ goto err_rtc;
+ }
+
+ rtc->base = ioremap(dev->res.start, SZ_4K);
+ if (!rtc->base) {
+ ret = -ENOMEM;
+ goto err_map;
+ }
+
+ __raw_writel(0, rtc->base + RTC_CR);
+ __raw_writel(0, rtc->base + RTC_EOI);
+
+ amba_set_drvdata(dev, rtc);
+
+ ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED,
+ "rtc-pl030", rtc);
+ if (ret)
+ goto err_irq;
+
+ rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc->rtc)) {
+ ret = PTR_ERR(rtc->rtc);
+ goto err_reg;
+ }
+
+ return 0;
+
+ err_reg:
+ free_irq(dev->irq[0], rtc);
+ err_irq:
+ iounmap(rtc->base);
+ err_map:
+ kfree(rtc);
+ err_rtc:
+ amba_release_regions(dev);
+ err_req:
+ return ret;
+}
+
+static int pl030_remove(struct amba_device *dev)
+{
+ struct pl030_rtc *rtc = amba_get_drvdata(dev);
+
+ amba_set_drvdata(dev, NULL);
+
+ writel(0, rtc->base + RTC_CR);
+
+ free_irq(dev->irq[0], rtc);
+ rtc_device_unregister(rtc->rtc);
+ iounmap(rtc->base);
+ kfree(rtc);
+ amba_release_regions(dev);
+
+ return 0;
+}
+
+static struct amba_id pl030_ids[] = {
+ {
+ .id = 0x00041030,
+ .mask = 0x000fffff,
+ },
+ { 0, 0 },
+};
+
+static struct amba_driver pl030_driver = {
+ .drv = {
+ .name = "rtc-pl030",
+ },
+ .probe = pl030_probe,
+ .remove = pl030_remove,
+ .id_table = pl030_ids,
+};
+
+static int __init pl030_init(void)
+{
+ return amba_driver_register(&pl030_driver);
+}
+
+static void __exit pl030_exit(void)
+{
+ amba_driver_unregister(&pl030_driver);
+}
+
+module_init(pl030_init);
+module_exit(pl030_exit);
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 2fd49edcc71..08b4610ec5a 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -12,23 +12,12 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
-#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/init.h>
-#include <linux/fs.h>
#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-
#include <linux/amba/bus.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/rtc.h>
+#include <linux/io.h>
/*
* Register definitions
@@ -142,13 +131,12 @@ static int pl031_remove(struct amba_device *adev)
{
struct pl031_local *ldata = dev_get_drvdata(&adev->dev);
- if (ldata) {
- dev_set_drvdata(&adev->dev, NULL);
- free_irq(adev->irq[0], ldata->rtc);
- rtc_device_unregister(ldata->rtc);
- iounmap(ldata->base);
- kfree(ldata);
- }
+ amba_set_drvdata(adev, NULL);
+ free_irq(adev->irq[0], ldata->rtc);
+ rtc_device_unregister(ldata->rtc);
+ iounmap(ldata->base);
+ kfree(ldata);
+ amba_release_regions(adev);
return 0;
}
@@ -158,13 +146,15 @@ static int pl031_probe(struct amba_device *adev, void *id)
int ret;
struct pl031_local *ldata;
+ ret = amba_request_regions(adev, NULL);
+ if (ret)
+ goto err_req;
ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
if (!ldata) {
ret = -ENOMEM;
goto out;
}
- dev_set_drvdata(&adev->dev, ldata);
ldata->base = ioremap(adev->res.start,
adev->res.end - adev->res.start + 1);
@@ -173,6 +163,8 @@ static int pl031_probe(struct amba_device *adev, void *id)
goto out_no_remap;
}
+ amba_set_drvdata(adev, ldata);
+
if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
"rtc-pl031", ldata->rtc)) {
ret = -EIO;
@@ -192,10 +184,12 @@ out_no_rtc:
free_irq(adev->irq[0], ldata->rtc);
out_no_irq:
iounmap(ldata->base);
+ amba_set_drvdata(adev, NULL);
out_no_remap:
- dev_set_drvdata(&adev->dev, NULL);
kfree(ldata);
out:
+ amba_release_regions(adev);
+err_req:
return ret;
}
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index f26e0cad8f1..fed86e507fd 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -26,10 +26,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/rtc.h>
-
-#include <asm/mach/time.h>
-
#include <asm/plat-s3c/regs-rtc.h>
/* I have yet to find an S3C implementation with more than one
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 82f62d25f92..f47294c6014 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -33,7 +33,6 @@
#include <asm/hardware.h>
#include <asm/irq.h>
-#include <asm/rtc.h>
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
@@ -47,6 +46,42 @@ static unsigned long rtc_freq = 1024;
static struct rtc_time rtc_alarm;
static DEFINE_SPINLOCK(sa1100_rtc_lock);
+static inline int rtc_periodic_alarm(struct rtc_time *tm)
+{
+ return (tm->tm_year == -1) ||
+ ((unsigned)tm->tm_mon >= 12) ||
+ ((unsigned)(tm->tm_mday - 1) >= 31) ||
+ ((unsigned)tm->tm_hour > 23) ||
+ ((unsigned)tm->tm_min > 59) ||
+ ((unsigned)tm->tm_sec > 59);
+}
+
+/*
+ * Calculate the next alarm time given the requested alarm time mask
+ * and the current time.
+ */
+static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
+{
+ unsigned long next_time;
+ unsigned long now_time;
+
+ next->tm_year = now->tm_year;
+ next->tm_mon = now->tm_mon;
+ next->tm_mday = now->tm_mday;
+ next->tm_hour = alrm->tm_hour;
+ next->tm_min = alrm->tm_min;
+ next->tm_sec = alrm->tm_sec;
+
+ rtc_tm_to_time(now, &now_time);
+ rtc_tm_to_time(next, &next_time);
+
+ if (next_time < now_time) {
+ /* Advance one day */
+ next_time += 60 * 60 * 24;
+ rtc_time_to_tm(next_time, next);
+ }
+}
+
static int rtc_update_alarm(struct rtc_time *alrm)
{
struct rtc_time alarm_tm, now_tm;
@@ -331,14 +366,14 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
RCNR = 0;
}
+ device_init_wakeup(&pdev->dev, 1);
+
rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
- device_init_wakeup(&pdev->dev, 1);
-
platform_set_drvdata(pdev, rtc);
return 0;
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index 7236143941f..a8587f1f5e7 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -3,7 +3,7 @@
#
config SCSI_ACORNSCSI_3
tristate "Acorn SCSI card (aka30) support"
- depends on ARCH_ACORN && SCSI && BROKEN
+ depends on ARCH_ACORN && SCSI
select SCSI_SPI_ATTRS
help
This enables support for the Acorn SCSI card (aka30). If you have an
diff --git a/drivers/scsi/arm/acornscsi-io.S b/drivers/scsi/arm/acornscsi-io.S
index 93467e6ac92..5cebe310526 100644
--- a/drivers/scsi/arm/acornscsi-io.S
+++ b/drivers/scsi/arm/acornscsi-io.S
@@ -10,17 +10,10 @@
#include <asm/assembler.h>
#include <asm/hardware.h>
-#if (IO_BASE == (PCIO_BASE & 0xff000000))
-#define ADDR(off,reg) \
- tst off, $0x80000000 ;\
- mov reg, $IO_BASE ;\
- orreq reg, reg, $(PCIO_BASE & 0x00ff0000)
-#else
-#define ADDR(off,reg) \
- tst off, $0x80000000 ;\
- movne reg, $IO_BASE ;\
- moveq reg, $(PCIO_BASE & 0xff000000) ;\
- orreq reg, reg, $(PCIO_BASE & 0x00ff0000)
+#if defined(__APCS_32__)
+#define LOADREGS(t,r,l...) ldm##t r, l
+#elif defined(__APCS_26__)
+#define LOADREGS(t,r,l...) ldm##t r, l##^
#endif
@ Purpose: transfer a block of data from the acorn scsi card to memory
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 8e53f02cc31..918ccf81875 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -123,12 +123,6 @@
#define DBG(cmd,xxx...) xxx
#endif
-#ifndef STRINGIFY
-#define STRINGIFY(x) #x
-#endif
-#define STRx(x) STRINGIFY(x)
-#define NO_WRITE_STR STRx(NO_WRITE)
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -141,9 +135,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/stringify.h>
+#include <linux/io.h>
#include <asm/system.h>
-#include <asm/io.h>
#include <asm/ecard.h>
#include "../scsi.h"
@@ -203,44 +198,46 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
* Miscellaneous
*/
-static inline void
-sbic_arm_write(unsigned int io_port, int reg, int value)
+/* Offsets from MEMC base */
+#define SBIC_REGIDX 0x2000
+#define SBIC_REGVAL 0x2004
+#define DMAC_OFFSET 0x3000
+
+/* Offsets from FAST IOC base */
+#define INT_REG 0x2000
+#define PAGE_REG 0x3000
+
+static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
{
- __raw_writeb(reg, io_port);
- __raw_writeb(value, io_port + 4);
+ writeb(reg, host->base + SBIC_REGIDX);
+ writeb(value, host->base + SBIC_REGVAL);
}
-#define sbic_arm_writenext(io,val) \
- __raw_writeb((val), (io) + 4)
-
-static inline
-int sbic_arm_read(unsigned int io_port, int reg)
+static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
{
if(reg == SBIC_ASR)
- return __raw_readl(io_port) & 255;
- __raw_writeb(reg, io_port);
- return __raw_readl(io_port + 4) & 255;
+ return readl(host->base + SBIC_REGIDX) & 255;
+ writeb(reg, host->base + SBIC_REGIDX);
+ return readl(host->base + SBIC_REGVAL) & 255;
}
-#define sbic_arm_readnext(io) \
- __raw_readb((io) + 4)
+#define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
+#define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
#ifdef USE_DMAC
-#define dmac_read(io_port,reg) \
- inb((io_port) + (reg))
+#define dmac_read(host,reg) \
+ readb((host)->base + DMAC_OFFSET + ((reg) << 2))
-#define dmac_write(io_port,reg,value) \
- ({ outb((value), (io_port) + (reg)); })
+#define dmac_write(host,reg,value) \
+ ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
-#define dmac_clearintr(io_port) \
- ({ outb(0, (io_port)); })
+#define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
-static inline
-unsigned int dmac_address(unsigned int io_port)
+static inline unsigned int dmac_address(AS_Host *host)
{
- return dmac_read(io_port, DMAC_TXADRHI) << 16 |
- dmac_read(io_port, DMAC_TXADRMD) << 8 |
- dmac_read(io_port, DMAC_TXADRLO);
+ return dmac_read(host, DMAC_TXADRHI) << 16 |
+ dmac_read(host, DMAC_TXADRMD) << 8 |
+ dmac_read(host, DMAC_TXADRLO);
}
static
@@ -248,15 +245,15 @@ void acornscsi_dumpdma(AS_Host *host, char *where)
{
unsigned int mode, addr, len;
- mode = dmac_read(host->dma.io_port, DMAC_MODECON);
- addr = dmac_address(host->dma.io_port);
- len = dmac_read(host->dma.io_port, DMAC_TXCNTHI) << 8 |
- dmac_read(host->dma.io_port, DMAC_TXCNTLO);
+ mode = dmac_read(host, DMAC_MODECON);
+ addr = dmac_address(host);
+ len = dmac_read(host, DMAC_TXCNTHI) << 8 |
+ dmac_read(host, DMAC_TXCNTLO);
printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
host->host->host_no, where,
mode, addr, (len + 1) & 0xffff,
- dmac_read(host->dma.io_port, DMAC_MASKREG));
+ dmac_read(host, DMAC_MASKREG));
printk("DMA @%06x, ", host->dma.start_addr);
printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
@@ -272,9 +269,9 @@ unsigned long acornscsi_sbic_xfcount(AS_Host *host)
{
unsigned long length;
- length = sbic_arm_read(host->scsi.io_port, SBIC_TRANSCNTH) << 16;
- length |= sbic_arm_readnext(host->scsi.io_port) << 8;
- length |= sbic_arm_readnext(host->scsi.io_port);
+ length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16;
+ length |= sbic_arm_readnext(host) << 8;
+ length |= sbic_arm_readnext(host);
return length;
}
@@ -285,7 +282,7 @@ acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *m
int asr;
do {
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if ((asr & stat_mask) == stat)
return 0;
@@ -304,7 +301,7 @@ int acornscsi_sbic_issuecmd(AS_Host *host, int command)
if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
return -1;
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, command);
+ sbic_arm_write(host, SBIC_CMND, command);
return 0;
}
@@ -331,20 +328,20 @@ void acornscsi_resetcard(AS_Host *host)
/* assert reset line */
host->card.page_reg = 0x80;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/* wait 3 cs. SCSI standard says 25ms. */
acornscsi_csdelay(3);
host->card.page_reg = 0;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/*
* Should get a reset from the card
*/
timeout = 1000;
do {
- if (inb(host->card.io_intr) & 8)
+ if (readb(host->fast + INT_REG) & 8)
break;
udelay(1);
} while (--timeout);
@@ -353,19 +350,19 @@ void acornscsi_resetcard(AS_Host *host)
printk("scsi%d: timeout while resetting card\n",
host->host->host_no);
- sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_ASR);
+ sbic_arm_read(host, SBIC_SSR);
/* setup sbic - WD33C93A */
- sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);
+ sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host, SBIC_CMND, CMND_RESET);
/*
* Command should cause a reset interrupt
*/
timeout = 1000;
do {
- if (inb(host->card.io_intr) & 8)
+ if (readb(host->fast + INT_REG) & 8)
break;
udelay(1);
} while (--timeout);
@@ -374,26 +371,26 @@ void acornscsi_resetcard(AS_Host *host)
printk("scsi%d: timeout while resetting card\n",
host->host->host_no);
- sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- if (sbic_arm_read(host->scsi.io_port, SBIC_SSR) != 0x01)
+ sbic_arm_read(host, SBIC_ASR);
+ if (sbic_arm_read(host, SBIC_SSR) != 0x01)
printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
host->host->host_no);
- sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->card.page_reg = 0x40;
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
/* setup dmac - uPC71071 */
- dmac_write(host->dma.io_port, DMAC_INIT, 0);
+ dmac_write(host, DMAC_INIT, 0);
#ifdef USE_DMAC
- dmac_write(host->dma.io_port, DMAC_INIT, INIT_8BIT);
- dmac_write(host->dma.io_port, DMAC_CHANNEL, CHANNEL_0);
- dmac_write(host->dma.io_port, DMAC_DEVCON0, INIT_DEVCON0);
- dmac_write(host->dma.io_port, DMAC_DEVCON1, INIT_DEVCON1);
+ dmac_write(host, DMAC_INIT, INIT_8BIT);
+ dmac_write(host, DMAC_CHANNEL, CHANNEL_0);
+ dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0);
+ dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1);
#endif
host->SCpnt = NULL;
@@ -741,9 +738,9 @@ intr_ret_t acornscsi_kick(AS_Host *host)
* If we have an interrupt pending, then we may have been reselected.
* In this case, we don't want to write to the registers
*/
- if (!(sbic_arm_read(host->scsi.io_port, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
- sbic_arm_write(host->scsi.io_port, SBIC_DESTID, SCpnt->device->id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_SELWITHATN);
+ if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
+ sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id);
+ sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN);
}
/*
@@ -807,7 +804,7 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
struct scsi_cmnd *SCpnt = *SCpntp;
/* clean up */
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
host->stats.fins += 1;
@@ -918,13 +915,13 @@ static
void acornscsi_data_read(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_in(int port, char *buf, int len);
+ extern void __acornscsi_in(void __iomem *, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
while (len > 0) {
unsigned int this_len;
@@ -934,7 +931,7 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
else
this_len = len;
- __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_in(host->base + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -943,10 +940,10 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
}
}
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
}
/*
@@ -963,13 +960,13 @@ static
void acornscsi_data_write(AS_Host *host, char *ptr,
unsigned int start_addr, unsigned int length)
{
- extern void __acornscsi_out(int port, char *buf, int len);
+ extern void __acornscsi_out(void __iomem *, char *buf, int len);
unsigned int page, offset, len = length;
page = (start_addr >> 12);
offset = start_addr & ((1 << 12) - 1);
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
while (len > 0) {
unsigned int this_len;
@@ -979,7 +976,7 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
else
this_len = len;
- __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len);
+ __acornscsi_out(host->base + (offset << 1), ptr, this_len);
offset += this_len;
ptr += this_len;
@@ -988,10 +985,10 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
if (offset == (1 << 12)) {
offset = 0;
page ++;
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
}
}
- outb(host->card.page_reg, host->card.io_page);
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
}
/* =========================================================================================
@@ -1008,8 +1005,8 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
static inline
void acornscsi_dma_stop(AS_Host *host)
{
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
@@ -1031,7 +1028,7 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
host->dma.direction = direction;
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
if (direction == DMA_OUT) {
#if (DEBUG & DEBUG_NO_WRITE)
@@ -1062,13 +1059,13 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
length);
length -= 1;
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MODECON, mode);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, length);
+ dmac_write(host, DMAC_TXCNTHI, length >> 8);
+ dmac_write(host, DMAC_TXADRLO, address);
+ dmac_write(host, DMAC_TXADRMD, address >> 8);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MODECON, mode);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
@@ -1088,8 +1085,8 @@ void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
static
void acornscsi_dma_cleanup(AS_Host *host)
{
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
/*
* Check for a pending transfer
@@ -1116,7 +1113,7 @@ void acornscsi_dma_cleanup(AS_Host *host)
/*
* Calculate number of bytes transferred from DMA.
*/
- transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host) - host->dma.start_addr;
host->dma.transferred += transferred;
if (host->dma.direction == DMA_IN)
@@ -1152,13 +1149,13 @@ void acornscsi_dma_intr(AS_Host *host)
DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
#endif
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
- dmac_clearintr(host->dma.io_intr_clear);
+ dmac_write(host, DMAC_MASKREG, MASK_ON);
+ dmac_clearintr(host);
/*
* Calculate amount transferred via DMA
*/
- transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
+ transferred = dmac_address(host) - host->dma.start_addr;
host->dma.transferred += transferred;
/*
@@ -1190,12 +1187,12 @@ void acornscsi_dma_intr(AS_Host *host)
length);
length -= 1;
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, length);
+ dmac_write(host, DMAC_TXCNTHI, length >> 8);
+ dmac_write(host, DMAC_TXADRLO, address);
+ dmac_write(host, DMAC_TXADRMD, address >> 8);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
#if (DEBUG & DEBUG_DMA)
DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
@@ -1209,15 +1206,15 @@ void acornscsi_dma_intr(AS_Host *host)
* attention condition. We continue giving one byte until
* the device recognises the attention.
*/
- if (dmac_read(host->dma.io_port, DMAC_STATUS) & STATUS_RQ0) {
+ if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) {
acornscsi_abortcmd(host, host->SCpnt->tag);
- dmac_write(host->dma.io_port, DMAC_TXCNTLO, 0);
- dmac_write(host->dma.io_port, DMAC_TXCNTHI, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRLO, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, 0);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
- dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
+ dmac_write(host, DMAC_TXCNTLO, 0);
+ dmac_write(host, DMAC_TXCNTHI, 0);
+ dmac_write(host, DMAC_TXADRLO, 0);
+ dmac_write(host, DMAC_TXADRMD, 0);
+ dmac_write(host, DMAC_TXADRHI, 0);
+ dmac_write(host, DMAC_MASKREG, MASK_OFF);
}
#endif
}
@@ -1271,9 +1268,9 @@ void acornscsi_dma_adjust(AS_Host *host)
host->dma.xfer_setup = 0;
else {
transferred += host->dma.start_addr;
- dmac_write(host->dma.io_port, DMAC_TXADRLO, transferred);
- dmac_write(host->dma.io_port, DMAC_TXADRMD, transferred >> 8);
- dmac_write(host->dma.io_port, DMAC_TXADRHI, transferred >> 16);
+ dmac_write(host, DMAC_TXADRLO, transferred);
+ dmac_write(host, DMAC_TXADRMD, transferred >> 8);
+ dmac_write(host, DMAC_TXADRHI, transferred >> 16);
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
#endif
@@ -1292,12 +1289,12 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int
int my_ptr = *ptr;
while (my_ptr < len) {
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (asr & ASR_DBR) {
timeout = max_timeout;
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, bytes[my_ptr++]);
+ sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]);
} else if (asr & ASR_INT)
break;
else if (--timeout == 0)
@@ -1320,9 +1317,9 @@ acornscsi_sendcommand(AS_Host *host)
{
struct scsi_cmnd *SCpnt = host->SCpnt;
- sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
- sbic_arm_writenext(host->scsi.io_port, 0);
- sbic_arm_writenext(host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command);
+ sbic_arm_write(host, SBIC_TRANSCNTH, 0);
+ sbic_arm_writenext(host, 0);
+ sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
@@ -1351,7 +1348,7 @@ void acornscsi_sendmessage(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, NOP);
+ sbic_arm_write(host, SBIC_DATA, NOP);
host->scsi.last_message = NOP;
#if (DEBUG & DEBUG_MESSAGES)
@@ -1365,7 +1362,7 @@ void acornscsi_sendmessage(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
- sbic_arm_write(host->scsi.io_port, SBIC_DATA, msg->msg[0]);
+ sbic_arm_write(host, SBIC_DATA, msg->msg[0]);
host->scsi.last_message = msg->msg[0];
#if (DEBUG & DEBUG_MESSAGES)
@@ -1382,9 +1379,9 @@ void acornscsi_sendmessage(AS_Host *host)
* initiator. This provides an interlock so that the
* initiator can determine which message byte is rejected.
*/
- sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
- sbic_arm_writenext(host->scsi.io_port, 0);
- sbic_arm_writenext(host->scsi.io_port, message_length);
+ sbic_arm_write(host, SBIC_TRANSCNTH, 0);
+ sbic_arm_writenext(host, 0);
+ sbic_arm_writenext(host, message_length);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
msgnr = 0;
@@ -1421,7 +1418,7 @@ void acornscsi_readstatusbyte(AS_Host *host)
{
acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
- host->scsi.SCp.Status = sbic_arm_read(host->scsi.io_port, SBIC_DATA);
+ host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA);
}
/*
@@ -1438,12 +1435,12 @@ unsigned char acornscsi_readmessagebyte(AS_Host *host)
acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
- message = sbic_arm_read(host->scsi.io_port, SBIC_DATA);
+ message = sbic_arm_read(host, SBIC_DATA);
/* wait for MSGIN-XFER-PAUSED */
acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_SSR);
return message;
}
@@ -1480,7 +1477,7 @@ void acornscsi_message(AS_Host *host)
/* wait for next msg-in */
acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
- sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ sbic_arm_read(host, SBIC_SSR);
}
} while (msgidx < msglen);
@@ -1602,7 +1599,7 @@ void acornscsi_message(AS_Host *host)
host->host->host_no, acornscsi_target(host));
host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
break;
default:
@@ -1652,7 +1649,7 @@ void acornscsi_message(AS_Host *host)
host->device[host->SCpnt->device->id].sync_xfer =
calc_sync_xfer(period * 4, length);
}
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
break;
#else
/* We do not accept synchronous transfers. Respond with a
@@ -1792,10 +1789,10 @@ int acornscsi_starttransfer(AS_Host *host)
residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred;
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
- sbic_arm_writenext(host->scsi.io_port, residual >> 16);
- sbic_arm_writenext(host->scsi.io_port, residual >> 8);
- sbic_arm_writenext(host->scsi.io_port, residual);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
+ sbic_arm_writenext(host, residual >> 16);
+ sbic_arm_writenext(host, residual >> 8);
+ sbic_arm_writenext(host, residual);
acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
return 1;
}
@@ -1816,7 +1813,7 @@ int acornscsi_reconnect(AS_Host *host)
{
unsigned int target, lun, ok = 0;
- target = sbic_arm_read(host->scsi.io_port, SBIC_SOURCEID);
+ target = sbic_arm_read(host, SBIC_SOURCEID);
if (!(target & 8))
printk(KERN_ERR "scsi%d: invalid source id after reselection "
@@ -1832,7 +1829,7 @@ int acornscsi_reconnect(AS_Host *host)
host->SCpnt = NULL;
}
- lun = sbic_arm_read(host->scsi.io_port, SBIC_DATA) & 7;
+ lun = sbic_arm_read(host, SBIC_DATA) & 7;
host->scsi.reconnected.target = target;
host->scsi.reconnected.lun = lun;
@@ -1952,7 +1949,7 @@ static
void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
{
host->scsi.phase = PHASE_ABORTED;
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_ASSERTATN);
+ sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN);
msgqueue_flush(&host->scsi.msgs);
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
@@ -1979,11 +1976,11 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
{
unsigned int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (!(asr & ASR_INT))
return INTR_IDLE;
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
#if (DEBUG & DEBUG_PHASES)
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -1999,15 +1996,15 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
host->host->host_no);
/* setup sbic - WD33C93A */
- sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);
+ sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
+ sbic_arm_write(host, SBIC_CMND, CMND_RESET);
return INTR_IDLE;
case 0x01: /* reset state - advanced */
- sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
- sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
- sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
- sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
+ sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
+ sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
+ sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
+ sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
msgqueue_flush(&host->scsi.msgs);
return INTR_IDLE;
@@ -2025,10 +2022,10 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
msgqueue_flush(&host->scsi.msgs);
host->dma.transferred = host->scsi.SCp.scsi_xferred;
/* 33C93 gives next interrupt indicating bus phase */
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
+ asr = sbic_arm_read(host, SBIC_ASR);
if (!(asr & ASR_INT))
break;
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
ADD_STATUS(8, ssr, host->scsi.phase, 1);
ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
goto connected;
@@ -2476,11 +2473,11 @@ acornscsi_intr(int irq, void *dev_id)
do {
ret = INTR_IDLE;
- iostatus = inb(host->card.io_intr);
+ iostatus = readb(host->fast + INT_REG);
if (iostatus & 2) {
acornscsi_dma_intr(host);
- iostatus = inb(host->card.io_intr);
+ iostatus = readb(host->fast + INT_REG);
}
if (iostatus & 8)
@@ -2655,7 +2652,7 @@ static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
* busylun bit.
*/
case PHASE_CONNECTED:
- sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_DISCONNECT);
+ sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT);
host->SCpnt = NULL;
res = res_success_clear;
break;
@@ -2699,8 +2696,8 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
#if (DEBUG & DEBUG_ABORT)
{
int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ asr = sbic_arm_read(host, SBIC_ASR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
printk(KERN_WARNING "acornscsi_abort: ");
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -2731,9 +2728,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
//#if (DEBUG & DEBUG_ABORT)
printk("success\n");
//#endif
- SCpnt->result = DID_ABORT << 16;
- SCpnt->scsi_done(SCpnt);
- result = SCSI_ABORT_SUCCESS;
+ result = SUCCESS;
break;
/*
@@ -2745,7 +2740,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
//#if (DEBUG & DEBUG_ABORT)
printk("snooze\n");
//#endif
- result = SCSI_ABORT_SNOOZE;
+ result = FAILED;
break;
/*
@@ -2755,11 +2750,7 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
default:
case res_not_running:
acornscsi_dumplog(host, SCpnt->device->id);
-#if (DEBUG & DEBUG_ABORT)
- result = SCSI_ABORT_SNOOZE;
-#else
- result = SCSI_ABORT_NOT_RUNNING;
-#endif
+ result = FAILED;
//#if (DEBUG & DEBUG_ABORT)
printk("not running\n");
//#endif
@@ -2770,13 +2761,12 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
}
/*
- * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
+ * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt)
* Purpose : reset a command on this host/reset this host
* Params : SCpnt - command causing reset
- * result - what type of reset to perform
* Returns : one of SCSI_RESET_ macros
*/
-int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
+int acornscsi_bus_reset(struct scsi_cmnd *SCpnt)
{
AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
struct scsi_cmnd *SCptr;
@@ -2787,8 +2777,8 @@ int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
{
int asr, ssr;
- asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
- ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
+ asr = sbic_arm_read(host, SBIC_ASR);
+ ssr = sbic_arm_read(host, SBIC_SSR);
printk(KERN_WARNING "acornscsi_reset: ");
print_sbic_status(asr, ssr, host->scsi.phase);
@@ -2798,28 +2788,16 @@ int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
acornscsi_dma_stop(host);
- SCptr = host->SCpnt;
-
/*
* do hard reset. This resets all devices on this host, and so we
* must set the reset status on all commands.
*/
acornscsi_resetcard(host);
- /*
- * report reset on commands current connected/disconnected
- */
- acornscsi_reportstatus(&host->SCpnt, &SCptr, DID_RESET);
-
while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
- acornscsi_reportstatus(&SCptr, &SCpnt, DID_RESET);
-
- if (SCpnt) {
- SCpnt->result = DID_RESET << 16;
- SCpnt->scsi_done(SCpnt);
- }
+ ;
- return SCSI_RESET_BUS_RESET | SCSI_RESET_HOST_RESET | SCSI_RESET_SUCCESS;
+ return SUCCESS;
}
/*==============================================================================================
@@ -2850,7 +2828,7 @@ char *acornscsi_info(struct Scsi_Host *host)
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
- " NOWRITE ("NO_WRITE_STR")"
+ " NOWRITE (" __stringify(NO_WRITE) ")"
#endif
, host->hostt->name, host->io_port, host->irq,
VER_MAJOR, VER_MINOR, VER_PATCH);
@@ -2881,15 +2859,15 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
- " NOWRITE ("NO_WRITE_STR")"
+ " NOWRITE (" __stringify(NO_WRITE) ")"
#endif
"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
- p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n",
- host->scsi.io_port, host->scsi.irq);
+ p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n",
+ host->base + SBIC_REGIDX, host->scsi.irq);
#ifdef USE_DMAC
- p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n",
- host->dma.io_port, host->scsi.irq);
+ p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
+ host->base + DMAC_OFFSET, host->scsi.irq);
#endif
p += sprintf(p, "Statistics:\n"
@@ -2976,9 +2954,8 @@ static struct scsi_host_template acornscsi_template = {
.name = "AcornSCSI",
.info = acornscsi_info,
.queuecommand = acornscsi_queuecmd,
-#warning fixme
- .abort = acornscsi_abort,
- .reset = acornscsi_reset,
+ .eh_abort_handler = acornscsi_abort,
+ .eh_bus_reset_handler = acornscsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
@@ -2992,48 +2969,37 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct Scsi_Host *host;
AS_Host *ashost;
- int ret = -ENOMEM;
+ int ret;
- host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
- if (!host)
+ ret = ecard_request_resources(ec);
+ if (ret)
goto out;
+ host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
+ if (!host) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
ashost = (AS_Host *)host->hostdata;
- host->io_port = ecard_address(ec, ECARD_MEMC, 0);
- host->irq = ec->irq;
+ ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
+ ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
+ if (!ashost->base || !ashost->fast)
+ goto out_put;
- ashost->host = host;
- ashost->scsi.io_port = ioaddr(host->io_port + 0x800);
- ashost->scsi.irq = host->irq;
- ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800;
- ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00;
- ashost->card.io_ram = ioaddr(host->io_port);
- ashost->dma.io_port = host->io_port + 0xc00;
- ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;
+ host->irq = ec->irq;
+ ashost->host = host;
+ ashost->scsi.irq = host->irq;
- ec->irqaddr = (char *)ioaddr(ashost->card.io_intr);
+ ec->irqaddr = ashost->fast + INT_REG;
ec->irqmask = 0x0a;
- ret = -EBUSY;
- if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
- goto err_1;
- if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
- goto err_2;
- if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
- goto err_3;
-#ifdef USE_DMAC
- if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
- goto err_4;
-#endif
- if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
- goto err_5;
-
ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost);
if (ret) {
printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
host->host_no, ashost->scsi.irq, ret);
- goto err_6;
+ goto out_put;
}
memset(&ashost->stats, 0, sizeof (ashost->stats));
@@ -3045,27 +3011,22 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
ret = scsi_add_host(host, &ec->dev);
if (ret)
- goto err_7;
+ goto out_irq;
scsi_scan_host(host);
goto out;
- err_7:
+ out_irq:
free_irq(host->irq, ashost);
- err_6:
- release_region(host->io_port, 2048);
- err_5:
-#ifdef USE_DMAC
- release_region(ashost->dma.io_port, 256);
-#endif
- err_4:
- release_region(ashost->card.io_page, 1);
- err_3:
- release_region(ashost->card.io_intr, 1);
- err_2:
- release_region(host->io_port + 0x800, 2);
- err_1:
+ msgqueue_free(&ashost->scsi.msgs);
+ queue_free(&ashost->queues.disconnected);
+ queue_free(&ashost->queues.issue);
+ out_put:
+ ecardm_iounmap(ec, ashost->fast);
+ ecardm_iounmap(ec, ashost->base);
scsi_host_put(host);
+ out_release:
+ ecard_release_resources(ec);
out:
return ret;
}
@@ -3081,20 +3042,17 @@ static void __devexit acornscsi_remove(struct expansion_card *ec)
/*
* Put card into RESET state
*/
- outb(0x80, ashost->card.io_page);
+ writeb(0x80, ashost->fast + PAGE_REG);
free_irq(host->irq, ashost);
- release_region(host->io_port + 0x800, 2);
- release_region(ashost->card.io_intr, 1);
- release_region(ashost->card.io_page, 1);
- release_region(ashost->dma.io_port, 256);
- release_region(host->io_port, 2048);
-
msgqueue_free(&ashost->scsi.msgs);
queue_free(&ashost->queues.disconnected);
queue_free(&ashost->queues.issue);
+ ecardm_iounmap(ec, ashost->fast);
+ ecardm_iounmap(ec, ashost->base);
scsi_host_put(host);
+ ecard_release_resources(ec);
}
static const struct ecard_id acornscsi_cids[] = {
diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h
index d11424b89f4..8d2172a0b35 100644
--- a/drivers/scsi/arm/acornscsi.h
+++ b/drivers/scsi/arm/acornscsi.h
@@ -179,7 +179,6 @@
/* miscellaneous internal variables */
-#define POD_SPACE(x) ((x) + 0xd0000)
#define MASK_ON (MASKREG_M3|MASKREG_M2|MASKREG_M1|MASKREG_M0)
#define MASK_OFF (MASKREG_M3|MASKREG_M2|MASKREG_M1)
@@ -279,10 +278,11 @@ typedef struct acornscsi_hostdata {
struct Scsi_Host *host; /* host */
struct scsi_cmnd *SCpnt; /* currently processing command */
struct scsi_cmnd *origSCpnt; /* original connecting command */
+ void __iomem *base; /* memc base address */
+ void __iomem *fast; /* fast ioc base address */
/* driver information */
struct {
- unsigned int io_port; /* base address of WD33C93 */
unsigned int irq; /* interrupt */
phase_t phase; /* current phase */
@@ -329,8 +329,6 @@ typedef struct acornscsi_hostdata {
/* DMA info */
struct {
- unsigned int io_port; /* base address of DMA controller */
- unsigned int io_intr_clear; /* address of DMA interrupt clear */
unsigned int free_addr; /* next free address */
unsigned int start_addr; /* start address of current transfer */
dmadir_t direction; /* dma direction */
@@ -345,9 +343,6 @@ typedef struct acornscsi_hostdata {
/* card info */
struct {
- unsigned int io_intr; /* base address of interrupt id reg */
- unsigned int io_page; /* base address of page reg */
- unsigned int io_ram; /* base address of RAM access */
unsigned char page_reg; /* current setting of page reg */
} card;
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index a0b6d414953..59fbef08d69 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -2359,6 +2359,24 @@ void scsi_esp_unregister(struct esp *esp)
}
EXPORT_SYMBOL(scsi_esp_unregister);
+static int esp_target_alloc(struct scsi_target *starget)
+{
+ struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+ struct esp_target_data *tp = &esp->target[starget->id];
+
+ tp->starget = starget;
+
+ return 0;
+}
+
+static void esp_target_destroy(struct scsi_target *starget)
+{
+ struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+ struct esp_target_data *tp = &esp->target[starget->id];
+
+ tp->starget = NULL;
+}
+
static int esp_slave_alloc(struct scsi_device *dev)
{
struct esp *esp = shost_priv(dev->host);
@@ -2370,8 +2388,6 @@ static int esp_slave_alloc(struct scsi_device *dev)
return -ENOMEM;
dev->hostdata = lp;
- tp->starget = dev->sdev_target;
-
spi_min_period(tp->starget) = esp->min_period;
spi_max_offset(tp->starget) = 15;
@@ -2608,6 +2624,8 @@ struct scsi_host_template scsi_esp_template = {
.name = "esp",
.info = esp_info,
.queuecommand = esp_queuecommand,
+ .target_alloc = esp_target_alloc,
+ .target_destroy = esp_target_destroy,
.slave_alloc = esp_slave_alloc,
.slave_configure = esp_slave_configure,
.slave_destroy = esp_slave_destroy,
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 45df83b9d84..0fe031f003e 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -61,7 +61,7 @@ static int ses_probe(struct device *dev)
return err;
}
-#define SES_TIMEOUT 30
+#define SES_TIMEOUT (30 * HZ)
#define SES_RETRIES 3
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9bc42763623..5a9754455ee 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -448,22 +448,27 @@ config SERIAL_CLPS711X_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
-config SERIAL_S3C2410
- tristate "Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support"
- depends on ARM && ARCH_S3C2410
- select SERIAL_CORE
+config SERIAL_SAMSUNG
+ tristate "Samsung SoC serial support"
+ depends on ARM && PLAT_S3C24XX
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port
pins are configured.
- Currently this driver supports the UARTS on the S3C2410, S3C2440,
- S3C2442, S3C2412 and S3C2413 CPUs.
+config SERIAL_SAMSUNG_DEBUG
+ bool "Samsung SoC serial debug"
+ depends on SERIAL_SAMSUNG
+ help
+ Add support for debugging the serial driver. Since this is
+ generally being used as a console, we use our own output
+ routines that go via the low-level debug printascii()
+ function.
-config SERIAL_S3C2410_CONSOLE
- bool "Support for console on S3C2410 serial port"
- depends on SERIAL_S3C2410=y
+config SERIAL_SAMSUNG_CONSOLE
+ bool "Support for console on Samsung SoC serial port"
+ depends on SERIAL_SAMSUNG=y
select SERIAL_CORE_CONSOLE
help
Allow selection of the S3C24XX on-board serial ports for use as
@@ -476,6 +481,37 @@ config SERIAL_S3C2410_CONSOLE
your boot loader about how to pass options to the kernel at
boot time.)
+config SERIAL_S3C2400
+ tristate "Samsung S3C2410 Serial port support"
+ depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400
+ default y if CPU_S3C2400
+ help
+ Serial port support for the Samsung S3C2400 SoC
+
+config SERIAL_S3C2410
+ tristate "Samsung S3C2410 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S3C2410
+ default y if CPU_S3C2410
+ help
+ Serial port support for the Samsung S3C2410 SoC
+
+config SERIAL_S3C2412
+ tristate "Samsung S3C2412/S3C2413 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S3C2412
+ default y if CPU_S3C2412
+ help
+ Serial port support for the Samsung S3C2412 and S3C2413 SoC
+
+config SERIAL_S3C2440
+ tristate "Samsung S3C2440/S3C2442 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
+ default y if CPU_S3C2440
+ default y if CPU_S3C2442
+ help
+ Serial port support for the Samsung S3C2440 and S3C2442 SoC
+
+
+
config SERIAL_DZ
bool "DECstation DZ serial driver"
depends on MACH_DECSTATION && 32BIT
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 0d9c09b1e83..7d85c1fbe7e 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -28,7 +28,11 @@ obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
+obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
+obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
+obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
+obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
new file mode 100644
index 00000000000..a1102053e55
--- /dev/null
+++ b/drivers/serial/s3c2400.c
@@ -0,0 +1,106 @@
+/* linux/drivers/serial/s3c240.c
+ *
+ * Driver for Samsung SoC onboard UARTs.
+ *
+ * Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/irq.h>
+
+#include <asm/hardware.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "samsung.h"
+
+static int s3c2400_serial_getsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ clk->divisor = 1;
+ clk->name = "pclk";
+
+ return 0;
+}
+
+static int s3c2400_serial_setsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ return 0;
+}
+
+static int s3c2400_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ dbg("s3c2400_serial_resetport: port=%p (%08lx), cfg=%p\n",
+ port, port->mapbase, cfg);
+
+ wr_regl(port, S3C2410_UCON, cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
+
+static struct s3c24xx_uart_info s3c2400_uart_inf = {
+ .name = "Samsung S3C2400 UART",
+ .type = PORT_S3C2400,
+ .fifosize = 16,
+ .rx_fifomask = S3C2410_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2410_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2410_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2410_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
+ .get_clksrc = s3c2400_serial_getsource,
+ .set_clksrc = s3c2400_serial_setsource,
+ .reset_port = s3c2400_serial_resetport,
+};
+
+static int s3c2400_serial_probe(struct platform_device *dev)
+{
+ return s3c24xx_serial_probe(dev, &s3c2400_uart_inf);
+}
+
+static struct platform_driver s3c2400_serial_drv = {
+ .probe = s3c2400_serial_probe,
+ .remove = s3c24xx_serial_remove,
+ .driver = {
+ .name = "s3c2400-uart",
+ .owner = THIS_MODULE,
+ },
+};
+
+s3c24xx_console_init(&s3c2400_serial_drv, &s3c2400_uart_inf);
+
+static inline int s3c2400_serial_init(void)
+{
+ return s3c24xx_serial_init(&s3c2400_serial_drv, &s3c2400_uart_inf);
+}
+
+static inline void s3c2400_serial_exit(void)
+{
+ platform_driver_unregister(&s3c2400_serial_drv);
+}
+
+module_init(s3c2400_serial_init);
+module_exit(s3c2400_serial_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C2400 SoC Serial port driver");
+MODULE_ALIAS("platform:s3c2400-uart");
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 2b6a013639e..c5f03f41686 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1,1270 +1,30 @@
-/*
- * linux/drivers/serial/s3c2410.c
+/* linux/drivers/serial/s3c2410.c
*
- * Driver for onboard UARTs on the Samsung S3C24XX
+ * Driver for Samsung S3C2410 SoC onboard UARTs.
*
- * Based on drivers/char/serial.c and drivers/char/21285.c
+ * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
*
- * Ben Dooks, (c) 2003-2005 Simtec Electronics
- * http://www.simtec.co.uk/products/SWLINUX/
- *
- * Changelog:
- *
- * 22-Jul-2004 BJD Finished off device rewrite
- *
- * 21-Jul-2004 BJD Thanks to <herbet@13thfloor.at> for pointing out
- * problems with baud rate and loss of IR settings. Update
- * to add configuration via platform_device structure
- *
- * 28-Sep-2004 BJD Re-write for the following items
- * - S3C2410 and S3C2440 serial support
- * - Power Management support
- * - Fix console via IrDA devices
- * - SysReq (Herbert Pötzl)
- * - Break character handling (Herbert Pötzl)
- * - spin-lock initialisation (Dimitry Andric)
- * - added clock control
- * - updated init code to use platform_device info
- *
- * 06-Mar-2005 BJD Add s3c2440 fclk clock source
- *
- * 09-Mar-2005 BJD Add s3c2400 support
- *
- * 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART
-*/
-
-/* Note on 2440 fclk clock source handling
- *
- * Whilst it is possible to use the fclk as clock source, the method
- * of properly switching too/from this is currently un-implemented, so
- * whichever way is configured at startup is the one that will be used.
-*/
-
-/* Hote on 2410 error handling
- *
- * The s3c2410 manual has a love/hate affair with the contents of the
- * UERSTAT register in the UART blocks, and keeps marking some of the
- * error bits as reserved. Having checked with the s3c2410x01,
- * it copes with BREAKs properly, so I am happy to ignore the RESERVED
- * feature from the latter versions of the manual.
- *
- * If it becomes aparrent that latter versions of the 2410 remove these
- * bits, then action will have to be taken to differentiate the versions
- * and change the policy on BREAK
- *
- * BJD, 04-Nov-2004
+ * 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.
*/
-
-#if defined(CONFIG_SERIAL_S3C2410_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
#include <linux/module.h>
#include <linux/ioport.h>
+#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
-#include <linux/sysrq.h>
-#include <linux/console.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <asm/io.h>
#include <asm/irq.h>
-
#include <asm/hardware.h>
#include <asm/plat-s3c/regs-serial.h>
#include <asm/arch/regs-gpio.h>
-/* structures */
-
-struct s3c24xx_uart_info {
- char *name;
- unsigned int type;
- unsigned int fifosize;
- unsigned long rx_fifomask;
- unsigned long rx_fifoshift;
- unsigned long rx_fifofull;
- unsigned long tx_fifomask;
- unsigned long tx_fifoshift;
- unsigned long tx_fifofull;
-
- /* clock source control */
-
- int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
- int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
-
- /* uart controls */
- int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
-};
-
-struct s3c24xx_uart_port {
- unsigned char rx_claimed;
- unsigned char tx_claimed;
-
- struct s3c24xx_uart_info *info;
- struct s3c24xx_uart_clksrc *clksrc;
- struct clk *clk;
- struct clk *baudclk;
- struct uart_port port;
-};
-
-
-/* configuration defines */
-
-#if 0
-#if 1
-/* send debug to the low-level output routines */
-
-extern void printascii(const char *);
-
-static void
-s3c24xx_serial_dbg(const char *fmt, ...)
-{
- va_list va;
- char buff[256];
-
- va_start(va, fmt);
- vsprintf(buff, fmt, va);
- va_end(va);
-
- printascii(buff);
-}
-
-#define dbg(x...) s3c24xx_serial_dbg(x)
-
-#else
-#define dbg(x...) printk(KERN_DEBUG "s3c24xx: ");
-#endif
-#else /* no debug */
-#define dbg(x...) do {} while(0)
-#endif
-
-/* UART name and device definitions */
-
-#define S3C24XX_SERIAL_NAME "ttySAC"
-#define S3C24XX_SERIAL_MAJOR 204
-#define S3C24XX_SERIAL_MINOR 64
-
-
-/* conversion functions */
-
-#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
-#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
-
-/* we can support 3 uarts, but not always use them */
-
-#ifdef CONFIG_CPU_S3C2400
-#define NR_PORTS (2)
-#else
-#define NR_PORTS (3)
-#endif
-
-/* port irq numbers */
-
-#define TX_IRQ(port) ((port)->irq + 1)
-#define RX_IRQ(port) ((port)->irq)
-
-/* register access controls */
-
-#define portaddr(port, reg) ((port)->membase + (reg))
-
-#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
-#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
-
-#define wr_regb(port, reg, val) \
- do { __raw_writeb(val, portaddr(port, reg)); } while(0)
-
-#define wr_regl(port, reg, val) \
- do { __raw_writel(val, portaddr(port, reg)); } while(0)
-
-/* macros to change one thing to another */
-
-#define tx_enabled(port) ((port)->unused[0])
-#define rx_enabled(port) ((port)->unused[1])
-
-/* flag to ignore all characters comming in */
-#define RXSTAT_DUMMY_READ (0x10000000)
-
-static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
-{
- return container_of(port, struct s3c24xx_uart_port, port);
-}
-
-/* translate a port to the device name */
-
-static inline const char *s3c24xx_serial_portname(struct uart_port *port)
-{
- return to_platform_device(port->dev)->name;
-}
-
-static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
-{
- return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
-}
-
-static void s3c24xx_serial_rx_enable(struct uart_port *port)
-{
- unsigned long flags;
- unsigned int ucon, ufcon;
- int count = 10000;
-
- spin_lock_irqsave(&port->lock, flags);
-
- while (--count && !s3c24xx_serial_txempty_nofifo(port))
- udelay(100);
-
- ufcon = rd_regl(port, S3C2410_UFCON);
- ufcon |= S3C2410_UFCON_RESETRX;
- wr_regl(port, S3C2410_UFCON, ufcon);
-
- ucon = rd_regl(port, S3C2410_UCON);
- ucon |= S3C2410_UCON_RXIRQMODE;
- wr_regl(port, S3C2410_UCON, ucon);
-
- rx_enabled(port) = 1;
- spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void s3c24xx_serial_rx_disable(struct uart_port *port)
-{
- unsigned long flags;
- unsigned int ucon;
-
- spin_lock_irqsave(&port->lock, flags);
-
- ucon = rd_regl(port, S3C2410_UCON);
- ucon &= ~S3C2410_UCON_RXIRQMODE;
- wr_regl(port, S3C2410_UCON, ucon);
-
- rx_enabled(port) = 0;
- spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void s3c24xx_serial_stop_tx(struct uart_port *port)
-{
- if (tx_enabled(port)) {
- disable_irq(TX_IRQ(port));
- tx_enabled(port) = 0;
- if (port->flags & UPF_CONS_FLOW)
- s3c24xx_serial_rx_enable(port);
- }
-}
-
-static void s3c24xx_serial_start_tx(struct uart_port *port)
-{
- if (!tx_enabled(port)) {
- if (port->flags & UPF_CONS_FLOW)
- s3c24xx_serial_rx_disable(port);
-
- enable_irq(TX_IRQ(port));
- tx_enabled(port) = 1;
- }
-}
-
-
-static void s3c24xx_serial_stop_rx(struct uart_port *port)
-{
- if (rx_enabled(port)) {
- dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
- disable_irq(RX_IRQ(port));
- rx_enabled(port) = 0;
- }
-}
-
-static void s3c24xx_serial_enable_ms(struct uart_port *port)
-{
-}
-
-static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
-{
- return to_ourport(port)->info;
-}
-
-static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
-{
- if (port->dev == NULL)
- return NULL;
-
- return (struct s3c2410_uartcfg *)port->dev->platform_data;
-}
-
-static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
- unsigned long ufstat)
-{
- struct s3c24xx_uart_info *info = ourport->info;
-
- if (ufstat & info->rx_fifofull)
- return info->fifosize;
-
- return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
-}
-
-
-/* ? - where has parity gone?? */
-#define S3C2410_UERSTAT_PARITY (0x1000)
-
-static irqreturn_t
-s3c24xx_serial_rx_chars(int irq, void *dev_id)
-{
- struct s3c24xx_uart_port *ourport = dev_id;
- struct uart_port *port = &ourport->port;
- struct tty_struct *tty = port->info->tty;
- unsigned int ufcon, ch, flag, ufstat, uerstat;
- int max_count = 64;
-
- while (max_count-- > 0) {
- ufcon = rd_regl(port, S3C2410_UFCON);
- ufstat = rd_regl(port, S3C2410_UFSTAT);
-
- if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
- break;
-
- uerstat = rd_regl(port, S3C2410_UERSTAT);
- ch = rd_regb(port, S3C2410_URXH);
-
- if (port->flags & UPF_CONS_FLOW) {
- int txe = s3c24xx_serial_txempty_nofifo(port);
-
- if (rx_enabled(port)) {
- if (!txe) {
- rx_enabled(port) = 0;
- continue;
- }
- } else {
- if (txe) {
- ufcon |= S3C2410_UFCON_RESETRX;
- wr_regl(port, S3C2410_UFCON, ufcon);
- rx_enabled(port) = 1;
- goto out;
- }
- continue;
- }
- }
-
- /* insert the character into the buffer */
-
- flag = TTY_NORMAL;
- port->icount.rx++;
-
- if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
- dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
- ch, uerstat);
-
- /* check for break */
- if (uerstat & S3C2410_UERSTAT_BREAK) {
- dbg("break!\n");
- port->icount.brk++;
- if (uart_handle_break(port))
- goto ignore_char;
- }
-
- if (uerstat & S3C2410_UERSTAT_FRAME)
- port->icount.frame++;
- if (uerstat & S3C2410_UERSTAT_OVERRUN)
- port->icount.overrun++;
-
- uerstat &= port->read_status_mask;
-
- if (uerstat & S3C2410_UERSTAT_BREAK)
- flag = TTY_BREAK;
- else if (uerstat & S3C2410_UERSTAT_PARITY)
- flag = TTY_PARITY;
- else if (uerstat & ( S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN))
- flag = TTY_FRAME;
- }
-
- if (uart_handle_sysrq_char(port, ch))
- goto ignore_char;
-
- uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
-
- ignore_char:
- continue;
- }
- tty_flip_buffer_push(tty);
-
- out:
- return IRQ_HANDLED;
-}
-
-static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
-{
- struct s3c24xx_uart_port *ourport = id;
- struct uart_port *port = &ourport->port;
- struct circ_buf *xmit = &port->info->xmit;
- int count = 256;
-
- if (port->x_char) {
- wr_regb(port, S3C2410_UTXH, port->x_char);
- port->icount.tx++;
- port->x_char = 0;
- goto out;
- }
-
- /* if there isnt anything more to transmit, or the uart is now
- * stopped, disable the uart and exit
- */
-
- if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
- s3c24xx_serial_stop_tx(port);
- goto out;
- }
-
- /* try and drain the buffer... */
-
- while (!uart_circ_empty(xmit) && count-- > 0) {
- if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
- break;
-
- wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- port->icount.tx++;
- }
-
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(port);
-
- if (uart_circ_empty(xmit))
- s3c24xx_serial_stop_tx(port);
-
- out:
- return IRQ_HANDLED;
-}
-
-static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
- unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
-
- if (ufcon & S3C2410_UFCON_FIFOMODE) {
- if ((ufstat & info->tx_fifomask) != 0 ||
- (ufstat & info->tx_fifofull))
- return 0;
-
- return 1;
- }
-
- return s3c24xx_serial_txempty_nofifo(port);
-}
-
-/* no modem control lines */
-static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
-{
- unsigned int umstat = rd_regb(port,S3C2410_UMSTAT);
-
- if (umstat & S3C2410_UMSTAT_CTS)
- return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
- else
- return TIOCM_CAR | TIOCM_DSR;
-}
-
-static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
- /* todo - possibly remove AFC and do manual CTS */
-}
-
-static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
-{
- unsigned long flags;
- unsigned int ucon;
-
- spin_lock_irqsave(&port->lock, flags);
-
- ucon = rd_regl(port, S3C2410_UCON);
-
- if (break_state)
- ucon |= S3C2410_UCON_SBREAK;
- else
- ucon &= ~S3C2410_UCON_SBREAK;
-
- wr_regl(port, S3C2410_UCON, ucon);
-
- spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void s3c24xx_serial_shutdown(struct uart_port *port)
-{
- struct s3c24xx_uart_port *ourport = to_ourport(port);
-
- if (ourport->tx_claimed) {
- free_irq(TX_IRQ(port), ourport);
- tx_enabled(port) = 0;
- ourport->tx_claimed = 0;
- }
-
- if (ourport->rx_claimed) {
- free_irq(RX_IRQ(port), ourport);
- ourport->rx_claimed = 0;
- rx_enabled(port) = 0;
- }
-}
-
-
-static int s3c24xx_serial_startup(struct uart_port *port)
-{
- struct s3c24xx_uart_port *ourport = to_ourport(port);
- int ret;
-
- dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
- port->mapbase, port->membase);
-
- rx_enabled(port) = 1;
-
- ret = request_irq(RX_IRQ(port),
- s3c24xx_serial_rx_chars, 0,
- s3c24xx_serial_portname(port), ourport);
-
- if (ret != 0) {
- printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port));
- return ret;
- }
-
- ourport->rx_claimed = 1;
-
- dbg("requesting tx irq...\n");
-
- tx_enabled(port) = 1;
-
- ret = request_irq(TX_IRQ(port),
- s3c24xx_serial_tx_chars, 0,
- s3c24xx_serial_portname(port), ourport);
-
- if (ret) {
- printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port));
- goto err;
- }
-
- ourport->tx_claimed = 1;
-
- dbg("s3c24xx_serial_startup ok\n");
-
- /* the port reset code should have done the correct
- * register setup for the port controls */
-
- return ret;
-
- err:
- s3c24xx_serial_shutdown(port);
- return ret;
-}
-
-/* power power management control */
-
-static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
- unsigned int old)
-{
- struct s3c24xx_uart_port *ourport = to_ourport(port);
-
- switch (level) {
- case 3:
- if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
- clk_disable(ourport->baudclk);
-
- clk_disable(ourport->clk);
- break;
-
- case 0:
- clk_enable(ourport->clk);
-
- if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
- clk_enable(ourport->baudclk);
-
- break;
- default:
- printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level);
- }
-}
-
-/* baud rate calculation
- *
- * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
- * of different sources, including the peripheral clock ("pclk") and an
- * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
- * with a programmable extra divisor.
- *
- * The following code goes through the clock sources, and calculates the
- * baud clocks (and the resultant actual baud rates) and then tries to
- * pick the closest one and select that.
- *
-*/
-
-
-#define MAX_CLKS (8)
-
-static struct s3c24xx_uart_clksrc tmp_clksrc = {
- .name = "pclk",
- .min_baud = 0,
- .max_baud = 0,
- .divisor = 1,
-};
-
-static inline int
-s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
-
- return (info->get_clksrc)(port, c);
-}
-
-static inline int
-s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
-
- return (info->set_clksrc)(port, c);
-}
-
-struct baud_calc {
- struct s3c24xx_uart_clksrc *clksrc;
- unsigned int calc;
- unsigned int quot;
- struct clk *src;
-};
-
-static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
- struct uart_port *port,
- struct s3c24xx_uart_clksrc *clksrc,
- unsigned int baud)
-{
- unsigned long rate;
-
- calc->src = clk_get(port->dev, clksrc->name);
- if (calc->src == NULL || IS_ERR(calc->src))
- return 0;
-
- rate = clk_get_rate(calc->src);
- rate /= clksrc->divisor;
-
- calc->clksrc = clksrc;
- calc->quot = (rate + (8 * baud)) / (16 * baud);
- calc->calc = (rate / (calc->quot * 16));
-
- calc->quot--;
- return 1;
-}
-
-static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
- struct s3c24xx_uart_clksrc **clksrc,
- struct clk **clk,
- unsigned int baud)
-{
- struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
- struct s3c24xx_uart_clksrc *clkp;
- struct baud_calc res[MAX_CLKS];
- struct baud_calc *resptr, *best, *sptr;
- int i;
-
- clkp = cfg->clocks;
- best = NULL;
-
- if (cfg->clocks_size < 2) {
- if (cfg->clocks_size == 0)
- clkp = &tmp_clksrc;
-
- /* check to see if we're sourcing fclk, and if so we're
- * going to have to update the clock source
- */
-
- if (strcmp(clkp->name, "fclk") == 0) {
- struct s3c24xx_uart_clksrc src;
-
- s3c24xx_serial_getsource(port, &src);
-
- /* check that the port already using fclk, and if
- * not, then re-select fclk
- */
-
- if (strcmp(src.name, clkp->name) == 0) {
- s3c24xx_serial_setsource(port, clkp);
- s3c24xx_serial_getsource(port, &src);
- }
-
- clkp->divisor = src.divisor;
- }
-
- s3c24xx_serial_calcbaud(res, port, clkp, baud);
- best = res;
- resptr = best + 1;
- } else {
- resptr = res;
-
- for (i = 0; i < cfg->clocks_size; i++, clkp++) {
- if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
- resptr++;
- }
- }
-
- /* ok, we now need to select the best clock we found */
-
- if (!best) {
- unsigned int deviation = (1<<30)|((1<<30)-1);
- int calc_deviation;
-
- for (sptr = res; sptr < resptr; sptr++) {
- printk(KERN_DEBUG
- "found clk %p (%s) quot %d, calc %d\n",
- sptr->clksrc, sptr->clksrc->name,
- sptr->quot, sptr->calc);
-
- calc_deviation = baud - sptr->calc;
- if (calc_deviation < 0)
- calc_deviation = -calc_deviation;
-
- if (calc_deviation < deviation) {
- best = sptr;
- deviation = calc_deviation;
- }
- }
-
- printk(KERN_DEBUG "best %p (deviation %d)\n", best, deviation);
- }
-
- printk(KERN_DEBUG "selected clock %p (%s) quot %d, calc %d\n",
- best->clksrc, best->clksrc->name, best->quot, best->calc);
-
- /* store results to pass back */
-
- *clksrc = best->clksrc;
- *clk = best->src;
-
- return best->quot;
-}
-
-static void s3c24xx_serial_set_termios(struct uart_port *port,
- struct ktermios *termios,
- struct ktermios *old)
-{
- struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
- struct s3c24xx_uart_port *ourport = to_ourport(port);
- struct s3c24xx_uart_clksrc *clksrc = NULL;
- struct clk *clk = NULL;
- unsigned long flags;
- unsigned int baud, quot;
- unsigned int ulcon;
- unsigned int umcon;
-
- /*
- * We don't support modem control lines.
- */
- termios->c_cflag &= ~(HUPCL | CMSPAR);
- termios->c_cflag |= CLOCAL;
-
- /*
- * Ask the core to calculate the divisor for us.
- */
-
- baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
-
- if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
- quot = port->custom_divisor;
- else
- quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
-
- /* check to see if we need to change clock source */
-
- if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
- s3c24xx_serial_setsource(port, clksrc);
-
- if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
- clk_disable(ourport->baudclk);
- ourport->baudclk = NULL;
- }
-
- clk_enable(clk);
-
- ourport->clksrc = clksrc;
- ourport->baudclk = clk;
- }
-
- switch (termios->c_cflag & CSIZE) {
- case CS5:
- dbg("config: 5bits/char\n");
- ulcon = S3C2410_LCON_CS5;
- break;
- case CS6:
- dbg("config: 6bits/char\n");
- ulcon = S3C2410_LCON_CS6;
- break;
- case CS7:
- dbg("config: 7bits/char\n");
- ulcon = S3C2410_LCON_CS7;
- break;
- case CS8:
- default:
- dbg("config: 8bits/char\n");
- ulcon = S3C2410_LCON_CS8;
- break;
- }
-
- /* preserve original lcon IR settings */
- ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
-
- if (termios->c_cflag & CSTOPB)
- ulcon |= S3C2410_LCON_STOPB;
-
- umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
-
- if (termios->c_cflag & PARENB) {
- if (termios->c_cflag & PARODD)
- ulcon |= S3C2410_LCON_PODD;
- else
- ulcon |= S3C2410_LCON_PEVEN;
- } else {
- ulcon |= S3C2410_LCON_PNONE;
- }
-
- spin_lock_irqsave(&port->lock, flags);
-
- dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);
-
- wr_regl(port, S3C2410_ULCON, ulcon);
- wr_regl(port, S3C2410_UBRDIV, quot);
- wr_regl(port, S3C2410_UMCON, umcon);
-
- dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
- rd_regl(port, S3C2410_ULCON),
- rd_regl(port, S3C2410_UCON),
- rd_regl(port, S3C2410_UFCON));
-
- /*
- * Update the per-port timeout.
- */
- uart_update_timeout(port, termios->c_cflag, baud);
-
- /*
- * Which character status flags are we interested in?
- */
- port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
- if (termios->c_iflag & INPCK)
- port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY;
-
- /*
- * Which character status flags should we ignore?
- */
- port->ignore_status_mask = 0;
- if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
- if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;
-
- /*
- * Ignore all characters if CREAD is not set.
- */
- if ((termios->c_cflag & CREAD) == 0)
- port->ignore_status_mask |= RXSTAT_DUMMY_READ;
-
- spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static const char *s3c24xx_serial_type(struct uart_port *port)
-{
- switch (port->type) {
- case PORT_S3C2410:
- return "S3C2410";
- case PORT_S3C2440:
- return "S3C2440";
- case PORT_S3C2412:
- return "S3C2412";
- default:
- return NULL;
- }
-}
-
-#define MAP_SIZE (0x100)
-
-static void s3c24xx_serial_release_port(struct uart_port *port)
-{
- release_mem_region(port->mapbase, MAP_SIZE);
-}
-
-static int s3c24xx_serial_request_port(struct uart_port *port)
-{
- const char *name = s3c24xx_serial_portname(port);
- return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
-}
-
-static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
-
- if (flags & UART_CONFIG_TYPE &&
- s3c24xx_serial_request_port(port) == 0)
- port->type = info->type;
-}
-
-/*
- * verify the new serial_struct (for TIOCSSERIAL).
- */
-static int
-s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
-
- if (ser->type != PORT_UNKNOWN && ser->type != info->type)
- return -EINVAL;
-
- return 0;
-}
-
-
-#ifdef CONFIG_SERIAL_S3C2410_CONSOLE
-
-static struct console s3c24xx_serial_console;
-
-#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
-#else
-#define S3C24XX_SERIAL_CONSOLE NULL
-#endif
-
-static struct uart_ops s3c24xx_serial_ops = {
- .pm = s3c24xx_serial_pm,
- .tx_empty = s3c24xx_serial_tx_empty,
- .get_mctrl = s3c24xx_serial_get_mctrl,
- .set_mctrl = s3c24xx_serial_set_mctrl,
- .stop_tx = s3c24xx_serial_stop_tx,
- .start_tx = s3c24xx_serial_start_tx,
- .stop_rx = s3c24xx_serial_stop_rx,
- .enable_ms = s3c24xx_serial_enable_ms,
- .break_ctl = s3c24xx_serial_break_ctl,
- .startup = s3c24xx_serial_startup,
- .shutdown = s3c24xx_serial_shutdown,
- .set_termios = s3c24xx_serial_set_termios,
- .type = s3c24xx_serial_type,
- .release_port = s3c24xx_serial_release_port,
- .request_port = s3c24xx_serial_request_port,
- .config_port = s3c24xx_serial_config_port,
- .verify_port = s3c24xx_serial_verify_port,
-};
-
-
-static struct uart_driver s3c24xx_uart_drv = {
- .owner = THIS_MODULE,
- .dev_name = "s3c2410_serial",
- .nr = 3,
- .cons = S3C24XX_SERIAL_CONSOLE,
- .driver_name = S3C24XX_SERIAL_NAME,
- .major = S3C24XX_SERIAL_MAJOR,
- .minor = S3C24XX_SERIAL_MINOR,
-};
-
-static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
- [0] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX0,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 0,
- }
- },
- [1] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX1,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 1,
- }
- },
-#if NR_PORTS > 2
-
- [2] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX2,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 2,
- }
- }
-#endif
-};
-
-/* s3c24xx_serial_resetport
- *
- * wrapper to call the specific reset for this port (reset the fifos
- * and the settings)
-*/
-
-static inline int s3c24xx_serial_resetport(struct uart_port * port,
- struct s3c2410_uartcfg *cfg)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
-
- return (info->reset_port)(port, cfg);
-}
-
-/* s3c24xx_serial_init_port
- *
- * initialise a single serial port from the platform device given
- */
-
-static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
- struct s3c24xx_uart_info *info,
- struct platform_device *platdev)
-{
- struct uart_port *port = &ourport->port;
- struct s3c2410_uartcfg *cfg;
- struct resource *res;
- int ret;
-
- dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);
-
- if (platdev == NULL)
- return -ENODEV;
-
- cfg = s3c24xx_dev_to_cfg(&platdev->dev);
-
- if (port->mapbase != 0)
- return 0;
-
- if (cfg->hwport > 3)
- return -EINVAL;
-
- /* setup info for port */
- port->dev = &platdev->dev;
- ourport->info = info;
-
- /* copy the info in from provided structure */
- ourport->port.fifosize = info->fifosize;
-
- dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);
-
- port->uartclk = 1;
-
- if (cfg->uart_flags & UPF_CONS_FLOW) {
- dbg("s3c24xx_serial_init_port: enabling flow control\n");
- port->flags |= UPF_CONS_FLOW;
- }
-
- /* sort our the physical and virtual addresses for each UART */
-
- res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- printk(KERN_ERR "failed to find memory resource for uart\n");
- return -EINVAL;
- }
-
- dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
-
- port->mapbase = res->start;
- port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
- ret = platform_get_irq(platdev, 0);
- if (ret < 0)
- port->irq = 0;
- else
- port->irq = ret;
-
- ourport->clk = clk_get(&platdev->dev, "uart");
-
- dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
- port->mapbase, port->membase, port->irq, port->uartclk);
-
- /* reset the fifos (and setup the uart) */
- s3c24xx_serial_resetport(port, cfg);
- return 0;
-}
-
-/* Device driver serial port probe */
-
-static int probe_index = 0;
-
-static int s3c24xx_serial_probe(struct platform_device *dev,
- struct s3c24xx_uart_info *info)
-{
- struct s3c24xx_uart_port *ourport;
- int ret;
-
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
-
- ourport = &s3c24xx_serial_ports[probe_index];
- probe_index++;
-
- dbg("%s: initialising port %p...\n", __func__, ourport);
-
- ret = s3c24xx_serial_init_port(ourport, info, dev);
- if (ret < 0)
- goto probe_err;
-
- dbg("%s: adding port\n", __func__);
- uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
- platform_set_drvdata(dev, &ourport->port);
-
- return 0;
-
- probe_err:
- return ret;
-}
-
-static int s3c24xx_serial_remove(struct platform_device *dev)
-{
- struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
-
- if (port)
- uart_remove_one_port(&s3c24xx_uart_drv, port);
-
- return 0;
-}
-
-/* UART power management code */
-
-#ifdef CONFIG_PM
-
-static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
-
- if (port)
- uart_suspend_port(&s3c24xx_uart_drv, port);
-
- return 0;
-}
-
-static int s3c24xx_serial_resume(struct platform_device *dev)
-{
- struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
- struct s3c24xx_uart_port *ourport = to_ourport(port);
-
- if (port) {
- clk_enable(ourport->clk);
- s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
- clk_disable(ourport->clk);
-
- uart_resume_port(&s3c24xx_uart_drv, port);
- }
-
- return 0;
-}
-
-#else
-#define s3c24xx_serial_suspend NULL
-#define s3c24xx_serial_resume NULL
-#endif
-
-static int s3c24xx_serial_init(struct platform_driver *drv,
- struct s3c24xx_uart_info *info)
-{
- dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
- return platform_driver_register(drv);
-}
-
-
-/* now comes the code to initialise either the s3c2410 or s3c2440 serial
- * port information
-*/
-
-/* cpu specific variations on the serial port support */
-
-#ifdef CONFIG_CPU_S3C2400
-
-static int s3c2400_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- clk->divisor = 1;
- clk->name = "pclk";
-
- return 0;
-}
-
-static int s3c2400_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- return 0;
-}
-
-static int s3c2400_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- dbg("s3c2400_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- wr_regl(port, S3C2410_UCON, cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
-static struct s3c24xx_uart_info s3c2400_uart_inf = {
- .name = "Samsung S3C2400 UART",
- .type = PORT_S3C2400,
- .fifosize = 16,
- .rx_fifomask = S3C2410_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2410_UFSTAT_RXFULL,
- .tx_fifofull = S3C2410_UFSTAT_TXFULL,
- .tx_fifomask = S3C2410_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2400_serial_getsource,
- .set_clksrc = s3c2400_serial_setsource,
- .reset_port = s3c2400_serial_resetport,
-};
-
-static int s3c2400_serial_probe(struct platform_device *dev)
-{
- return s3c24xx_serial_probe(dev, &s3c2400_uart_inf);
-}
-
-static struct platform_driver s3c2400_serial_drv = {
- .probe = s3c2400_serial_probe,
- .remove = s3c24xx_serial_remove,
- .suspend = s3c24xx_serial_suspend,
- .resume = s3c24xx_serial_resume,
- .driver = {
- .name = "s3c2400-uart",
- .owner = THIS_MODULE,
- },
-};
-
-static inline int s3c2400_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2400_serial_drv, &s3c2400_uart_inf);
-}
-
-static inline void s3c2400_serial_exit(void)
-{
- platform_driver_unregister(&s3c2400_serial_drv);
-}
-
-#define s3c2400_uart_inf_at &s3c2400_uart_inf
-#else
-
-static inline int s3c2400_serial_init(void)
-{
- return 0;
-}
-
-static inline void s3c2400_serial_exit(void)
-{
-}
-
-#define s3c2400_uart_inf_at NULL
-
-#endif /* CONFIG_CPU_S3C2400 */
-
-/* S3C2410 support */
-
-#ifdef CONFIG_CPU_S3C2410
+#include "samsung.h"
static int s3c2410_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
@@ -1323,8 +83,6 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = {
.reset_port = s3c2410_serial_resetport,
};
-/* device management */
-
static int s3c2410_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
@@ -1333,612 +91,28 @@ static int s3c2410_serial_probe(struct platform_device *dev)
static struct platform_driver s3c2410_serial_drv = {
.probe = s3c2410_serial_probe,
.remove = s3c24xx_serial_remove,
- .suspend = s3c24xx_serial_suspend,
- .resume = s3c24xx_serial_resume,
.driver = {
.name = "s3c2410-uart",
.owner = THIS_MODULE,
},
};
-static inline int s3c2410_serial_init(void)
+s3c24xx_console_init(&s3c2410_serial_drv, &s3c2410_uart_inf);
+
+static int __init s3c2410_serial_init(void)
{
return s3c24xx_serial_init(&s3c2410_serial_drv, &s3c2410_uart_inf);
}
-static inline void s3c2410_serial_exit(void)
+static void __exit s3c2410_serial_exit(void)
{
platform_driver_unregister(&s3c2410_serial_drv);
}
-#define s3c2410_uart_inf_at &s3c2410_uart_inf
-#else
-
-static inline int s3c2410_serial_init(void)
-{
- return 0;
-}
-
-static inline void s3c2410_serial_exit(void)
-{
-}
-
-#define s3c2410_uart_inf_at NULL
-
-#endif /* CONFIG_CPU_S3C2410 */
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-static int s3c2440_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- // todo - proper fclk<>nonfclk switch //
-
- ucon &= ~S3C2440_UCON_CLKMASK;
-
- if (strcmp(clk->name, "uclk") == 0)
- ucon |= S3C2440_UCON_UCLK;
- else if (strcmp(clk->name, "pclk") == 0)
- ucon |= S3C2440_UCON_PCLK;
- else if (strcmp(clk->name, "fclk") == 0)
- ucon |= S3C2440_UCON_FCLK;
- else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s3c2440_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
- unsigned long ucon0, ucon1, ucon2;
-
- switch (ucon & S3C2440_UCON_CLKMASK) {
- case S3C2440_UCON_UCLK:
- clk->divisor = 1;
- clk->name = "uclk";
- break;
-
- case S3C2440_UCON_PCLK:
- case S3C2440_UCON_PCLK2:
- clk->divisor = 1;
- clk->name = "pclk";
- break;
-
- case S3C2440_UCON_FCLK:
- /* the fun of calculating the uart divisors on
- * the s3c2440 */
-
- ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
- ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
- ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
-
- printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
-
- ucon0 &= S3C2440_UCON0_DIVMASK;
- ucon1 &= S3C2440_UCON1_DIVMASK;
- ucon2 &= S3C2440_UCON2_DIVMASK;
-
- if (ucon0 != 0) {
- clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 6;
- } else if (ucon1 != 0) {
- clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 21;
- } else if (ucon2 != 0) {
- clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
- clk->divisor += 36;
- } else {
- /* manual calims 44, seems to be 9 */
- clk->divisor = 9;
- }
-
- clk->name = "fclk";
- break;
- }
-
- return 0;
-}
-
-static int s3c2440_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
- port, port->mapbase, cfg);
-
- /* ensure we don't change the clock settings... */
-
- ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
-
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
-static struct s3c24xx_uart_info s3c2440_uart_inf = {
- .name = "Samsung S3C2440 UART",
- .type = PORT_S3C2440,
- .fifosize = 64,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2440_serial_getsource,
- .set_clksrc = s3c2440_serial_setsource,
- .reset_port = s3c2440_serial_resetport,
-};
-
-/* device management */
-
-static int s3c2440_serial_probe(struct platform_device *dev)
-{
- dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
-}
-
-static struct platform_driver s3c2440_serial_drv = {
- .probe = s3c2440_serial_probe,
- .remove = s3c24xx_serial_remove,
- .suspend = s3c24xx_serial_suspend,
- .resume = s3c24xx_serial_resume,
- .driver = {
- .name = "s3c2440-uart",
- .owner = THIS_MODULE,
- },
-};
-
-
-static inline int s3c2440_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
-}
-
-static inline void s3c2440_serial_exit(void)
-{
- platform_driver_unregister(&s3c2440_serial_drv);
-}
-
-#define s3c2440_uart_inf_at &s3c2440_uart_inf
-#else
-
-static inline int s3c2440_serial_init(void)
-{
- return 0;
-}
-
-static inline void s3c2440_serial_exit(void)
-{
-}
-
-#define s3c2440_uart_inf_at NULL
-#endif /* CONFIG_CPU_S3C2440 */
-
-#if defined(CONFIG_CPU_S3C2412)
-
-static int s3c2412_serial_setsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- ucon &= ~S3C2412_UCON_CLKMASK;
-
- if (strcmp(clk->name, "uclk") == 0)
- ucon |= S3C2440_UCON_UCLK;
- else if (strcmp(clk->name, "pclk") == 0)
- ucon |= S3C2440_UCON_PCLK;
- else if (strcmp(clk->name, "usysclk") == 0)
- ucon |= S3C2412_UCON_USYSCLK;
- else {
- printk(KERN_ERR "unknown clock source %s\n", clk->name);
- return -EINVAL;
- }
-
- wr_regl(port, S3C2410_UCON, ucon);
- return 0;
-}
-
-
-static int s3c2412_serial_getsource(struct uart_port *port,
- struct s3c24xx_uart_clksrc *clk)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- switch (ucon & S3C2412_UCON_CLKMASK) {
- case S3C2412_UCON_UCLK:
- clk->divisor = 1;
- clk->name = "uclk";
- break;
-
- case S3C2412_UCON_PCLK:
- case S3C2412_UCON_PCLK2:
- clk->divisor = 1;
- clk->name = "pclk";
- break;
-
- case S3C2412_UCON_USYSCLK:
- clk->divisor = 1;
- clk->name = "usysclk";
- break;
- }
-
- return 0;
-}
-
-static int s3c2412_serial_resetport(struct uart_port *port,
- struct s3c2410_uartcfg *cfg)
-{
- unsigned long ucon = rd_regl(port, S3C2410_UCON);
-
- dbg("%s: port=%p (%08lx), cfg=%p\n",
- __func__, port, port->mapbase, cfg);
-
- /* ensure we don't change the clock settings... */
-
- ucon &= S3C2412_UCON_CLKMASK;
-
- wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
- wr_regl(port, S3C2410_ULCON, cfg->ulcon);
-
- /* reset both fifos */
-
- wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
- wr_regl(port, S3C2410_UFCON, cfg->ufcon);
-
- return 0;
-}
-
-static struct s3c24xx_uart_info s3c2412_uart_inf = {
- .name = "Samsung S3C2412 UART",
- .type = PORT_S3C2412,
- .fifosize = 64,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2412_serial_getsource,
- .set_clksrc = s3c2412_serial_setsource,
- .reset_port = s3c2412_serial_resetport,
-};
-
-/* device management */
-
-static int s3c2412_serial_probe(struct platform_device *dev)
-{
- dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
-}
-
-static struct platform_driver s3c2412_serial_drv = {
- .probe = s3c2412_serial_probe,
- .remove = s3c24xx_serial_remove,
- .suspend = s3c24xx_serial_suspend,
- .resume = s3c24xx_serial_resume,
- .driver = {
- .name = "s3c2412-uart",
- .owner = THIS_MODULE,
- },
-};
-
-
-static inline int s3c2412_serial_init(void)
-{
- return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
-}
-
-static inline void s3c2412_serial_exit(void)
-{
- platform_driver_unregister(&s3c2412_serial_drv);
-}
-
-#define s3c2412_uart_inf_at &s3c2412_uart_inf
-#else
-
-static inline int s3c2412_serial_init(void)
-{
- return 0;
-}
-
-static inline void s3c2412_serial_exit(void)
-{
-}
-
-#define s3c2412_uart_inf_at NULL
-#endif /* CONFIG_CPU_S3C2440 */
-
-
-/* module initialisation code */
-
-static int __init s3c24xx_serial_modinit(void)
-{
- int ret;
-
- ret = uart_register_driver(&s3c24xx_uart_drv);
- if (ret < 0) {
- printk(KERN_ERR "failed to register UART driver\n");
- return -1;
- }
-
- s3c2400_serial_init();
- s3c2410_serial_init();
- s3c2412_serial_init();
- s3c2440_serial_init();
-
- return 0;
-}
-
-static void __exit s3c24xx_serial_modexit(void)
-{
- s3c2400_serial_exit();
- s3c2410_serial_exit();
- s3c2412_serial_exit();
- s3c2440_serial_exit();
-
- uart_unregister_driver(&s3c24xx_uart_drv);
-}
-
-
-module_init(s3c24xx_serial_modinit);
-module_exit(s3c24xx_serial_modexit);
-
-/* Console code */
-
-#ifdef CONFIG_SERIAL_S3C2410_CONSOLE
-
-static struct uart_port *cons_uart;
-
-static int
-s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
-{
- struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
- unsigned long ufstat, utrstat;
-
- if (ufcon & S3C2410_UFCON_FIFOMODE) {
- /* fifo mode - check ammount of data in fifo registers... */
-
- ufstat = rd_regl(port, S3C2410_UFSTAT);
- return (ufstat & info->tx_fifofull) ? 0 : 1;
- }
-
- /* in non-fifo mode, we go and use the tx buffer empty */
-
- utrstat = rd_regl(port, S3C2410_UTRSTAT);
- return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
-}
-
-static void
-s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
-{
- unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
- while (!s3c24xx_serial_console_txrdy(port, ufcon))
- barrier();
- wr_regb(cons_uart, S3C2410_UTXH, ch);
-}
-
-static void
-s3c24xx_serial_console_write(struct console *co, const char *s,
- unsigned int count)
-{
- uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
-}
-
-static void __init
-s3c24xx_serial_get_options(struct uart_port *port, int *baud,
- int *parity, int *bits)
-{
- struct s3c24xx_uart_clksrc clksrc;
- struct clk *clk;
- unsigned int ulcon;
- unsigned int ucon;
- unsigned int ubrdiv;
- unsigned long rate;
-
- ulcon = rd_regl(port, S3C2410_ULCON);
- ucon = rd_regl(port, S3C2410_UCON);
- ubrdiv = rd_regl(port, S3C2410_UBRDIV);
-
- dbg("s3c24xx_serial_get_options: port=%p\n"
- "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n",
- port, ulcon, ucon, ubrdiv);
-
- if ((ucon & 0xf) != 0) {
- /* consider the serial port configured if the tx/rx mode set */
-
- switch (ulcon & S3C2410_LCON_CSMASK) {
- case S3C2410_LCON_CS5:
- *bits = 5;
- break;
- case S3C2410_LCON_CS6:
- *bits = 6;
- break;
- case S3C2410_LCON_CS7:
- *bits = 7;
- break;
- default:
- case S3C2410_LCON_CS8:
- *bits = 8;
- break;
- }
-
- switch (ulcon & S3C2410_LCON_PMASK) {
- case S3C2410_LCON_PEVEN:
- *parity = 'e';
- break;
-
- case S3C2410_LCON_PODD:
- *parity = 'o';
- break;
-
- case S3C2410_LCON_PNONE:
- default:
- *parity = 'n';
- }
-
- /* now calculate the baud rate */
-
- s3c24xx_serial_getsource(port, &clksrc);
-
- clk = clk_get(port->dev, clksrc.name);
- if (!IS_ERR(clk) && clk != NULL)
- rate = clk_get_rate(clk) / clksrc.divisor;
- else
- rate = 1;
-
-
- *baud = rate / ( 16 * (ubrdiv + 1));
- dbg("calculated baud %d\n", *baud);
- }
-
-}
-
-/* s3c24xx_serial_init_ports
- *
- * initialise the serial ports from the machine provided initialisation
- * data.
-*/
-
-static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
-{
- struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
- struct platform_device **platdev_ptr;
- int i;
-
- dbg("s3c24xx_serial_init_ports: initialising ports...\n");
-
- platdev_ptr = s3c24xx_uart_devs;
-
- for (i = 0; i < NR_PORTS; i++, ptr++, platdev_ptr++) {
- s3c24xx_serial_init_port(ptr, info, *platdev_ptr);
- }
-
- return 0;
-}
-
-static int __init
-s3c24xx_serial_console_setup(struct console *co, char *options)
-{
- struct uart_port *port;
- int baud = 9600;
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
-
- dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n",
- co, co->index, options);
-
- /* is this a valid port */
-
- if (co->index == -1 || co->index >= NR_PORTS)
- co->index = 0;
-
- port = &s3c24xx_serial_ports[co->index].port;
-
- /* is the port configured? */
-
- if (port->mapbase == 0x0) {
- co->index = 0;
- port = &s3c24xx_serial_ports[co->index].port;
- }
-
- cons_uart = port;
-
- dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index);
-
- /*
- * Check whether an invalid uart number has been specified, and
- * if so, search for the first available port that does have
- * console support.
- */
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
- else
- s3c24xx_serial_get_options(port, &baud, &parity, &bits);
-
- dbg("s3c24xx_serial_console_setup: baud %d\n", baud);
-
- return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
-/* s3c24xx_serial_initconsole
- *
- * initialise the console from one of the uart drivers
-*/
-
-static struct console s3c24xx_serial_console =
-{
- .name = S3C24XX_SERIAL_NAME,
- .device = uart_console_device,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .write = s3c24xx_serial_console_write,
- .setup = s3c24xx_serial_console_setup
-};
-
-static int s3c24xx_serial_initconsole(void)
-{
- struct s3c24xx_uart_info *info;
- struct platform_device *dev = s3c24xx_uart_devs[0];
-
- dbg("s3c24xx_serial_initconsole\n");
-
- /* select driver based on the cpu */
-
- if (dev == NULL) {
- printk(KERN_ERR "s3c24xx: no devices for console init\n");
- return 0;
- }
-
- if (strcmp(dev->name, "s3c2400-uart") == 0) {
- info = s3c2400_uart_inf_at;
- } else if (strcmp(dev->name, "s3c2410-uart") == 0) {
- info = s3c2410_uart_inf_at;
- } else if (strcmp(dev->name, "s3c2440-uart") == 0) {
- info = s3c2440_uart_inf_at;
- } else if (strcmp(dev->name, "s3c2412-uart") == 0) {
- info = s3c2412_uart_inf_at;
- } else {
- printk(KERN_ERR "s3c24xx: no driver for %s\n", dev->name);
- return 0;
- }
-
- if (info == NULL) {
- printk(KERN_ERR "s3c24xx: no driver for console\n");
- return 0;
- }
-
- s3c24xx_serial_console.data = &s3c24xx_uart_drv;
- s3c24xx_serial_init_ports(info);
-
- register_console(&s3c24xx_serial_console);
- return 0;
-}
-
-console_initcall(s3c24xx_serial_initconsole);
-
-#endif /* CONFIG_SERIAL_S3C2410_CONSOLE */
+module_init(s3c2410_serial_init);
+module_exit(s3c2410_serial_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("Samsung S3C2410/S3C2440/S3C2412 Serial port driver");
-MODULE_ALIAS("platform:s3c2400-uart");
+MODULE_DESCRIPTION("Samsung S3C2410 SoC Serial port driver");
MODULE_ALIAS("platform:s3c2410-uart");
-MODULE_ALIAS("platform:s3c2412-uart");
-MODULE_ALIAS("platform:s3c2440-uart");
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
new file mode 100644
index 00000000000..ce0c220e3e9
--- /dev/null
+++ b/drivers/serial/s3c2412.c
@@ -0,0 +1,151 @@
+/* linux/drivers/serial/s3c2412.c
+ *
+ * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
+ *
+ * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "samsung.h"
+
+static int s3c2412_serial_setsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ ucon &= ~S3C2412_UCON_CLKMASK;
+
+ if (strcmp(clk->name, "uclk") == 0)
+ ucon |= S3C2440_UCON_UCLK;
+ else if (strcmp(clk->name, "pclk") == 0)
+ ucon |= S3C2440_UCON_PCLK;
+ else if (strcmp(clk->name, "usysclk") == 0)
+ ucon |= S3C2412_UCON_USYSCLK;
+ else {
+ printk(KERN_ERR "unknown clock source %s\n", clk->name);
+ return -EINVAL;
+ }
+
+ wr_regl(port, S3C2410_UCON, ucon);
+ return 0;
+}
+
+
+static int s3c2412_serial_getsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ switch (ucon & S3C2412_UCON_CLKMASK) {
+ case S3C2412_UCON_UCLK:
+ clk->divisor = 1;
+ clk->name = "uclk";
+ break;
+
+ case S3C2412_UCON_PCLK:
+ case S3C2412_UCON_PCLK2:
+ clk->divisor = 1;
+ clk->name = "pclk";
+ break;
+
+ case S3C2412_UCON_USYSCLK:
+ clk->divisor = 1;
+ clk->name = "usysclk";
+ break;
+ }
+
+ return 0;
+}
+
+static int s3c2412_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ dbg("%s: port=%p (%08lx), cfg=%p\n",
+ __func__, port, port->mapbase, cfg);
+
+ /* ensure we don't change the clock settings... */
+
+ ucon &= S3C2412_UCON_CLKMASK;
+
+ wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
+
+static struct s3c24xx_uart_info s3c2412_uart_inf = {
+ .name = "Samsung S3C2412 UART",
+ .type = PORT_S3C2412,
+ .fifosize = 64,
+ .rx_fifomask = S3C2440_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2440_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2440_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2440_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
+ .get_clksrc = s3c2412_serial_getsource,
+ .set_clksrc = s3c2412_serial_setsource,
+ .reset_port = s3c2412_serial_resetport,
+};
+
+/* device management */
+
+static int s3c2412_serial_probe(struct platform_device *dev)
+{
+ dbg("s3c2440_serial_probe: dev=%p\n", dev);
+ return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
+}
+
+static struct platform_driver s3c2412_serial_drv = {
+ .probe = s3c2412_serial_probe,
+ .remove = s3c24xx_serial_remove,
+ .driver = {
+ .name = "s3c2412-uart",
+ .owner = THIS_MODULE,
+ },
+};
+
+s3c24xx_console_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
+
+static inline int s3c2412_serial_init(void)
+{
+ return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
+}
+
+static inline void s3c2412_serial_exit(void)
+{
+ platform_driver_unregister(&s3c2412_serial_drv);
+}
+
+module_init(s3c2412_serial_init);
+module_exit(s3c2412_serial_exit);
+
+MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:s3c2412-uart");
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
new file mode 100644
index 00000000000..38f954bd39c
--- /dev/null
+++ b/drivers/serial/s3c2440.c
@@ -0,0 +1,181 @@
+/* linux/drivers/serial/s3c2440.c
+ *
+ * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
+ *
+ * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "samsung.h"
+
+
+static int s3c2440_serial_setsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ /* todo - proper fclk<>nonfclk switch. */
+
+ ucon &= ~S3C2440_UCON_CLKMASK;
+
+ if (strcmp(clk->name, "uclk") == 0)
+ ucon |= S3C2440_UCON_UCLK;
+ else if (strcmp(clk->name, "pclk") == 0)
+ ucon |= S3C2440_UCON_PCLK;
+ else if (strcmp(clk->name, "fclk") == 0)
+ ucon |= S3C2440_UCON_FCLK;
+ else {
+ printk(KERN_ERR "unknown clock source %s\n", clk->name);
+ return -EINVAL;
+ }
+
+ wr_regl(port, S3C2410_UCON, ucon);
+ return 0;
+}
+
+
+static int s3c2440_serial_getsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+ unsigned long ucon0, ucon1, ucon2;
+
+ switch (ucon & S3C2440_UCON_CLKMASK) {
+ case S3C2440_UCON_UCLK:
+ clk->divisor = 1;
+ clk->name = "uclk";
+ break;
+
+ case S3C2440_UCON_PCLK:
+ case S3C2440_UCON_PCLK2:
+ clk->divisor = 1;
+ clk->name = "pclk";
+ break;
+
+ case S3C2440_UCON_FCLK:
+ /* the fun of calculating the uart divisors on
+ * the s3c2440 */
+
+ ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
+ ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
+ ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
+
+ printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
+
+ ucon0 &= S3C2440_UCON0_DIVMASK;
+ ucon1 &= S3C2440_UCON1_DIVMASK;
+ ucon2 &= S3C2440_UCON2_DIVMASK;
+
+ if (ucon0 != 0) {
+ clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 6;
+ } else if (ucon1 != 0) {
+ clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 21;
+ } else if (ucon2 != 0) {
+ clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
+ clk->divisor += 36;
+ } else {
+ /* manual calims 44, seems to be 9 */
+ clk->divisor = 9;
+ }
+
+ clk->name = "fclk";
+ break;
+ }
+
+ return 0;
+}
+
+static int s3c2440_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
+ port, port->mapbase, cfg);
+
+ /* ensure we don't change the clock settings... */
+
+ ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
+
+ wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
+
+static struct s3c24xx_uart_info s3c2440_uart_inf = {
+ .name = "Samsung S3C2440 UART",
+ .type = PORT_S3C2440,
+ .fifosize = 64,
+ .rx_fifomask = S3C2440_UFSTAT_RXMASK,
+ .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
+ .rx_fifofull = S3C2440_UFSTAT_RXFULL,
+ .tx_fifofull = S3C2440_UFSTAT_TXFULL,
+ .tx_fifomask = S3C2440_UFSTAT_TXMASK,
+ .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
+ .get_clksrc = s3c2440_serial_getsource,
+ .set_clksrc = s3c2440_serial_setsource,
+ .reset_port = s3c2440_serial_resetport,
+};
+
+/* device management */
+
+static int s3c2440_serial_probe(struct platform_device *dev)
+{
+ dbg("s3c2440_serial_probe: dev=%p\n", dev);
+ return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
+}
+
+static struct platform_driver s3c2440_serial_drv = {
+ .probe = s3c2440_serial_probe,
+ .remove = s3c24xx_serial_remove,
+ .driver = {
+ .name = "s3c2440-uart",
+ .owner = THIS_MODULE,
+ },
+};
+
+s3c24xx_console_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
+
+static int __init s3c2440_serial_init(void)
+{
+ return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
+}
+
+static void __exit s3c2440_serial_exit(void)
+{
+ platform_driver_unregister(&s3c2440_serial_drv);
+}
+
+module_init(s3c2440_serial_init);
+module_exit(s3c2440_serial_exit);
+
+MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPLi v2");
+MODULE_ALIAS("platform:s3c2440-uart");
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
new file mode 100644
index 00000000000..4a3ecaa629e
--- /dev/null
+++ b/drivers/serial/samsung.c
@@ -0,0 +1,1317 @@
+/* linux/drivers/serial/samsuing.c
+ *
+ * Driver core for Samsung SoC onboard UARTs.
+ *
+ * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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.
+*/
+
+/* Hote on 2410 error handling
+ *
+ * The s3c2410 manual has a love/hate affair with the contents of the
+ * UERSTAT register in the UART blocks, and keeps marking some of the
+ * error bits as reserved. Having checked with the s3c2410x01,
+ * it copes with BREAKs properly, so I am happy to ignore the RESERVED
+ * feature from the latter versions of the manual.
+ *
+ * If it becomes aparrent that latter versions of the 2410 remove these
+ * bits, then action will have to be taken to differentiate the versions
+ * and change the policy on BREAK
+ *
+ * BJD, 04-Nov-2004
+*/
+
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/sysrq.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/irq.h>
+
+#include <asm/hardware.h>
+
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "samsung.h"
+
+/* UART name and device definitions */
+
+#define S3C24XX_SERIAL_NAME "ttySAC"
+#define S3C24XX_SERIAL_MAJOR 204
+#define S3C24XX_SERIAL_MINOR 64
+
+/* we can support 3 uarts, but not always use them */
+
+#ifdef CONFIG_CPU_S3C2400
+#define NR_PORTS (2)
+#else
+#define NR_PORTS (3)
+#endif
+
+/* port irq numbers */
+
+#define TX_IRQ(port) ((port)->irq + 1)
+#define RX_IRQ(port) ((port)->irq)
+
+/* macros to change one thing to another */
+
+#define tx_enabled(port) ((port)->unused[0])
+#define rx_enabled(port) ((port)->unused[1])
+
+/* flag to ignore all characters comming in */
+#define RXSTAT_DUMMY_READ (0x10000000)
+
+static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
+{
+ return container_of(port, struct s3c24xx_uart_port, port);
+}
+
+/* translate a port to the device name */
+
+static inline const char *s3c24xx_serial_portname(struct uart_port *port)
+{
+ return to_platform_device(port->dev)->name;
+}
+
+static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
+{
+ return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
+}
+
+static void s3c24xx_serial_rx_enable(struct uart_port *port)
+{
+ unsigned long flags;
+ unsigned int ucon, ufcon;
+ int count = 10000;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ while (--count && !s3c24xx_serial_txempty_nofifo(port))
+ udelay(100);
+
+ ufcon = rd_regl(port, S3C2410_UFCON);
+ ufcon |= S3C2410_UFCON_RESETRX;
+ wr_regl(port, S3C2410_UFCON, ufcon);
+
+ ucon = rd_regl(port, S3C2410_UCON);
+ ucon |= S3C2410_UCON_RXIRQMODE;
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ rx_enabled(port) = 1;
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void s3c24xx_serial_rx_disable(struct uart_port *port)
+{
+ unsigned long flags;
+ unsigned int ucon;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ ucon = rd_regl(port, S3C2410_UCON);
+ ucon &= ~S3C2410_UCON_RXIRQMODE;
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ rx_enabled(port) = 0;
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void s3c24xx_serial_stop_tx(struct uart_port *port)
+{
+ if (tx_enabled(port)) {
+ disable_irq(TX_IRQ(port));
+ tx_enabled(port) = 0;
+ if (port->flags & UPF_CONS_FLOW)
+ s3c24xx_serial_rx_enable(port);
+ }
+}
+
+static void s3c24xx_serial_start_tx(struct uart_port *port)
+{
+ if (!tx_enabled(port)) {
+ if (port->flags & UPF_CONS_FLOW)
+ s3c24xx_serial_rx_disable(port);
+
+ enable_irq(TX_IRQ(port));
+ tx_enabled(port) = 1;
+ }
+}
+
+
+static void s3c24xx_serial_stop_rx(struct uart_port *port)
+{
+ if (rx_enabled(port)) {
+ dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
+ disable_irq(RX_IRQ(port));
+ rx_enabled(port) = 0;
+ }
+}
+
+static void s3c24xx_serial_enable_ms(struct uart_port *port)
+{
+}
+
+static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
+{
+ return to_ourport(port)->info;
+}
+
+static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
+{
+ if (port->dev == NULL)
+ return NULL;
+
+ return (struct s3c2410_uartcfg *)port->dev->platform_data;
+}
+
+static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
+ unsigned long ufstat)
+{
+ struct s3c24xx_uart_info *info = ourport->info;
+
+ if (ufstat & info->rx_fifofull)
+ return info->fifosize;
+
+ return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
+}
+
+
+/* ? - where has parity gone?? */
+#define S3C2410_UERSTAT_PARITY (0x1000)
+
+static irqreturn_t
+s3c24xx_serial_rx_chars(int irq, void *dev_id)
+{
+ struct s3c24xx_uart_port *ourport = dev_id;
+ struct uart_port *port = &ourport->port;
+ struct tty_struct *tty = port->info->tty;
+ unsigned int ufcon, ch, flag, ufstat, uerstat;
+ int max_count = 64;
+
+ while (max_count-- > 0) {
+ ufcon = rd_regl(port, S3C2410_UFCON);
+ ufstat = rd_regl(port, S3C2410_UFSTAT);
+
+ if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
+ break;
+
+ uerstat = rd_regl(port, S3C2410_UERSTAT);
+ ch = rd_regb(port, S3C2410_URXH);
+
+ if (port->flags & UPF_CONS_FLOW) {
+ int txe = s3c24xx_serial_txempty_nofifo(port);
+
+ if (rx_enabled(port)) {
+ if (!txe) {
+ rx_enabled(port) = 0;
+ continue;
+ }
+ } else {
+ if (txe) {
+ ufcon |= S3C2410_UFCON_RESETRX;
+ wr_regl(port, S3C2410_UFCON, ufcon);
+ rx_enabled(port) = 1;
+ goto out;
+ }
+ continue;
+ }
+ }
+
+ /* insert the character into the buffer */
+
+ flag = TTY_NORMAL;
+ port->icount.rx++;
+
+ if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
+ dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
+ ch, uerstat);
+
+ /* check for break */
+ if (uerstat & S3C2410_UERSTAT_BREAK) {
+ dbg("break!\n");
+ port->icount.brk++;
+ if (uart_handle_break(port))
+ goto ignore_char;
+ }
+
+ if (uerstat & S3C2410_UERSTAT_FRAME)
+ port->icount.frame++;
+ if (uerstat & S3C2410_UERSTAT_OVERRUN)
+ port->icount.overrun++;
+
+ uerstat &= port->read_status_mask;
+
+ if (uerstat & S3C2410_UERSTAT_BREAK)
+ flag = TTY_BREAK;
+ else if (uerstat & S3C2410_UERSTAT_PARITY)
+ flag = TTY_PARITY;
+ else if (uerstat & (S3C2410_UERSTAT_FRAME |
+ S3C2410_UERSTAT_OVERRUN))
+ flag = TTY_FRAME;
+ }
+
+ if (uart_handle_sysrq_char(port, ch))
+ goto ignore_char;
+
+ uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
+ ch, flag);
+
+ ignore_char:
+ continue;
+ }
+ tty_flip_buffer_push(tty);
+
+ out:
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
+{
+ struct s3c24xx_uart_port *ourport = id;
+ struct uart_port *port = &ourport->port;
+ struct circ_buf *xmit = &port->info->xmit;
+ int count = 256;
+
+ if (port->x_char) {
+ wr_regb(port, S3C2410_UTXH, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+ goto out;
+ }
+
+ /* if there isnt anything more to transmit, or the uart is now
+ * stopped, disable the uart and exit
+ */
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ s3c24xx_serial_stop_tx(port);
+ goto out;
+ }
+
+ /* try and drain the buffer... */
+
+ while (!uart_circ_empty(xmit) && count-- > 0) {
+ if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
+ break;
+
+ wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ }
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ s3c24xx_serial_stop_tx(port);
+
+ out:
+ return IRQ_HANDLED;
+}
+
+static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
+ unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
+
+ if (ufcon & S3C2410_UFCON_FIFOMODE) {
+ if ((ufstat & info->tx_fifomask) != 0 ||
+ (ufstat & info->tx_fifofull))
+ return 0;
+
+ return 1;
+ }
+
+ return s3c24xx_serial_txempty_nofifo(port);
+}
+
+/* no modem control lines */
+static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
+{
+ unsigned int umstat = rd_regb(port, S3C2410_UMSTAT);
+
+ if (umstat & S3C2410_UMSTAT_CTS)
+ return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+ else
+ return TIOCM_CAR | TIOCM_DSR;
+}
+
+static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* todo - possibly remove AFC and do manual CTS */
+}
+
+static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
+{
+ unsigned long flags;
+ unsigned int ucon;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ ucon = rd_regl(port, S3C2410_UCON);
+
+ if (break_state)
+ ucon |= S3C2410_UCON_SBREAK;
+ else
+ ucon &= ~S3C2410_UCON_SBREAK;
+
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void s3c24xx_serial_shutdown(struct uart_port *port)
+{
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+ if (ourport->tx_claimed) {
+ free_irq(TX_IRQ(port), ourport);
+ tx_enabled(port) = 0;
+ ourport->tx_claimed = 0;
+ }
+
+ if (ourport->rx_claimed) {
+ free_irq(RX_IRQ(port), ourport);
+ ourport->rx_claimed = 0;
+ rx_enabled(port) = 0;
+ }
+}
+
+
+static int s3c24xx_serial_startup(struct uart_port *port)
+{
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+ int ret;
+
+ dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
+ port->mapbase, port->membase);
+
+ rx_enabled(port) = 1;
+
+ ret = request_irq(RX_IRQ(port),
+ s3c24xx_serial_rx_chars, 0,
+ s3c24xx_serial_portname(port), ourport);
+
+ if (ret != 0) {
+ printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port));
+ return ret;
+ }
+
+ ourport->rx_claimed = 1;
+
+ dbg("requesting tx irq...\n");
+
+ tx_enabled(port) = 1;
+
+ ret = request_irq(TX_IRQ(port),
+ s3c24xx_serial_tx_chars, 0,
+ s3c24xx_serial_portname(port), ourport);
+
+ if (ret) {
+ printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port));
+ goto err;
+ }
+
+ ourport->tx_claimed = 1;
+
+ dbg("s3c24xx_serial_startup ok\n");
+
+ /* the port reset code should have done the correct
+ * register setup for the port controls */
+
+ return ret;
+
+ err:
+ s3c24xx_serial_shutdown(port);
+ return ret;
+}
+
+/* power power management control */
+
+static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
+ unsigned int old)
+{
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+ switch (level) {
+ case 3:
+ if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
+ clk_disable(ourport->baudclk);
+
+ clk_disable(ourport->clk);
+ break;
+
+ case 0:
+ clk_enable(ourport->clk);
+
+ if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
+ clk_enable(ourport->baudclk);
+
+ break;
+ default:
+ printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level);
+ }
+}
+
+/* baud rate calculation
+ *
+ * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
+ * of different sources, including the peripheral clock ("pclk") and an
+ * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
+ * with a programmable extra divisor.
+ *
+ * The following code goes through the clock sources, and calculates the
+ * baud clocks (and the resultant actual baud rates) and then tries to
+ * pick the closest one and select that.
+ *
+*/
+
+
+#define MAX_CLKS (8)
+
+static struct s3c24xx_uart_clksrc tmp_clksrc = {
+ .name = "pclk",
+ .min_baud = 0,
+ .max_baud = 0,
+ .divisor = 1,
+};
+
+static inline int
+s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+ return (info->get_clksrc)(port, c);
+}
+
+static inline int
+s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+ return (info->set_clksrc)(port, c);
+}
+
+struct baud_calc {
+ struct s3c24xx_uart_clksrc *clksrc;
+ unsigned int calc;
+ unsigned int quot;
+ struct clk *src;
+};
+
+static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
+ struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clksrc,
+ unsigned int baud)
+{
+ unsigned long rate;
+
+ calc->src = clk_get(port->dev, clksrc->name);
+ if (calc->src == NULL || IS_ERR(calc->src))
+ return 0;
+
+ rate = clk_get_rate(calc->src);
+ rate /= clksrc->divisor;
+
+ calc->clksrc = clksrc;
+ calc->quot = (rate + (8 * baud)) / (16 * baud);
+ calc->calc = (rate / (calc->quot * 16));
+
+ calc->quot--;
+ return 1;
+}
+
+static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
+ struct s3c24xx_uart_clksrc **clksrc,
+ struct clk **clk,
+ unsigned int baud)
+{
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+ struct s3c24xx_uart_clksrc *clkp;
+ struct baud_calc res[MAX_CLKS];
+ struct baud_calc *resptr, *best, *sptr;
+ int i;
+
+ clkp = cfg->clocks;
+ best = NULL;
+
+ if (cfg->clocks_size < 2) {
+ if (cfg->clocks_size == 0)
+ clkp = &tmp_clksrc;
+
+ /* check to see if we're sourcing fclk, and if so we're
+ * going to have to update the clock source
+ */
+
+ if (strcmp(clkp->name, "fclk") == 0) {
+ struct s3c24xx_uart_clksrc src;
+
+ s3c24xx_serial_getsource(port, &src);
+
+ /* check that the port already using fclk, and if
+ * not, then re-select fclk
+ */
+
+ if (strcmp(src.name, clkp->name) == 0) {
+ s3c24xx_serial_setsource(port, clkp);
+ s3c24xx_serial_getsource(port, &src);
+ }
+
+ clkp->divisor = src.divisor;
+ }
+
+ s3c24xx_serial_calcbaud(res, port, clkp, baud);
+ best = res;
+ resptr = best + 1;
+ } else {
+ resptr = res;
+
+ for (i = 0; i < cfg->clocks_size; i++, clkp++) {
+ if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
+ resptr++;
+ }
+ }
+
+ /* ok, we now need to select the best clock we found */
+
+ if (!best) {
+ unsigned int deviation = (1<<30)|((1<<30)-1);
+ int calc_deviation;
+
+ for (sptr = res; sptr < resptr; sptr++) {
+ calc_deviation = baud - sptr->calc;
+ if (calc_deviation < 0)
+ calc_deviation = -calc_deviation;
+
+ if (calc_deviation < deviation) {
+ best = sptr;
+ deviation = calc_deviation;
+ }
+ }
+ }
+
+ /* store results to pass back */
+
+ *clksrc = best->clksrc;
+ *clk = best->src;
+
+ return best->quot;
+}
+
+static void s3c24xx_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+ struct s3c24xx_uart_clksrc *clksrc = NULL;
+ struct clk *clk = NULL;
+ unsigned long flags;
+ unsigned int baud, quot;
+ unsigned int ulcon;
+ unsigned int umcon;
+
+ /*
+ * We don't support modem control lines.
+ */
+ termios->c_cflag &= ~(HUPCL | CMSPAR);
+ termios->c_cflag |= CLOCAL;
+
+ /*
+ * Ask the core to calculate the divisor for us.
+ */
+
+ baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
+
+ if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
+ quot = port->custom_divisor;
+ else
+ quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);
+
+ /* check to see if we need to change clock source */
+
+ if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
+ s3c24xx_serial_setsource(port, clksrc);
+
+ if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
+ clk_disable(ourport->baudclk);
+ ourport->baudclk = NULL;
+ }
+
+ clk_enable(clk);
+
+ ourport->clksrc = clksrc;
+ ourport->baudclk = clk;
+ }
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ dbg("config: 5bits/char\n");
+ ulcon = S3C2410_LCON_CS5;
+ break;
+ case CS6:
+ dbg("config: 6bits/char\n");
+ ulcon = S3C2410_LCON_CS6;
+ break;
+ case CS7:
+ dbg("config: 7bits/char\n");
+ ulcon = S3C2410_LCON_CS7;
+ break;
+ case CS8:
+ default:
+ dbg("config: 8bits/char\n");
+ ulcon = S3C2410_LCON_CS8;
+ break;
+ }
+
+ /* preserve original lcon IR settings */
+ ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
+
+ if (termios->c_cflag & CSTOPB)
+ ulcon |= S3C2410_LCON_STOPB;
+
+ umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
+
+ if (termios->c_cflag & PARENB) {
+ if (termios->c_cflag & PARODD)
+ ulcon |= S3C2410_LCON_PODD;
+ else
+ ulcon |= S3C2410_LCON_PEVEN;
+ } else {
+ ulcon |= S3C2410_LCON_PNONE;
+ }
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);
+
+ wr_regl(port, S3C2410_ULCON, ulcon);
+ wr_regl(port, S3C2410_UBRDIV, quot);
+ wr_regl(port, S3C2410_UMCON, umcon);
+
+ dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
+ rd_regl(port, S3C2410_ULCON),
+ rd_regl(port, S3C2410_UCON),
+ rd_regl(port, S3C2410_UFCON));
+
+ /*
+ * Update the per-port timeout.
+ */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ /*
+ * Which character status flags are we interested in?
+ */
+ port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY;
+
+ /*
+ * Which character status flags should we ignore?
+ */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
+ if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;
+
+ /*
+ * Ignore all characters if CREAD is not set.
+ */
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |= RXSTAT_DUMMY_READ;
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *s3c24xx_serial_type(struct uart_port *port)
+{
+ switch (port->type) {
+ case PORT_S3C2410:
+ return "S3C2410";
+ case PORT_S3C2440:
+ return "S3C2440";
+ case PORT_S3C2412:
+ return "S3C2412";
+ default:
+ return NULL;
+ }
+}
+
+#define MAP_SIZE (0x100)
+
+static void s3c24xx_serial_release_port(struct uart_port *port)
+{
+ release_mem_region(port->mapbase, MAP_SIZE);
+}
+
+static int s3c24xx_serial_request_port(struct uart_port *port)
+{
+ const char *name = s3c24xx_serial_portname(port);
+ return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
+}
+
+static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+ if (flags & UART_CONFIG_TYPE &&
+ s3c24xx_serial_request_port(port) == 0)
+ port->type = info->type;
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int
+s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+ if (ser->type != PORT_UNKNOWN && ser->type != info->type)
+ return -EINVAL;
+
+ return 0;
+}
+
+
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+
+static struct console s3c24xx_serial_console;
+
+#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
+#else
+#define S3C24XX_SERIAL_CONSOLE NULL
+#endif
+
+static struct uart_ops s3c24xx_serial_ops = {
+ .pm = s3c24xx_serial_pm,
+ .tx_empty = s3c24xx_serial_tx_empty,
+ .get_mctrl = s3c24xx_serial_get_mctrl,
+ .set_mctrl = s3c24xx_serial_set_mctrl,
+ .stop_tx = s3c24xx_serial_stop_tx,
+ .start_tx = s3c24xx_serial_start_tx,
+ .stop_rx = s3c24xx_serial_stop_rx,
+ .enable_ms = s3c24xx_serial_enable_ms,
+ .break_ctl = s3c24xx_serial_break_ctl,
+ .startup = s3c24xx_serial_startup,
+ .shutdown = s3c24xx_serial_shutdown,
+ .set_termios = s3c24xx_serial_set_termios,
+ .type = s3c24xx_serial_type,
+ .release_port = s3c24xx_serial_release_port,
+ .request_port = s3c24xx_serial_request_port,
+ .config_port = s3c24xx_serial_config_port,
+ .verify_port = s3c24xx_serial_verify_port,
+};
+
+
+static struct uart_driver s3c24xx_uart_drv = {
+ .owner = THIS_MODULE,
+ .dev_name = "s3c2410_serial",
+ .nr = 3,
+ .cons = S3C24XX_SERIAL_CONSOLE,
+ .driver_name = S3C24XX_SERIAL_NAME,
+ .major = S3C24XX_SERIAL_MAJOR,
+ .minor = S3C24XX_SERIAL_MINOR,
+};
+
+static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
+ [0] = {
+ .port = {
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
+ .iotype = UPIO_MEM,
+ .irq = IRQ_S3CUART_RX0,
+ .uartclk = 0,
+ .fifosize = 16,
+ .ops = &s3c24xx_serial_ops,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 0,
+ }
+ },
+ [1] = {
+ .port = {
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
+ .iotype = UPIO_MEM,
+ .irq = IRQ_S3CUART_RX1,
+ .uartclk = 0,
+ .fifosize = 16,
+ .ops = &s3c24xx_serial_ops,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 1,
+ }
+ },
+#if NR_PORTS > 2
+
+ [2] = {
+ .port = {
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
+ .iotype = UPIO_MEM,
+ .irq = IRQ_S3CUART_RX2,
+ .uartclk = 0,
+ .fifosize = 16,
+ .ops = &s3c24xx_serial_ops,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 2,
+ }
+ }
+#endif
+};
+
+/* s3c24xx_serial_resetport
+ *
+ * wrapper to call the specific reset for this port (reset the fifos
+ * and the settings)
+*/
+
+static inline int s3c24xx_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+
+ return (info->reset_port)(port, cfg);
+}
+
+/* s3c24xx_serial_init_port
+ *
+ * initialise a single serial port from the platform device given
+ */
+
+static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
+ struct s3c24xx_uart_info *info,
+ struct platform_device *platdev)
+{
+ struct uart_port *port = &ourport->port;
+ struct s3c2410_uartcfg *cfg;
+ struct resource *res;
+ int ret;
+
+ dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);
+
+ if (platdev == NULL)
+ return -ENODEV;
+
+ cfg = s3c24xx_dev_to_cfg(&platdev->dev);
+
+ if (port->mapbase != 0)
+ return 0;
+
+ if (cfg->hwport > 3)
+ return -EINVAL;
+
+ /* setup info for port */
+ port->dev = &platdev->dev;
+ ourport->info = info;
+
+ /* copy the info in from provided structure */
+ ourport->port.fifosize = info->fifosize;
+
+ dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);
+
+ port->uartclk = 1;
+
+ if (cfg->uart_flags & UPF_CONS_FLOW) {
+ dbg("s3c24xx_serial_init_port: enabling flow control\n");
+ port->flags |= UPF_CONS_FLOW;
+ }
+
+ /* sort our the physical and virtual addresses for each UART */
+
+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ printk(KERN_ERR "failed to find memory resource for uart\n");
+ return -EINVAL;
+ }
+
+ dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
+
+ port->mapbase = res->start;
+ port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
+ ret = platform_get_irq(platdev, 0);
+ if (ret < 0)
+ port->irq = 0;
+ else
+ port->irq = ret;
+
+ ourport->clk = clk_get(&platdev->dev, "uart");
+
+ dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
+ port->mapbase, port->membase, port->irq, port->uartclk);
+
+ /* reset the fifos (and setup the uart) */
+ s3c24xx_serial_resetport(port, cfg);
+ return 0;
+}
+
+static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct uart_port *port = s3c24xx_dev_to_port(dev);
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+ return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name);
+}
+
+static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
+
+/* Device driver serial port probe */
+
+static int probe_index;
+
+int s3c24xx_serial_probe(struct platform_device *dev,
+ struct s3c24xx_uart_info *info)
+{
+ struct s3c24xx_uart_port *ourport;
+ int ret;
+
+ dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
+
+ ourport = &s3c24xx_serial_ports[probe_index];
+ probe_index++;
+
+ dbg("%s: initialising port %p...\n", __func__, ourport);
+
+ ret = s3c24xx_serial_init_port(ourport, info, dev);
+ if (ret < 0)
+ goto probe_err;
+
+ dbg("%s: adding port\n", __func__);
+ uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
+ platform_set_drvdata(dev, &ourport->port);
+
+ ret = device_create_file(&dev->dev, &dev_attr_clock_source);
+ if (ret < 0)
+ printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__);
+
+ return 0;
+
+ probe_err:
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(s3c24xx_serial_probe);
+
+int s3c24xx_serial_remove(struct platform_device *dev)
+{
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
+
+ if (port) {
+ device_remove_file(&dev->dev, &dev_attr_clock_source);
+ uart_remove_one_port(&s3c24xx_uart_drv, port);
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(s3c24xx_serial_remove);
+
+/* UART power management code */
+
+#ifdef CONFIG_PM
+
+static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
+
+ if (port)
+ uart_suspend_port(&s3c24xx_uart_drv, port);
+
+ return 0;
+}
+
+static int s3c24xx_serial_resume(struct platform_device *dev)
+{
+ struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+ if (port) {
+ clk_enable(ourport->clk);
+ s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+ clk_disable(ourport->clk);
+
+ uart_resume_port(&s3c24xx_uart_drv, port);
+ }
+
+ return 0;
+}
+#endif
+
+int s3c24xx_serial_init(struct platform_driver *drv,
+ struct s3c24xx_uart_info *info)
+{
+ dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
+
+#ifdef CONFIG_PM
+ drv->suspend = s3c24xx_serial_suspend;
+ drv->resume = s3c24xx_serial_resume;
+#endif
+
+ return platform_driver_register(drv);
+}
+
+EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
+
+/* module initialisation code */
+
+static int __init s3c24xx_serial_modinit(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&s3c24xx_uart_drv);
+ if (ret < 0) {
+ printk(KERN_ERR "failed to register UART driver\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __exit s3c24xx_serial_modexit(void)
+{
+ uart_unregister_driver(&s3c24xx_uart_drv);
+}
+
+module_init(s3c24xx_serial_modinit);
+module_exit(s3c24xx_serial_modexit);
+
+/* Console code */
+
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+
+static struct uart_port *cons_uart;
+
+static int
+s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
+{
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+ unsigned long ufstat, utrstat;
+
+ if (ufcon & S3C2410_UFCON_FIFOMODE) {
+ /* fifo mode - check ammount of data in fifo registers... */
+
+ ufstat = rd_regl(port, S3C2410_UFSTAT);
+ return (ufstat & info->tx_fifofull) ? 0 : 1;
+ }
+
+ /* in non-fifo mode, we go and use the tx buffer empty */
+
+ utrstat = rd_regl(port, S3C2410_UTRSTAT);
+ return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
+}
+
+static void
+s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
+{
+ unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
+ while (!s3c24xx_serial_console_txrdy(port, ufcon))
+ barrier();
+ wr_regb(cons_uart, S3C2410_UTXH, ch);
+}
+
+static void
+s3c24xx_serial_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
+}
+
+static void __init
+s3c24xx_serial_get_options(struct uart_port *port, int *baud,
+ int *parity, int *bits)
+{
+ struct s3c24xx_uart_clksrc clksrc;
+ struct clk *clk;
+ unsigned int ulcon;
+ unsigned int ucon;
+ unsigned int ubrdiv;
+ unsigned long rate;
+
+ ulcon = rd_regl(port, S3C2410_ULCON);
+ ucon = rd_regl(port, S3C2410_UCON);
+ ubrdiv = rd_regl(port, S3C2410_UBRDIV);
+
+ dbg("s3c24xx_serial_get_options: port=%p\n"
+ "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n",
+ port, ulcon, ucon, ubrdiv);
+
+ if ((ucon & 0xf) != 0) {
+ /* consider the serial port configured if the tx/rx mode set */
+
+ switch (ulcon & S3C2410_LCON_CSMASK) {
+ case S3C2410_LCON_CS5:
+ *bits = 5;
+ break;
+ case S3C2410_LCON_CS6:
+ *bits = 6;
+ break;
+ case S3C2410_LCON_CS7:
+ *bits = 7;
+ break;
+ default:
+ case S3C2410_LCON_CS8:
+ *bits = 8;
+ break;
+ }
+
+ switch (ulcon & S3C2410_LCON_PMASK) {
+ case S3C2410_LCON_PEVEN:
+ *parity = 'e';
+ break;
+
+ case S3C2410_LCON_PODD:
+ *parity = 'o';
+ break;
+
+ case S3C2410_LCON_PNONE:
+ default:
+ *parity = 'n';
+ }
+
+ /* now calculate the baud rate */
+
+ s3c24xx_serial_getsource(port, &clksrc);
+
+ clk = clk_get(port->dev, clksrc.name);
+ if (!IS_ERR(clk) && clk != NULL)
+ rate = clk_get_rate(clk) / clksrc.divisor;
+ else
+ rate = 1;
+
+
+ *baud = rate / (16 * (ubrdiv + 1));
+ dbg("calculated baud %d\n", *baud);
+ }
+
+}
+
+/* s3c24xx_serial_init_ports
+ *
+ * initialise the serial ports from the machine provided initialisation
+ * data.
+*/
+
+static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
+{
+ struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
+ struct platform_device **platdev_ptr;
+ int i;
+
+ dbg("s3c24xx_serial_init_ports: initialising ports...\n");
+
+ platdev_ptr = s3c24xx_uart_devs;
+
+ for (i = 0; i < NR_PORTS; i++, ptr++, platdev_ptr++) {
+ s3c24xx_serial_init_port(ptr, info, *platdev_ptr);
+ }
+
+ return 0;
+}
+
+static int __init
+s3c24xx_serial_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 9600;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n",
+ co, co->index, options);
+
+ /* is this a valid port */
+
+ if (co->index == -1 || co->index >= NR_PORTS)
+ co->index = 0;
+
+ port = &s3c24xx_serial_ports[co->index].port;
+
+ /* is the port configured? */
+
+ if (port->mapbase == 0x0) {
+ co->index = 0;
+ port = &s3c24xx_serial_ports[co->index].port;
+ }
+
+ cons_uart = port;
+
+ dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index);
+
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else
+ s3c24xx_serial_get_options(port, &baud, &parity, &bits);
+
+ dbg("s3c24xx_serial_console_setup: baud %d\n", baud);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+/* s3c24xx_serial_initconsole
+ *
+ * initialise the console from one of the uart drivers
+*/
+
+static struct console s3c24xx_serial_console = {
+ .name = S3C24XX_SERIAL_NAME,
+ .device = uart_console_device,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .write = s3c24xx_serial_console_write,
+ .setup = s3c24xx_serial_console_setup
+};
+
+int s3c24xx_serial_initconsole(struct platform_driver *drv,
+ struct s3c24xx_uart_info *info)
+
+{
+ struct platform_device *dev = s3c24xx_uart_devs[0];
+
+ dbg("s3c24xx_serial_initconsole\n");
+
+ /* select driver based on the cpu */
+
+ if (dev == NULL) {
+ printk(KERN_ERR "s3c24xx: no devices for console init\n");
+ return 0;
+ }
+
+ if (strcmp(dev->name, drv->driver.name) != 0)
+ return 0;
+
+ s3c24xx_serial_console.data = &s3c24xx_uart_drv;
+ s3c24xx_serial_init_ports(info);
+
+ register_console(&s3c24xx_serial_console);
+ return 0;
+}
+
+#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
+
+MODULE_DESCRIPTION("Samsung SoC Serial port driver");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h
new file mode 100644
index 00000000000..5c92ebbe7d9
--- /dev/null
+++ b/drivers/serial/samsung.h
@@ -0,0 +1,102 @@
+/* linux/drivers/serial/samsung.h
+ *
+ * Driver for Samsung SoC onboard UARTs.
+ *
+ * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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.
+*/
+
+struct s3c24xx_uart_info {
+ char *name;
+ unsigned int type;
+ unsigned int fifosize;
+ unsigned long rx_fifomask;
+ unsigned long rx_fifoshift;
+ unsigned long rx_fifofull;
+ unsigned long tx_fifomask;
+ unsigned long tx_fifoshift;
+ unsigned long tx_fifofull;
+
+ /* clock source control */
+
+ int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
+ int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
+
+ /* uart controls */
+ int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
+};
+
+struct s3c24xx_uart_port {
+ unsigned char rx_claimed;
+ unsigned char tx_claimed;
+
+ struct s3c24xx_uart_info *info;
+ struct s3c24xx_uart_clksrc *clksrc;
+ struct clk *clk;
+ struct clk *baudclk;
+ struct uart_port port;
+};
+
+/* conversion functions */
+
+#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
+#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
+
+/* register access controls */
+
+#define portaddr(port, reg) ((port)->membase + (reg))
+
+#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
+#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
+
+#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
+#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
+
+extern int s3c24xx_serial_probe(struct platform_device *dev,
+ struct s3c24xx_uart_info *uart);
+
+extern int s3c24xx_serial_remove(struct platform_device *dev);
+
+extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
+ struct s3c24xx_uart_info *uart);
+
+extern int s3c24xx_serial_init(struct platform_driver *drv,
+ struct s3c24xx_uart_info *info);
+
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
+
+#define s3c24xx_console_init(__drv, __inf) \
+static int __init s3c_serial_console_init(void) \
+{ \
+ return s3c24xx_serial_initconsole(__drv, __inf); \
+} \
+ \
+console_initcall(s3c_serial_console_init)
+
+#else
+#define s3c24xx_console_init(drv, inf) extern void no_console(void)
+#endif
+
+#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
+
+extern void printascii(const char *);
+
+static void dbg(const char *fmt, ...)
+{
+ va_list va;
+ char buff[256];
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ printascii(buff);
+}
+
+#else
+#define dbg(x...) do { } while (0)
+#endif
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index c730d05bfeb..547e3029827 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1526,24 +1526,24 @@ static int __init spi_imx_probe(struct platform_device *pdev)
drv_data->rx_channel = -1;
if (platform_info->enable_dma) {
/* Get rx DMA channel */
- status = imx_dma_request_by_prio(&drv_data->rx_channel,
- "spi_imx_rx", DMA_PRIO_HIGH);
- if (status < 0) {
+ 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",
- status);
+ 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 */
- status = imx_dma_request_by_prio(&drv_data->tx_channel,
- "spi_imx_tx", DMA_PRIO_MEDIUM);
- if (status < 0) {
+ 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",
- status);
+ drv_data->tx_channel);
imx_dma_free(drv_data->rx_channel);
goto err_no_txdma;
} else
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 4b628526df0..a86e952ed4c 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -12,3 +12,12 @@ menuconfig THERMAL
cooling devices.
All platforms with ACPI thermal support can use this driver.
If you want this support, you should say Y or M here.
+
+config THERMAL_HWMON
+ bool "Hardware monitoring support"
+ depends on HWMON=y || HWMON=THERMAL
+ help
+ The generic thermal sysfs driver's hardware monitoring support
+ requires a 2.10.7/3.0.2 or later lm-sensors userspace.
+
+ Say Y if your user-space is new enough.
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 6098787341f..fe07462d594 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -295,8 +295,8 @@ thermal_cooling_device_trip_point_show(struct device *dev,
/* Device management */
-#if defined(CONFIG_HWMON) || \
- (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
+
/* hwmon sys I/F */
#include <linux/hwmon.h>
static LIST_HEAD(thermal_hwmon_list);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 6e784d2db42..3565d435282 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -118,10 +118,10 @@ config USB_AMD5536UDC
config USB_GADGET_ATMEL_USBA
boolean "Atmel USBA"
select USB_GADGET_DUALSPEED
- depends on AVR32 || ARCH_AT91CAP9
+ depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL
help
USBA is the integrated high-speed USB Device controller on
- the AT32AP700x and AT91CAP9 processors from Atmel.
+ the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
config USB_ATMEL_USBA
tristate
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 274c60a970c..b6b2a0a5ba3 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -888,7 +888,7 @@ static void pullup(struct at91_udc *udc, int is_on)
at91_udp_write(udc, AT91_UDP_TXVC, 0);
if (cpu_is_at91rm9200())
gpio_set_value(udc->board.pullup_pin, active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
+ else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
txvc |= AT91_UDP_TXVC_PUON;
@@ -906,7 +906,7 @@ static void pullup(struct at91_udc *udc, int is_on)
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
if (cpu_is_at91rm9200())
gpio_set_value(udc->board.pullup_pin, !active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
+ else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
txvc &= ~AT91_UDP_TXVC_PUON;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 881d74c3d96..03a7f49d207 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -135,13 +135,17 @@ static void use_ep(struct omap_ep *ep, u16 select)
if (ep->bEndpointAddress & USB_DIR_IN)
num |= UDC_EP_DIR;
- UDC_EP_NUM_REG = num | select;
+ omap_writew(num | select, UDC_EP_NUM);
/* when select, MUST deselect later !! */
}
static inline void deselect_ep(void)
{
- UDC_EP_NUM_REG &= ~UDC_EP_SEL;
+ u16 w;
+
+ w = omap_readw(UDC_EP_NUM);
+ w &= ~UDC_EP_SEL;
+ omap_writew(w, UDC_EP_NUM);
/* 6 wait states before TX will happen */
}
@@ -216,7 +220,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
ep->has_dma = 0;
ep->lch = -1;
use_ep(ep, UDC_EP_SEL);
- UDC_CTRL_REG = udc->clr_halt;
+ omap_writew(udc->clr_halt, UDC_CTRL);
ep->ackwait = 0;
deselect_ep();
@@ -232,7 +236,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
if (desc->bmAttributes != USB_ENDPOINT_XFER_ISOC
&& !ep->has_dma
&& !(ep->bEndpointAddress & USB_DIR_IN)) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
@@ -259,7 +263,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
nuke (ep, -ESHUTDOWN);
ep->ep.maxpacket = ep->maxpacket;
ep->has_dma = 0;
- UDC_CTRL_REG = UDC_SET_HALT;
+ omap_writew(UDC_SET_HALT, UDC_CTRL);
list_del_init(&ep->iso);
del_timer(&ep->timer);
@@ -360,13 +364,13 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max)
if (likely((((int)buf) & 1) == 0)) {
wp = (u16 *)buf;
while (max >= 2) {
- UDC_DATA_REG = *wp++;
+ omap_writew(*wp++, UDC_DATA);
max -= 2;
}
buf = (u8 *)wp;
}
while (max--)
- *(volatile u8 *)&UDC_DATA_REG = *buf++;
+ omap_writeb(*buf++, UDC_DATA);
return len;
}
@@ -385,13 +389,13 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req)
prefetch(buf);
/* PIO-IN isn't double buffered except for iso */
- ep_stat = UDC_STAT_FLG_REG;
+ ep_stat = omap_readw(UDC_STAT_FLG);
if (ep_stat & UDC_FIFO_UNWRITABLE)
return 0;
count = ep->ep.maxpacket;
count = write_packet(buf, req, count);
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1;
/* last packet is often short (sometimes a zlp) */
@@ -425,13 +429,13 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail)
if (likely((((int)buf) & 1) == 0)) {
wp = (u16 *)buf;
while (avail >= 2) {
- *wp++ = UDC_DATA_REG;
+ *wp++ = omap_readw(UDC_DATA);
avail -= 2;
}
buf = (u8 *)wp;
}
while (avail--)
- *buf++ = *(volatile u8 *)&UDC_DATA_REG;
+ *buf++ = omap_readb(UDC_DATA);
return len;
}
@@ -446,7 +450,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
prefetchw(buf);
for (;;) {
- u16 ep_stat = UDC_STAT_FLG_REG;
+ u16 ep_stat = omap_readw(UDC_STAT_FLG);
is_last = 0;
if (ep_stat & FIFO_EMPTY) {
@@ -460,7 +464,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
if (ep_stat & UDC_FIFO_FULL)
avail = ep->ep.maxpacket;
else {
- avail = UDC_RXFSTAT_REG;
+ avail = omap_readw(UDC_RXFSTAT);
ep->fnf = ep->double_buf;
}
count = read_packet(buf, req, avail);
@@ -473,7 +477,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
req->req.status = -EOVERFLOW;
avail -= count;
while (avail--)
- (void) *(volatile u8 *)&UDC_DATA_REG;
+ omap_readw(UDC_DATA);
}
} else if (req->req.length == req->req.actual)
is_last = 1;
@@ -491,32 +495,6 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req)
/*-------------------------------------------------------------------------*/
-static inline dma_addr_t dma_csac(unsigned lch)
-{
- dma_addr_t csac;
-
- /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- csac = OMAP_DMA_CSAC_REG(lch);
- if (csac == 0)
- csac = OMAP_DMA_CSAC_REG(lch);
- return csac;
-}
-
-static inline dma_addr_t dma_cdac(unsigned lch)
-{
- dma_addr_t cdac;
-
- /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- cdac = OMAP_DMA_CDAC_REG(lch);
- if (cdac == 0)
- cdac = OMAP_DMA_CDAC_REG(lch);
- return cdac;
-}
-
static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
{
dma_addr_t end;
@@ -527,7 +505,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
if (cpu_is_omap15xx())
return 0;
- end = dma_csac(ep->lch);
+ end = omap_get_dma_src_pos(ep->lch);
if (end == ep->dma_counter)
return 0;
@@ -537,15 +515,11 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
return end - start;
}
-#define DMA_DEST_LAST(x) (cpu_is_omap15xx() \
- ? OMAP_DMA_CSAC_REG(x) /* really: CPC */ \
- : dma_cdac(x))
-
static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start)
{
dma_addr_t end;
- end = DMA_DEST_LAST(ep->lch);
+ end = omap_get_dma_dst_pos(ep->lch);
if (end == ep->dma_counter)
return 0;
@@ -565,7 +539,7 @@ static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start)
static void next_in_dma(struct omap_ep *ep, struct omap_req *req)
{
- u16 txdma_ctrl;
+ u16 txdma_ctrl, w;
unsigned length = req->req.length - req->req.actual;
const int sync_mode = cpu_is_omap15xx()
? OMAP_DMA_SYNC_FRAME
@@ -596,14 +570,18 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req)
0, 0);
omap_start_dma(ep->lch);
- ep->dma_counter = dma_csac(ep->lch);
- UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel);
- UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl;
+ ep->dma_counter = omap_get_dma_src_pos(ep->lch);
+ w = omap_readw(UDC_DMA_IRQ_EN);
+ w |= UDC_TX_DONE_IE(ep->dma_channel);
+ omap_writew(w, UDC_DMA_IRQ_EN);
+ omap_writew(UDC_TXN_START | txdma_ctrl, UDC_TXDMA(ep->dma_channel));
req->dma_bytes = length;
}
static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status)
{
+ u16 w;
+
if (status == 0) {
req->req.actual += req->dma_bytes;
@@ -620,7 +598,9 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status)
/* tx completion */
omap_stop_dma(ep->lch);
- UDC_DMA_IRQ_EN_REG &= ~UDC_TX_DONE_IE(ep->dma_channel);
+ w = omap_readw(UDC_DMA_IRQ_EN);
+ w &= ~UDC_TX_DONE_IE(ep->dma_channel);
+ omap_writew(w, UDC_DMA_IRQ_EN);
done(ep, req, status);
}
@@ -628,6 +608,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
{
unsigned packets = req->req.length - req->req.actual;
int dma_trigger = 0;
+ u16 w;
if (cpu_is_omap24xx())
dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel);
@@ -654,12 +635,14 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF,
OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual,
0, 0);
- ep->dma_counter = DMA_DEST_LAST(ep->lch);
+ ep->dma_counter = omap_get_dma_dst_pos(ep->lch);
- UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1);
- UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel);
- UDC_EP_NUM_REG = (ep->bEndpointAddress & 0xf);
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_RXN_STOP | (packets - 1), UDC_RXDMA(ep->dma_channel));
+ w = omap_readw(UDC_DMA_IRQ_EN);
+ w |= UDC_RX_EOT_IE(ep->dma_channel);
+ omap_writew(w, UDC_DMA_IRQ_EN);
+ omap_writew(ep->bEndpointAddress & 0xf, UDC_EP_NUM);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
omap_start_dma(ep->lch);
}
@@ -667,7 +650,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req)
static void
finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one)
{
- u16 count;
+ u16 count, w;
if (status == 0)
ep->dma_counter = (u16) (req->req.dma + req->req.actual);
@@ -686,13 +669,15 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one)
return;
/* rx completion */
- UDC_DMA_IRQ_EN_REG &= ~UDC_RX_EOT_IE(ep->dma_channel);
+ w = omap_readw(UDC_DMA_IRQ_EN);
+ w &= ~UDC_RX_EOT_IE(ep->dma_channel);
+ omap_writew(w, UDC_DMA_IRQ_EN);
done(ep, req, status);
}
static void dma_irq(struct omap_udc *udc, u16 irq_src)
{
- u16 dman_stat = UDC_DMAN_STAT_REG;
+ u16 dman_stat = omap_readw(UDC_DMAN_STAT);
struct omap_ep *ep;
struct omap_req *req;
@@ -706,7 +691,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src)
struct omap_req, queue);
finish_in_dma(ep, req, 0);
}
- UDC_IRQ_SRC_REG = UDC_TXN_DONE;
+ omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC);
if (!list_empty (&ep->queue)) {
req = container_of(ep->queue.next,
@@ -725,7 +710,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src)
struct omap_req, queue);
finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB);
}
- UDC_IRQ_SRC_REG = UDC_RXN_EOT;
+ omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC);
if (!list_empty (&ep->queue)) {
req = container_of(ep->queue.next,
@@ -739,7 +724,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src)
ep->irqs++;
/* omap15xx does this unasked... */
VDBG("%s, RX_CNT irq?\n", ep->ep.name);
- UDC_IRQ_SRC_REG = UDC_RXN_CNT;
+ omap_writew(UDC_RXN_CNT, UDC_IRQ_SRC);
}
}
@@ -762,9 +747,9 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
is_in = ep->bEndpointAddress & USB_DIR_IN;
if (is_in)
- reg = UDC_TXDMA_CFG_REG;
+ reg = omap_readw(UDC_TXDMA_CFG);
else
- reg = UDC_RXDMA_CFG_REG;
+ reg = omap_readw(UDC_RXDMA_CFG);
reg |= UDC_DMA_REQ; /* "pulse" activated */
ep->dma_channel = 0;
@@ -792,7 +777,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
status = omap_request_dma(dma_channel,
ep->ep.name, dma_error, ep, &ep->lch);
if (status == 0) {
- UDC_TXDMA_CFG_REG = reg;
+ omap_writew(reg, UDC_TXDMA_CFG);
/* EMIFF or SDRC */
omap_set_dma_src_burst_mode(ep->lch,
OMAP_DMA_DATA_BURST_4);
@@ -801,7 +786,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
omap_set_dma_dest_params(ep->lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG),
+ (unsigned long) io_v2p(UDC_DATA_DMA),
0, 0);
}
} else {
@@ -813,12 +798,12 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
status = omap_request_dma(dma_channel,
ep->ep.name, dma_error, ep, &ep->lch);
if (status == 0) {
- UDC_RXDMA_CFG_REG = reg;
+ omap_writew(reg, UDC_RXDMA_CFG);
/* TIPB */
omap_set_dma_src_params(ep->lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG),
+ (unsigned long) io_v2p(UDC_DATA_DMA),
0, 0);
/* EMIFF or SDRC */
omap_set_dma_dest_burst_mode(ep->lch,
@@ -834,7 +819,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
/* channel type P: hw synch (fifo) */
if (cpu_class_is_omap1() && !cpu_is_omap15xx())
- OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2;
+ omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P);
}
just_restart:
@@ -860,7 +845,7 @@ just_restart:
(is_in ? write_fifo : read_fifo)(ep, req);
deselect_ep();
if (!is_in) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
/* IN: 6 wait states before it'll tx */
@@ -881,7 +866,7 @@ static void dma_channel_release(struct omap_ep *ep)
else
req = NULL;
- active = ((1 << 7) & OMAP_DMA_CCR_REG(ep->lch)) != 0;
+ active = omap_get_dma_active_status(ep->lch);
DBG("%s release %s %cxdma%d %p\n", ep->ep.name,
active ? "active" : "idle",
@@ -894,23 +879,25 @@ static void dma_channel_release(struct omap_ep *ep)
/* wait till current packet DMA finishes, and fifo empties */
if (ep->bEndpointAddress & USB_DIR_IN) {
- UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
+ omap_writew((omap_readw(UDC_TXDMA_CFG) & ~mask) | UDC_DMA_REQ,
+ UDC_TXDMA_CFG);
if (req) {
finish_in_dma(ep, req, -ECONNRESET);
/* clear FIFO; hosts probably won't empty it */
use_ep(ep, UDC_EP_SEL);
- UDC_CTRL_REG = UDC_CLR_EP;
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
deselect_ep();
}
- while (UDC_TXDMA_CFG_REG & mask)
+ while (omap_readw(UDC_TXDMA_CFG) & mask)
udelay(10);
} else {
- UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
+ omap_writew((omap_readw(UDC_RXDMA_CFG) & ~mask) | UDC_DMA_REQ,
+ UDC_RXDMA_CFG);
/* dma empties the fifo */
- while (UDC_RXDMA_CFG_REG & mask)
+ while (omap_readw(UDC_RXDMA_CFG) & mask)
udelay(10);
if (req)
finish_out_dma(ep, req, -ECONNRESET, 0);
@@ -997,9 +984,13 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
req->req.actual = 0;
/* maybe kickstart non-iso i/o queues */
- if (is_iso)
- UDC_IRQ_EN_REG |= UDC_SOF_IE;
- else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) {
+ if (is_iso) {
+ u16 w;
+
+ w = omap_readw(UDC_IRQ_EN);
+ w |= UDC_SOF_IE;
+ omap_writew(w, UDC_IRQ_EN);
+ } else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) {
int is_in;
if (ep->bEndpointAddress == 0) {
@@ -1017,23 +1008,23 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
* requests to non-control endpoints
*/
if (udc->ep0_set_config) {
- u16 irq_en = UDC_IRQ_EN_REG;
+ u16 irq_en = omap_readw(UDC_IRQ_EN);
irq_en |= UDC_DS_CHG_IE | UDC_EP0_IE;
if (!udc->ep0_reset_config)
irq_en |= UDC_EPN_RX_IE
| UDC_EPN_TX_IE;
- UDC_IRQ_EN_REG = irq_en;
+ omap_writew(irq_en, UDC_IRQ_EN);
}
/* STATUS for zero length DATA stages is
* always an IN ... even for IN transfers,
* a weird case which seem to stall OMAP.
*/
- UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR);
- UDC_CTRL_REG = UDC_CLR_EP;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM);
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
/* cleanup */
udc->ep0_pending = 0;
@@ -1042,11 +1033,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
/* non-empty DATA stage */
} else if (is_in) {
- UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
+ omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM);
} else {
if (udc->ep0_setup)
goto irq_wait;
- UDC_EP_NUM_REG = UDC_EP_SEL;
+ omap_writew(UDC_EP_SEL, UDC_EP_NUM);
}
} else {
is_in = ep->bEndpointAddress & USB_DIR_IN;
@@ -1062,7 +1053,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
req = NULL;
deselect_ep();
if (!is_in) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
/* IN: 6 wait states before it'll tx */
@@ -1130,9 +1121,9 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
else if (value) {
if (ep->udc->ep0_set_config) {
WARN("error changing config?\n");
- UDC_SYSCON2_REG = UDC_CLR_CFG;
+ omap_writew(UDC_CLR_CFG, UDC_SYSCON2);
}
- UDC_SYSCON2_REG = UDC_STALL_CMD;
+ omap_writew(UDC_STALL_CMD, UDC_SYSCON2);
ep->udc->ep0_pending = 0;
status = 0;
} else /* NOP */
@@ -1159,8 +1150,8 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
channel = 0;
use_ep(ep, UDC_EP_SEL);
- if (UDC_STAT_FLG_REG & UDC_NON_ISO_FIFO_EMPTY) {
- UDC_CTRL_REG = UDC_SET_HALT;
+ if (omap_readw(UDC_STAT_FLG) & UDC_NON_ISO_FIFO_EMPTY) {
+ omap_writew(UDC_SET_HALT, UDC_CTRL);
status = 0;
} else
status = -EAGAIN;
@@ -1170,10 +1161,10 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value)
dma_channel_claim(ep, channel);
} else {
use_ep(ep, 0);
- UDC_CTRL_REG = ep->udc->clr_halt;
+ omap_writew(ep->udc->clr_halt, UDC_CTRL);
ep->ackwait = 0;
if (!(ep->bEndpointAddress & USB_DIR_IN)) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
}
@@ -1205,7 +1196,7 @@ static struct usb_ep_ops omap_ep_ops = {
static int omap_get_frame(struct usb_gadget *gadget)
{
- u16 sof = UDC_SOF_REG;
+ u16 sof = omap_readw(UDC_SOF);
return (sof & UDC_TS_OK) ? (sof & UDC_TS) : -EL2NSYNC;
}
@@ -1224,7 +1215,7 @@ static int omap_wakeup(struct usb_gadget *gadget)
*/
if (udc->devstat & (UDC_B_HNP_ENABLE|UDC_R_WK_OK)) {
DBG("remote wakeup...\n");
- UDC_SYSCON2_REG = UDC_RMT_WKP;
+ omap_writew(UDC_RMT_WKP, UDC_SYSCON2);
retval = 0;
}
@@ -1247,12 +1238,12 @@ omap_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
udc = container_of(gadget, struct omap_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
- syscon1 = UDC_SYSCON1_REG;
+ syscon1 = omap_readw(UDC_SYSCON1);
if (is_selfpowered)
syscon1 |= UDC_SELF_PWR;
else
syscon1 &= ~UDC_SELF_PWR;
- UDC_SYSCON1_REG = syscon1;
+ omap_writew(syscon1, UDC_SYSCON1);
spin_unlock_irqrestore(&udc->lock, flags);
return 0;
@@ -1265,18 +1256,36 @@ static int can_pullup(struct omap_udc *udc)
static void pullup_enable(struct omap_udc *udc)
{
- UDC_SYSCON1_REG |= UDC_PULLUP_EN;
- if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
- OTG_CTRL_REG |= OTG_BSESSVLD;
- UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
+ u16 w;
+
+ w = omap_readw(UDC_SYSCON1);
+ w |= UDC_PULLUP_EN;
+ omap_writew(w, UDC_SYSCON1);
+ if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) {
+ u32 l;
+
+ l = omap_readl(OTG_CTRL);
+ l |= OTG_BSESSVLD;
+ omap_writel(l, OTG_CTRL);
+ }
+ omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN);
}
static void pullup_disable(struct omap_udc *udc)
{
- if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
- OTG_CTRL_REG &= ~OTG_BSESSVLD;
- UDC_IRQ_EN_REG = UDC_DS_CHG_IE;
- UDC_SYSCON1_REG &= ~UDC_PULLUP_EN;
+ u16 w;
+
+ if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) {
+ u32 l;
+
+ l = omap_readl(OTG_CTRL);
+ l &= ~OTG_BSESSVLD;
+ omap_writel(l, OTG_CTRL);
+ }
+ omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN);
+ w = omap_readw(UDC_SYSCON1);
+ w &= ~UDC_PULLUP_EN;
+ omap_writew(w, UDC_SYSCON1);
}
static struct omap_udc *udc;
@@ -1304,6 +1313,7 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active)
{
struct omap_udc *udc;
unsigned long flags;
+ u32 l;
udc = container_of(gadget, struct omap_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
@@ -1311,10 +1321,12 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active)
udc->vbus_active = (is_active != 0);
if (cpu_is_omap15xx()) {
/* "software" detect, ignored if !VBUS_MODE_1510 */
+ l = omap_readl(FUNC_MUX_CTRL_0);
if (is_active)
- FUNC_MUX_CTRL_0_REG |= VBUS_CTRL_1510;
+ l |= VBUS_CTRL_1510;
else
- FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510;
+ l &= ~VBUS_CTRL_1510;
+ omap_writel(l, FUNC_MUX_CTRL_0);
}
if (udc->dc_clk != NULL && is_active) {
if (!udc->clk_requested) {
@@ -1384,9 +1396,9 @@ static void nuke(struct omap_ep *ep, int status)
dma_channel_release(ep);
use_ep(ep, 0);
- UDC_CTRL_REG = UDC_CLR_EP;
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
if (ep->bEndpointAddress && ep->bmAttributes != USB_ENDPOINT_XFER_ISOC)
- UDC_CTRL_REG = UDC_SET_HALT;
+ omap_writew(UDC_SET_HALT, UDC_CTRL);
while (!list_empty(&ep->queue)) {
req = list_entry(ep->queue.next, struct omap_req, queue);
@@ -1414,8 +1426,8 @@ static void update_otg(struct omap_udc *udc)
if (!gadget_is_otg(&udc->gadget))
return;
- if (OTG_CTRL_REG & OTG_ID)
- devstat = UDC_DEVSTAT_REG;
+ if (omap_readl(OTG_CTRL) & OTG_ID)
+ devstat = omap_readw(UDC_DEVSTAT);
else
devstat = 0;
@@ -1426,9 +1438,14 @@ static void update_otg(struct omap_udc *udc)
/* Enable HNP early, avoiding races on suspend irq path.
* ASSUMES OTG state machine B_BUS_REQ input is true.
*/
- if (udc->gadget.b_hnp_enable)
- OTG_CTRL_REG = (OTG_CTRL_REG | OTG_B_HNPEN | OTG_B_BUSREQ)
- & ~OTG_PULLUP;
+ if (udc->gadget.b_hnp_enable) {
+ u32 l;
+
+ l = omap_readl(OTG_CTRL);
+ l |= OTG_B_HNPEN | OTG_B_BUSREQ;
+ l &= ~OTG_PULLUP;
+ omap_writel(l, OTG_CTRL);
+ }
}
static void ep0_irq(struct omap_udc *udc, u16 irq_src)
@@ -1446,7 +1463,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
nuke(ep0, 0);
if (ack) {
- UDC_IRQ_SRC_REG = ack;
+ omap_writew(ack, UDC_IRQ_SRC);
irq_src = UDC_SETUP;
}
}
@@ -1466,9 +1483,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
if (irq_src & UDC_EP0_TX) {
int stat;
- UDC_IRQ_SRC_REG = UDC_EP0_TX;
- UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
- stat = UDC_STAT_FLG_REG;
+ omap_writew(UDC_EP0_TX, UDC_IRQ_SRC);
+ omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM);
+ stat = omap_readw(UDC_STAT_FLG);
if (stat & UDC_ACK) {
if (udc->ep0_in) {
/* write next IN packet from response,
@@ -1476,26 +1493,26 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
*/
if (req)
stat = write_fifo(ep0, req);
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
if (!req && udc->ep0_pending) {
- UDC_EP_NUM_REG = UDC_EP_SEL;
- UDC_CTRL_REG = UDC_CLR_EP;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = 0;
+ omap_writew(UDC_EP_SEL, UDC_EP_NUM);
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(0, UDC_EP_NUM);
udc->ep0_pending = 0;
} /* else: 6 wait states before it'll tx */
} else {
/* ack status stage of OUT transfer */
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
if (req)
done(ep0, req, 0);
}
req = NULL;
} else if (stat & UDC_STALL) {
- UDC_CTRL_REG = UDC_CLR_HALT;
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_CLR_HALT, UDC_CTRL);
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
} else {
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
}
}
@@ -1503,9 +1520,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
if (irq_src & UDC_EP0_RX) {
int stat;
- UDC_IRQ_SRC_REG = UDC_EP0_RX;
- UDC_EP_NUM_REG = UDC_EP_SEL;
- stat = UDC_STAT_FLG_REG;
+ omap_writew(UDC_EP0_RX, UDC_IRQ_SRC);
+ omap_writew(UDC_EP_SEL, UDC_EP_NUM);
+ stat = omap_readw(UDC_STAT_FLG);
if (stat & UDC_ACK) {
if (!udc->ep0_in) {
stat = 0;
@@ -1513,34 +1530,35 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
* reactiviting the fifo; stall on errors.
*/
if (!req || (stat = read_fifo(ep0, req)) < 0) {
- UDC_SYSCON2_REG = UDC_STALL_CMD;
+ omap_writew(UDC_STALL_CMD, UDC_SYSCON2);
udc->ep0_pending = 0;
stat = 0;
} else if (stat == 0)
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = 0;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(0, UDC_EP_NUM);
/* activate status stage */
if (stat == 1) {
done(ep0, req, 0);
/* that may have STALLed ep0... */
- UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
- UDC_CTRL_REG = UDC_CLR_EP;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_SEL | UDC_EP_DIR,
+ UDC_EP_NUM);
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
udc->ep0_pending = 0;
}
} else {
/* ack status stage of IN transfer */
- UDC_EP_NUM_REG = 0;
+ omap_writew(0, UDC_EP_NUM);
if (req)
done(ep0, req, 0);
}
} else if (stat & UDC_STALL) {
- UDC_CTRL_REG = UDC_CLR_HALT;
- UDC_EP_NUM_REG = 0;
+ omap_writew(UDC_CLR_HALT, UDC_CTRL);
+ omap_writew(0, UDC_EP_NUM);
} else {
- UDC_EP_NUM_REG = 0;
+ omap_writew(0, UDC_EP_NUM);
}
}
@@ -1555,14 +1573,14 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
/* read the (latest) SETUP message */
do {
- UDC_EP_NUM_REG = UDC_SETUP_SEL;
+ omap_writew(UDC_SETUP_SEL, UDC_EP_NUM);
/* two bytes at a time */
- u.word[0] = UDC_DATA_REG;
- u.word[1] = UDC_DATA_REG;
- u.word[2] = UDC_DATA_REG;
- u.word[3] = UDC_DATA_REG;
- UDC_EP_NUM_REG = 0;
- } while (UDC_IRQ_SRC_REG & UDC_SETUP);
+ u.word[0] = omap_readw(UDC_DATA);
+ u.word[1] = omap_readw(UDC_DATA);
+ u.word[2] = omap_readw(UDC_DATA);
+ u.word[3] = omap_readw(UDC_DATA);
+ omap_writew(0, UDC_EP_NUM);
+ } while (omap_readw(UDC_IRQ_SRC) & UDC_SETUP);
#define w_value le16_to_cpu(u.r.wValue)
#define w_index le16_to_cpu(u.r.wIndex)
@@ -1593,9 +1611,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
* later if it fails the request.
*/
if (udc->ep0_reset_config)
- UDC_SYSCON2_REG = UDC_CLR_CFG;
+ omap_writew(UDC_CLR_CFG, UDC_SYSCON2);
else
- UDC_SYSCON2_REG = UDC_DEV_CFG;
+ omap_writew(UDC_DEV_CFG, UDC_SYSCON2);
update_otg(udc);
goto delegate;
case USB_REQ_CLEAR_FEATURE:
@@ -1613,10 +1631,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
|| !ep->desc)
goto do_stall;
use_ep(ep, 0);
- UDC_CTRL_REG = udc->clr_halt;
+ omap_writew(udc->clr_halt, UDC_CTRL);
ep->ackwait = 0;
if (!(ep->bEndpointAddress & USB_DIR_IN)) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
/* NOTE: assumes the host behaves sanely,
@@ -1649,15 +1667,15 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
}
use_ep(ep, 0);
/* can't halt if fifo isn't empty... */
- UDC_CTRL_REG = UDC_CLR_EP;
- UDC_CTRL_REG = UDC_SET_HALT;
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
+ omap_writew(UDC_SET_HALT, UDC_CTRL);
VDBG("%s halted by host\n", ep->name);
ep0out_status_stage:
status = 0;
- UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
- UDC_CTRL_REG = UDC_CLR_EP;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM);
+ omap_writew(UDC_CLR_EP, UDC_CTRL);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
udc->ep0_pending = 0;
break;
case USB_REQ_GET_STATUS:
@@ -1694,10 +1712,10 @@ intf_status:
zero_status:
/* return two zero bytes */
- UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
- UDC_DATA_REG = 0;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
- UDC_EP_NUM_REG = UDC_EP_DIR;
+ omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM);
+ omap_writew(0, UDC_DATA);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
+ omap_writew(UDC_EP_DIR, UDC_EP_NUM);
status = 0;
VDBG("GET_STATUS, interface %d\n", w_index);
/* next, status stage */
@@ -1706,8 +1724,8 @@ zero_status:
delegate:
/* activate the ep0out fifo right away */
if (!udc->ep0_in && w_length) {
- UDC_EP_NUM_REG = 0;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(0, UDC_EP_NUM);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
}
/* gadget drivers see class/vendor specific requests,
@@ -1748,9 +1766,9 @@ do_stall:
if (udc->ep0_reset_config)
WARN("error resetting config?\n");
else
- UDC_SYSCON2_REG = UDC_CLR_CFG;
+ omap_writew(UDC_CLR_CFG, UDC_SYSCON2);
}
- UDC_SYSCON2_REG = UDC_STALL_CMD;
+ omap_writew(UDC_STALL_CMD, UDC_SYSCON2);
udc->ep0_pending = 0;
}
}
@@ -1764,7 +1782,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
{
u16 devstat, change;
- devstat = UDC_DEVSTAT_REG;
+ devstat = omap_readw(UDC_DEVSTAT);
change = devstat ^ udc->devstat;
udc->devstat = devstat;
@@ -1804,7 +1822,8 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
INFO("USB reset done, gadget %s\n",
udc->driver->driver.name);
/* ep0 traffic is legal from now on */
- UDC_IRQ_EN_REG = UDC_DS_CHG_IE | UDC_EP0_IE;
+ omap_writew(UDC_DS_CHG_IE | UDC_EP0_IE,
+ UDC_IRQ_EN);
}
change &= ~UDC_USB_RESET;
}
@@ -1848,7 +1867,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
VDBG("devstat %03x, ignore change %03x\n",
devstat, change);
- UDC_IRQ_SRC_REG = UDC_DS_CHG;
+ omap_writew(UDC_DS_CHG, UDC_IRQ_SRC);
}
static irqreturn_t omap_udc_irq(int irq, void *_udc)
@@ -1859,7 +1878,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc)
unsigned long flags;
spin_lock_irqsave(&udc->lock, flags);
- irq_src = UDC_IRQ_SRC_REG;
+ irq_src = omap_readw(UDC_IRQ_SRC);
/* Device state change (usb ch9 stuff) */
if (irq_src & UDC_DS_CHG) {
@@ -1882,7 +1901,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc)
irq_src &= ~(UDC_TXN_DONE|UDC_RXN_CNT|UDC_RXN_EOT);
}
- irq_src &= ~(UDC_SOF|UDC_EPN_TX|UDC_EPN_RX);
+ irq_src &= ~(UDC_IRQ_SOF | UDC_EPN_TX|UDC_EPN_RX);
if (irq_src)
DBG("udc_irq, unhandled %03x\n", irq_src);
spin_unlock_irqrestore(&udc->lock, flags);
@@ -1903,7 +1922,7 @@ static void pio_out_timer(unsigned long _ep)
spin_lock_irqsave(&ep->udc->lock, flags);
if (!list_empty(&ep->queue) && ep->ackwait) {
use_ep(ep, UDC_EP_SEL);
- stat_flg = UDC_STAT_FLG_REG;
+ stat_flg = omap_readw(UDC_STAT_FLG);
if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN)
|| (ep->double_buf && HALF_FULL(stat_flg)))) {
@@ -1913,8 +1932,8 @@ static void pio_out_timer(unsigned long _ep)
req = container_of(ep->queue.next,
struct omap_req, queue);
(void) read_fifo(ep, req);
- UDC_EP_NUM_REG = ep->bEndpointAddress;
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(ep->bEndpointAddress, UDC_EP_NUM);
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
} else
deselect_ep();
@@ -1934,20 +1953,20 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev)
unsigned long flags;
spin_lock_irqsave(&udc->lock, flags);
- epn_stat = UDC_EPN_STAT_REG;
- irq_src = UDC_IRQ_SRC_REG;
+ epn_stat = omap_readw(UDC_EPN_STAT);
+ irq_src = omap_readw(UDC_IRQ_SRC);
/* handle OUT first, to avoid some wasteful NAKs */
if (irq_src & UDC_EPN_RX) {
epnum = (epn_stat >> 8) & 0x0f;
- UDC_IRQ_SRC_REG = UDC_EPN_RX;
+ omap_writew(UDC_EPN_RX, UDC_IRQ_SRC);
status = IRQ_HANDLED;
ep = &udc->ep[epnum];
ep->irqs++;
- UDC_EP_NUM_REG = epnum | UDC_EP_SEL;
+ omap_writew(epnum | UDC_EP_SEL, UDC_EP_NUM);
ep->fnf = 0;
- if ((UDC_STAT_FLG_REG & UDC_ACK)) {
+ if (omap_readw(UDC_STAT_FLG) & UDC_ACK) {
ep->ackwait--;
if (!list_empty(&ep->queue)) {
int stat;
@@ -1959,15 +1978,15 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev)
}
}
/* min 6 clock delay before clearing EP_SEL ... */
- epn_stat = UDC_EPN_STAT_REG;
- epn_stat = UDC_EPN_STAT_REG;
- UDC_EP_NUM_REG = epnum;
+ epn_stat = omap_readw(UDC_EPN_STAT);
+ epn_stat = omap_readw(UDC_EPN_STAT);
+ omap_writew(epnum, UDC_EP_NUM);
/* enabling fifo _after_ clearing ACK, contrary to docs,
* reduces lossage; timer still needed though (sigh).
*/
if (ep->fnf) {
- UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ omap_writew(UDC_SET_FIFO_EN, UDC_CTRL);
ep->ackwait = 1 + ep->double_buf;
}
mod_timer(&ep->timer, PIO_OUT_TIMEOUT);
@@ -1976,13 +1995,13 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev)
/* then IN transfers */
else if (irq_src & UDC_EPN_TX) {
epnum = epn_stat & 0x0f;
- UDC_IRQ_SRC_REG = UDC_EPN_TX;
+ omap_writew(UDC_EPN_TX, UDC_IRQ_SRC);
status = IRQ_HANDLED;
ep = &udc->ep[16 + epnum];
ep->irqs++;
- UDC_EP_NUM_REG = epnum | UDC_EP_DIR | UDC_EP_SEL;
- if ((UDC_STAT_FLG_REG & UDC_ACK)) {
+ omap_writew(epnum | UDC_EP_DIR | UDC_EP_SEL, UDC_EP_NUM);
+ if (omap_readw(UDC_STAT_FLG) & UDC_ACK) {
ep->ackwait = 0;
if (!list_empty(&ep->queue)) {
req = container_of(ep->queue.next,
@@ -1991,9 +2010,9 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev)
}
}
/* min 6 clock delay before clearing EP_SEL ... */
- epn_stat = UDC_EPN_STAT_REG;
- epn_stat = UDC_EPN_STAT_REG;
- UDC_EP_NUM_REG = epnum | UDC_EP_DIR;
+ epn_stat = omap_readw(UDC_EPN_STAT);
+ epn_stat = omap_readw(UDC_EPN_STAT);
+ omap_writew(epnum | UDC_EP_DIR, UDC_EP_NUM);
/* then 6 clocks before it'd tx */
}
@@ -2021,7 +2040,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev)
req = list_entry(ep->queue.next, struct omap_req, queue);
use_ep(ep, UDC_EP_SEL);
- stat = UDC_STAT_FLG_REG;
+ stat = omap_readw(UDC_STAT_FLG);
/* NOTE: like the other controller drivers, this isn't
* currently reporting lost or damaged frames.
@@ -2053,9 +2072,14 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev)
if (!list_empty(&ep->queue))
pending = 1;
}
- if (!pending)
- UDC_IRQ_EN_REG &= ~UDC_SOF_IE;
- UDC_IRQ_SRC_REG = UDC_SOF;
+ if (!pending) {
+ u16 w;
+
+ w = omap_readw(UDC_IRQ_EN);
+ w &= ~UDC_SOF_IE;
+ omap_writew(w, UDC_IRQ_EN);
+ }
+ omap_writew(UDC_IRQ_SOF, UDC_IRQ_SRC);
spin_unlock_irqrestore(&udc->lock, flags);
return IRQ_HANDLED;
@@ -2104,7 +2128,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
continue;
use_ep(ep, 0);
- UDC_CTRL_REG = UDC_SET_HALT;
+ omap_writew(UDC_SET_HALT, UDC_CTRL);
}
udc->ep0_pending = 0;
udc->ep[0].irqs = 0;
@@ -2128,7 +2152,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
}
DBG("bound to driver %s\n", driver->driver.name);
- UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK;
+ omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC);
/* connect to bus through transceiver */
if (udc->transceiver) {
@@ -2225,7 +2249,7 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep)
else
buf[0] = 0;
- stat_flg = UDC_STAT_FLG_REG;
+ stat_flg = omap_readw(UDC_STAT_FLG);
seq_printf(s,
"\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n",
ep->name, buf,
@@ -2292,11 +2316,11 @@ static int proc_otg_show(struct seq_file *s)
trans = CONTROL_DEVCONF_REG;
} else {
ctrl_name = "tranceiver_ctrl";
- trans = USB_TRANSCEIVER_CTRL_REG;
+ trans = omap_readw(USB_TRANSCEIVER_CTRL);
}
seq_printf(s, "\nOTG rev %d.%d, %s %05x\n",
tmp >> 4, tmp & 0xf, ctrl_name, trans);
- tmp = OTG_SYSCON_1_REG;
+ tmp = omap_readw(OTG_SYSCON_1);
seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s,"
FOURBITS "\n", tmp,
trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R),
@@ -2308,7 +2332,7 @@ static int proc_otg_show(struct seq_file *s)
(tmp & HST_IDLE_EN) ? " !host" : "",
(tmp & DEV_IDLE_EN) ? " !dev" : "",
(tmp & OTG_RESET_DONE) ? " reset_done" : " reset_active");
- tmp = OTG_SYSCON_2_REG;
+ tmp = omap_readl(OTG_SYSCON_2);
seq_printf(s, "otg_syscon2 %08x%s" EIGHTBITS
" b_ase_brst=%d hmc=%d\n", tmp,
(tmp & OTG_EN) ? " otg_en" : "",
@@ -2323,7 +2347,7 @@ static int proc_otg_show(struct seq_file *s)
(tmp & HMC_TLLATTACH) ? " tllattach" : "",
B_ASE_BRST(tmp),
OTG_HMC(tmp));
- tmp = OTG_CTRL_REG;
+ tmp = omap_readl(OTG_CTRL);
seq_printf(s, "otg_ctrl %06x" EIGHTBITS EIGHTBITS "%s\n", tmp,
(tmp & OTG_ASESSVLD) ? " asess" : "",
(tmp & OTG_BSESSEND) ? " bsess_end" : "",
@@ -2343,13 +2367,13 @@ static int proc_otg_show(struct seq_file *s)
(tmp & OTG_PU_VBUS) ? " pu_vb" : "",
(tmp & OTG_PU_ID) ? " pu_id" : ""
);
- tmp = OTG_IRQ_EN_REG;
+ tmp = omap_readw(OTG_IRQ_EN);
seq_printf(s, "otg_irq_en %04x" "\n", tmp);
- tmp = OTG_IRQ_SRC_REG;
+ tmp = omap_readw(OTG_IRQ_SRC);
seq_printf(s, "otg_irq_src %04x" "\n", tmp);
- tmp = OTG_OUTCTRL_REG;
+ tmp = omap_readw(OTG_OUTCTRL);
seq_printf(s, "otg_outctrl %04x" "\n", tmp);
- tmp = OTG_TEST_REG;
+ tmp = omap_readw(OTG_TEST);
seq_printf(s, "otg_test %04x" "\n", tmp);
return 0;
}
@@ -2370,7 +2394,7 @@ static int proc_udc_show(struct seq_file *s, void *_)
driver_desc,
use_dma ? " (dma)" : "");
- tmp = UDC_REV_REG & 0xff;
+ tmp = omap_readw(UDC_REV) & 0xff;
seq_printf(s,
"UDC rev %d.%d, fifo mode %d, gadget %s\n"
"hmc %d, transceiver %s\n",
@@ -2384,16 +2408,16 @@ static int proc_udc_show(struct seq_file *s, void *_)
? "external" : "(none)"));
if (cpu_class_is_omap1()) {
seq_printf(s, "ULPD control %04x req %04x status %04x\n",
- __REG16(ULPD_CLOCK_CTRL),
- __REG16(ULPD_SOFT_REQ),
- __REG16(ULPD_STATUS_REQ));
+ omap_readw(ULPD_CLOCK_CTRL),
+ omap_readw(ULPD_SOFT_REQ),
+ omap_readw(ULPD_STATUS_REQ));
}
/* OTG controller registers */
if (!cpu_is_omap15xx())
proc_otg_show(s);
- tmp = UDC_SYSCON1_REG;
+ tmp = omap_readw(UDC_SYSCON1);
seq_printf(s, "\nsyscon1 %04x" EIGHTBITS "\n", tmp,
(tmp & UDC_CFG_LOCK) ? " cfg_lock" : "",
(tmp & UDC_DATA_ENDIAN) ? " data_endian" : "",
@@ -2412,7 +2436,7 @@ static int proc_udc_show(struct seq_file *s, void *_)
return 0;
}
- tmp = UDC_DEVSTAT_REG;
+ tmp = omap_readw(UDC_DEVSTAT);
seq_printf(s, "devstat %04x" EIGHTBITS "%s%s\n", tmp,
(tmp & UDC_B_HNP_ENABLE) ? " b_hnp" : "",
(tmp & UDC_A_HNP_SUPPORT) ? " a_hnp" : "",
@@ -2424,20 +2448,20 @@ static int proc_udc_show(struct seq_file *s, void *_)
(tmp & UDC_ADD) ? " ADD" : "",
(tmp & UDC_DEF) ? " DEF" : "",
(tmp & UDC_ATT) ? " ATT" : "");
- seq_printf(s, "sof %04x\n", UDC_SOF_REG);
- tmp = UDC_IRQ_EN_REG;
+ seq_printf(s, "sof %04x\n", omap_readw(UDC_SOF));
+ tmp = omap_readw(UDC_IRQ_EN);
seq_printf(s, "irq_en %04x" FOURBITS "%s\n", tmp,
(tmp & UDC_SOF_IE) ? " sof" : "",
(tmp & UDC_EPN_RX_IE) ? " epn_rx" : "",
(tmp & UDC_EPN_TX_IE) ? " epn_tx" : "",
(tmp & UDC_DS_CHG_IE) ? " ds_chg" : "",
(tmp & UDC_EP0_IE) ? " ep0" : "");
- tmp = UDC_IRQ_SRC_REG;
+ tmp = omap_readw(UDC_IRQ_SRC);
seq_printf(s, "irq_src %04x" EIGHTBITS "%s%s\n", tmp,
(tmp & UDC_TXN_DONE) ? " txn_done" : "",
(tmp & UDC_RXN_CNT) ? " rxn_cnt" : "",
(tmp & UDC_RXN_EOT) ? " rxn_eot" : "",
- (tmp & UDC_SOF) ? " sof" : "",
+ (tmp & UDC_IRQ_SOF) ? " sof" : "",
(tmp & UDC_EPN_RX) ? " epn_rx" : "",
(tmp & UDC_EPN_TX) ? " epn_tx" : "",
(tmp & UDC_DS_CHG) ? " ds_chg" : "",
@@ -2447,7 +2471,7 @@ static int proc_udc_show(struct seq_file *s, void *_)
if (use_dma) {
unsigned i;
- tmp = UDC_DMA_IRQ_EN_REG;
+ tmp = omap_readw(UDC_DMA_IRQ_EN);
seq_printf(s, "dma_irq_en %04x%s" EIGHTBITS "\n", tmp,
(tmp & UDC_TX_DONE_IE(3)) ? " tx2_done" : "",
(tmp & UDC_RX_CNT_IE(3)) ? " rx2_cnt" : "",
@@ -2461,29 +2485,29 @@ static int proc_udc_show(struct seq_file *s, void *_)
(tmp & UDC_RX_CNT_IE(1)) ? " rx0_cnt" : "",
(tmp & UDC_RX_EOT_IE(1)) ? " rx0_eot" : "");
- tmp = UDC_RXDMA_CFG_REG;
+ tmp = omap_readw(UDC_RXDMA_CFG);
seq_printf(s, "rxdma_cfg %04x\n", tmp);
if (tmp) {
for (i = 0; i < 3; i++) {
if ((tmp & (0x0f << (i * 4))) == 0)
continue;
seq_printf(s, "rxdma[%d] %04x\n", i,
- UDC_RXDMA_REG(i + 1));
+ omap_readw(UDC_RXDMA(i + 1)));
}
}
- tmp = UDC_TXDMA_CFG_REG;
+ tmp = omap_readw(UDC_TXDMA_CFG);
seq_printf(s, "txdma_cfg %04x\n", tmp);
if (tmp) {
for (i = 0; i < 3; i++) {
if (!(tmp & (0x0f << (i * 4))))
continue;
seq_printf(s, "txdma[%d] %04x\n", i,
- UDC_TXDMA_REG(i + 1));
+ omap_readw(UDC_TXDMA(i + 1)));
}
}
}
- tmp = UDC_DEVSTAT_REG;
+ tmp = omap_readw(UDC_DEVSTAT);
if (tmp & UDC_ATT) {
proc_ep_show(s, &udc->ep[0]);
if (tmp & UDC_ADD) {
@@ -2535,7 +2559,7 @@ static inline void remove_proc_file(void) {}
* buffer space among the endpoints we'll be operating.
*
* NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when
- * UDC_SYSCON_1_REG.CFG_LOCK is set can now work. We won't use that
+ * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that
* capability yet though.
*/
static unsigned __init
@@ -2597,9 +2621,9 @@ omap_ep_setup(char *name, u8 addr, u8 type,
name, addr, epn_rxtx, maxp, dbuf ? "x2" : "", buf);
if (addr & USB_DIR_IN)
- UDC_EP_TX_REG(addr & 0xf) = epn_rxtx;
+ omap_writew(epn_rxtx, UDC_EP_TX(addr & 0xf));
else
- UDC_EP_RX_REG(addr) = epn_rxtx;
+ omap_writew(epn_rxtx, UDC_EP_RX(addr));
/* next endpoint's buffer starts after this one's */
buf += maxp;
@@ -2638,15 +2662,15 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
unsigned tmp, buf;
/* abolish any previous hardware state */
- UDC_SYSCON1_REG = 0;
- UDC_IRQ_EN_REG = 0;
- UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK;
- UDC_DMA_IRQ_EN_REG = 0;
- UDC_RXDMA_CFG_REG = 0;
- UDC_TXDMA_CFG_REG = 0;
+ omap_writew(0, UDC_SYSCON1);
+ omap_writew(0, UDC_IRQ_EN);
+ omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC);
+ omap_writew(0, UDC_DMA_IRQ_EN);
+ omap_writew(0, UDC_RXDMA_CFG);
+ omap_writew(0, UDC_TXDMA_CFG);
/* UDC_PULLUP_EN gates the chip clock */
- // OTG_SYSCON_1_REG |= DEV_IDLE_EN;
+ // OTG_SYSCON_1 |= DEV_IDLE_EN;
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
if (!udc)
@@ -2677,8 +2701,8 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
/* initially disable all non-ep0 endpoints */
for (tmp = 1; tmp < 15; tmp++) {
- UDC_EP_RX_REG(tmp) = 0;
- UDC_EP_TX_REG(tmp) = 0;
+ omap_writew(0, UDC_EP_RX(tmp));
+ omap_writew(0, UDC_EP_TX(tmp));
}
#define OMAP_BULK_EP(name,addr) \
@@ -2763,7 +2787,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
ERR("unsupported fifo_mode #%d\n", fifo_mode);
return -ENODEV;
}
- UDC_SYSCON1_REG = UDC_CFG_LOCK|UDC_SELF_PWR;
+ omap_writew(UDC_CFG_LOCK|UDC_SELF_PWR, UDC_SYSCON1);
INFO("fifo mode %d, %d bytes not used\n", fifo_mode, 2048 - buf);
return 0;
}
@@ -2807,7 +2831,7 @@ static int __init omap_udc_probe(struct platform_device *pdev)
}
INFO("OMAP UDC rev %d.%d%s\n",
- UDC_REV_REG >> 4, UDC_REV_REG & 0xf,
+ omap_readw(UDC_REV) >> 4, omap_readw(UDC_REV) & 0xf,
config->otg ? ", Mini-AB" : "");
/* use the mode given to us by board init code */
@@ -2822,12 +2846,12 @@ static int __init omap_udc_probe(struct platform_device *pdev)
* know when to turn PULLUP_EN on/off; and that
* means we always "need" the 48MHz clock.
*/
- u32 tmp = FUNC_MUX_CTRL_0_REG;
-
- FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510;
+ u32 tmp = omap_readl(FUNC_MUX_CTRL_0);
+ tmp &= ~VBUS_CTRL_1510;
+ omap_writel(tmp, FUNC_MUX_CTRL_0);
tmp |= VBUS_MODE_1510;
tmp &= ~VBUS_CTRL_1510;
- FUNC_MUX_CTRL_0_REG = tmp;
+ omap_writel(tmp, FUNC_MUX_CTRL_0);
}
} else {
/* The transceiver may package some GPIO logic or handle
@@ -2907,7 +2931,7 @@ known:
#endif
/* starting with omap1710 es2.0, clear toggle is a separate bit */
- if (UDC_REV_REG >= 0x61)
+ if (omap_readw(UDC_REV) >= 0x61)
udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE;
else
udc->clr_halt = UDC_RESET_EP;
@@ -3005,7 +3029,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev)
put_device(udc->transceiver->dev);
udc->transceiver = NULL;
}
- UDC_SYSCON1_REG = 0;
+ omap_writew(0, UDC_SYSCON1);
remove_proc_file();
@@ -3036,7 +3060,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev)
*
* REVISIT we should probably reject suspend requests when there's a host
* session active, rather than disconnecting, at least on boards that can
- * report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT). And in any case, we need to
+ * report VBUS irqs (UDC_DEVSTAT.UDC_ATT). And in any case, we need to
* make host resumes and VBUS detection trigger OMAP wakeup events; that
* may involve talking to an external transceiver (e.g. isp1301).
*/
@@ -3045,7 +3069,7 @@ static int omap_udc_suspend(struct platform_device *dev, pm_message_t message)
{
u32 devstat;
- devstat = UDC_DEVSTAT_REG;
+ devstat = omap_readw(UDC_DEVSTAT);
/* we're requesting 48 MHz clock if the pullup is enabled
* (== we're attached to the host) and we're not suspended,
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h
index c6b9cbc7230..8522bbb1227 100644
--- a/drivers/usb/gadget/omap_udc.h
+++ b/drivers/usb/gadget/omap_udc.h
@@ -8,23 +8,22 @@
/*
* USB device/endpoint management registers
*/
-#define UDC_REG(offset) __REG16(UDC_BASE + (offset))
-#define UDC_REV_REG UDC_REG(0x0) /* Revision */
-#define UDC_EP_NUM_REG UDC_REG(0x4) /* Which endpoint */
+#define UDC_REV (UDC_BASE + 0x0) /* Revision */
+#define UDC_EP_NUM (UDC_BASE + 0x4) /* Which endpoint */
# define UDC_SETUP_SEL (1 << 6)
# define UDC_EP_SEL (1 << 5)
# define UDC_EP_DIR (1 << 4)
/* low 4 bits for endpoint number */
-#define UDC_DATA_REG UDC_REG(0x08) /* Endpoint FIFO */
-#define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */
+#define UDC_DATA (UDC_BASE + 0x08) /* Endpoint FIFO */
+#define UDC_CTRL (UDC_BASE + 0x0C) /* Endpoint control */
# define UDC_CLR_HALT (1 << 7)
# define UDC_SET_HALT (1 << 6)
# define UDC_CLRDATA_TOGGLE (1 << 3)
# define UDC_SET_FIFO_EN (1 << 2)
# define UDC_CLR_EP (1 << 1)
# define UDC_RESET_EP (1 << 0)
-#define UDC_STAT_FLG_REG UDC_REG(0x10) /* Endpoint status */
+#define UDC_STAT_FLG (UDC_BASE + 0x10) /* Endpoint status */
# define UDC_NO_RXPACKET (1 << 15)
# define UDC_MISS_IN (1 << 14)
# define UDC_DATA_FLUSH (1 << 13)
@@ -38,8 +37,8 @@
# define UDC_FIFO_EN (1 << 2)
# define UDC_NON_ISO_FIFO_EMPTY (1 << 1)
# define UDC_NON_ISO_FIFO_FULL (1 << 0)
-#define UDC_RXFSTAT_REG UDC_REG(0x14) /* OUT bytecount */
-#define UDC_SYSCON1_REG UDC_REG(0x18) /* System config 1 */
+#define UDC_RXFSTAT (UDC_BASE + 0x14) /* OUT bytecount */
+#define UDC_SYSCON1 (UDC_BASE + 0x18) /* System config 1 */
# define UDC_CFG_LOCK (1 << 8)
# define UDC_DATA_ENDIAN (1 << 7)
# define UDC_DMA_ENDIAN (1 << 6)
@@ -48,12 +47,12 @@
# define UDC_SELF_PWR (1 << 2)
# define UDC_SOFF_DIS (1 << 1)
# define UDC_PULLUP_EN (1 << 0)
-#define UDC_SYSCON2_REG UDC_REG(0x1C) /* System config 2 */
+#define UDC_SYSCON2 (UDC_BASE + 0x1C) /* System config 2 */
# define UDC_RMT_WKP (1 << 6)
# define UDC_STALL_CMD (1 << 5)
# define UDC_DEV_CFG (1 << 3)
# define UDC_CLR_CFG (1 << 2)
-#define UDC_DEVSTAT_REG UDC_REG(0x20) /* Device status */
+#define UDC_DEVSTAT (UDC_BASE + 0x20) /* Device status */
# define UDC_B_HNP_ENABLE (1 << 9)
# define UDC_A_HNP_SUPPORT (1 << 8)
# define UDC_A_ALT_HNP_SUPPORT (1 << 7)
@@ -64,26 +63,26 @@
# define UDC_ADD (1 << 2)
# define UDC_DEF (1 << 1)
# define UDC_ATT (1 << 0)
-#define UDC_SOF_REG UDC_REG(0x24) /* Start of frame */
+#define UDC_SOF (UDC_BASE + 0x24) /* Start of frame */
# define UDC_FT_LOCK (1 << 12)
# define UDC_TS_OK (1 << 11)
# define UDC_TS 0x03ff
-#define UDC_IRQ_EN_REG UDC_REG(0x28) /* Interrupt enable */
+#define UDC_IRQ_EN (UDC_BASE + 0x28) /* Interrupt enable */
# define UDC_SOF_IE (1 << 7)
# define UDC_EPN_RX_IE (1 << 5)
# define UDC_EPN_TX_IE (1 << 4)
# define UDC_DS_CHG_IE (1 << 3)
# define UDC_EP0_IE (1 << 0)
-#define UDC_DMA_IRQ_EN_REG UDC_REG(0x2C) /* DMA irq enable */
+#define UDC_DMA_IRQ_EN (UDC_BASE + 0x2C) /* DMA irq enable */
/* rx/tx dma channels numbered 1-3 not 0-2 */
# define UDC_TX_DONE_IE(n) (1 << (4 * (n) - 2))
# define UDC_RX_CNT_IE(n) (1 << (4 * (n) - 3))
# define UDC_RX_EOT_IE(n) (1 << (4 * (n) - 4))
-#define UDC_IRQ_SRC_REG UDC_REG(0x30) /* Interrupt source */
+#define UDC_IRQ_SRC (UDC_BASE + 0x30) /* Interrupt source */
# define UDC_TXN_DONE (1 << 10)
# define UDC_RXN_CNT (1 << 9)
# define UDC_RXN_EOT (1 << 8)
-# define UDC_SOF (1 << 7)
+# define UDC_IRQ_SOF (1 << 7)
# define UDC_EPN_RX (1 << 5)
# define UDC_EPN_TX (1 << 4)
# define UDC_DS_CHG (1 << 3)
@@ -91,41 +90,41 @@
# define UDC_EP0_RX (1 << 1)
# define UDC_EP0_TX (1 << 0)
# define UDC_IRQ_SRC_MASK 0x7bf
-#define UDC_EPN_STAT_REG UDC_REG(0x34) /* EP irq status */
-#define UDC_DMAN_STAT_REG UDC_REG(0x38) /* DMA irq status */
+#define UDC_EPN_STAT (UDC_BASE + 0x34) /* EP irq status */
+#define UDC_DMAN_STAT (UDC_BASE + 0x38) /* DMA irq status */
# define UDC_DMA_RX_SB (1 << 12)
# define UDC_DMA_RX_SRC(x) (((x)>>8) & 0xf)
# define UDC_DMA_TX_SRC(x) (((x)>>0) & 0xf)
/* DMA configuration registers: up to three channels in each direction. */
-#define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */
+#define UDC_RXDMA_CFG (UDC_BASE + 0x40) /* 3 eps for RX DMA */
# define UDC_DMA_REQ (1 << 12)
-#define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */
-#define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */
+#define UDC_TXDMA_CFG (UDC_BASE + 0x44) /* 3 eps for TX DMA */
+#define UDC_DATA_DMA (UDC_BASE + 0x48) /* rx/tx fifo addr */
/* rx/tx dma control, numbering channels 1-3 not 0-2 */
-#define UDC_TXDMA_REG(chan) UDC_REG(0x50 - 4 + 4 * (chan))
+#define UDC_TXDMA(chan) (UDC_BASE + 0x50 - 4 + 4 * (chan))
# define UDC_TXN_EOT (1 << 15) /* bytes vs packets */
# define UDC_TXN_START (1 << 14) /* start transfer */
# define UDC_TXN_TSC 0x03ff /* units in xfer */
-#define UDC_RXDMA_REG(chan) UDC_REG(0x60 - 4 + 4 * (chan))
+#define UDC_RXDMA(chan) (UDC_BASE + 0x60 - 4 + 4 * (chan))
# define UDC_RXN_STOP (1 << 15) /* enable EOT irq */
# define UDC_RXN_TC 0x00ff /* packets in xfer */
/*
* Endpoint configuration registers (used before CFG_LOCK is set)
- * UDC_EP_TX_REG(0) is unused
+ * UDC_EP_TX(0) is unused
*/
-#define UDC_EP_RX_REG(endpoint) UDC_REG(0x80 + (endpoint)*4)
+#define UDC_EP_RX(endpoint) (UDC_BASE + 0x80 + (endpoint)*4)
# define UDC_EPN_RX_VALID (1 << 15)
# define UDC_EPN_RX_DB (1 << 14)
/* buffer size in bits 13, 12 */
# define UDC_EPN_RX_ISO (1 << 11)
/* buffer pointer in low 11 bits */
-#define UDC_EP_TX_REG(endpoint) UDC_REG(0xc0 + (endpoint)*4)
- /* same bitfields as in RX_REG */
+#define UDC_EP_TX(endpoint) (UDC_BASE + 0xc0 + (endpoint)*4)
+ /* same bitfields as in RX */
/*-------------------------------------------------------------------------*/
@@ -195,14 +194,14 @@ struct omap_udc {
/*-------------------------------------------------------------------------*/
-#define MOD_CONF_CTRL_0_REG __REG32(MOD_CONF_CTRL_0)
-#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */
+/* MOD_CONF_CTRL_0 */
+#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */
-#define FUNC_MUX_CTRL_0_REG __REG32(FUNC_MUX_CTRL_0)
+/* FUNC_MUX_CTRL_0 */
#define VBUS_CTRL_1510 (1 << 19) /* 1 connected (software) */
#define VBUS_MODE_1510 (1 << 18) /* 0 hardware, 1 software */
-#define HMC_1510 ((MOD_CONF_CTRL_0_REG >> 1) & 0x3f)
-#define HMC_1610 (OTG_SYSCON_2_REG & 0x3f)
+#define HMC_1510 ((omap_readl(MOD_CONF_CTRL_0) >> 1) & 0x3f)
+#define HMC_1610 (omap_readl(OTG_SYSCON_2) & 0x3f)
#define HMC (cpu_is_omap15xx() ? HMC_1510 : HMC_1610)
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 6859fb5f1d6..2b7c04079d5 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -169,13 +169,16 @@ static void start_hnp(struct ohci_hcd *ohci)
{
const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1;
unsigned long flags;
+ u32 l;
otg_start_hnp(ohci->transceiver);
local_irq_save(flags);
ohci->transceiver->state = OTG_STATE_A_SUSPEND;
writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
- OTG_CTRL_REG &= ~OTG_A_BUSREQ;
+ l = omap_readl(OTG_CTRL);
+ l &= ~OTG_A_BUSREQ;
+ omap_writel(l, OTG_CTRL);
local_irq_restore(flags);
}
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 7dcda187d9b..fafe7db20d6 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1246,7 +1246,7 @@ static int pxafb_resume(struct platform_device *dev)
* cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region.
*/
-static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
+static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi)
{
/*
* We reserve one page for the palette, plus the size
@@ -1348,7 +1348,7 @@ decode_mode:
pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
}
-static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
+static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
{
struct pxafb_info *fbi;
void *addr;
@@ -1410,7 +1410,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
}
#ifdef CONFIG_FB_PXA_PARAMETERS
-static int __init parse_opt_mode(struct device *dev, const char *this_opt)
+static int __devinit parse_opt_mode(struct device *dev, const char *this_opt)
{
struct pxafb_mach_info *inf = dev->platform_data;
@@ -1469,7 +1469,7 @@ done:
return 0;
}
-static int __init parse_opt(struct device *dev, char *this_opt)
+static int __devinit parse_opt(struct device *dev, char *this_opt)
{
struct pxafb_mach_info *inf = dev->platform_data;
struct pxafb_mode_info *mode = &inf->modes[0];
@@ -1567,7 +1567,7 @@ static int __init parse_opt(struct device *dev, char *this_opt)
return 0;
}
-static int __init pxafb_parse_options(struct device *dev, char *options)
+static int __devinit pxafb_parse_options(struct device *dev, char *options)
{
char *this_opt;
int ret;
@@ -1588,8 +1588,8 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
static char g_options[256] __devinitdata = "";
-#ifndef CONFIG_MODULES
-static int __devinit pxafb_setup_options(void)
+#ifndef MODULE
+static int __init pxafb_setup_options(void)
{
char *options = NULL;
@@ -1613,7 +1613,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
#define pxafb_setup_options() (0)
#endif
-static int __init pxafb_probe(struct platform_device *dev)
+static int __devinit pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
struct pxafb_mach_info *inf;
@@ -1685,14 +1685,14 @@ static int __init pxafb_probe(struct platform_device *dev)
if (r == NULL) {
dev_err(&dev->dev, "no I/O memory resource defined\n");
ret = -ENODEV;
- goto failed;
+ goto failed_fbi;
}
r = request_mem_region(r->start, r->end - r->start + 1, dev->name);
if (r == NULL) {
dev_err(&dev->dev, "failed to request I/O memory\n");
ret = -EBUSY;
- goto failed;
+ goto failed_fbi;
}
fbi->mmio_base = ioremap(r->start, r->end - r->start + 1);
@@ -1735,8 +1735,17 @@ static int __init pxafb_probe(struct platform_device *dev)
* This makes sure that our colour bitfield
* descriptors are correctly initialised.
*/
- pxafb_check_var(&fbi->fb.var, &fbi->fb);
- pxafb_set_par(&fbi->fb);
+ ret = pxafb_check_var(&fbi->fb.var, &fbi->fb);
+ if (ret) {
+ dev_err(&dev->dev, "failed to get suitable mode\n");
+ goto failed_free_irq;
+ }
+
+ ret = pxafb_set_par(&fbi->fb);
+ if (ret) {
+ dev_err(&dev->dev, "Failed to set parameters\n");
+ goto failed_free_irq;
+ }
platform_set_drvdata(dev, fbi);
@@ -1744,7 +1753,7 @@ static int __init pxafb_probe(struct platform_device *dev)
if (ret < 0) {
dev_err(&dev->dev,
"Failed to register framebuffer device: %d\n", ret);
- goto failed_free_irq;
+ goto failed_free_cmap;
}
#ifdef CONFIG_CPU_FREQ
@@ -1763,18 +1772,23 @@ static int __init pxafb_probe(struct platform_device *dev)
return 0;
+failed_free_cmap:
+ if (fbi->fb.cmap.len)
+ fb_dealloc_cmap(&fbi->fb.cmap);
failed_free_irq:
free_irq(irq, fbi);
-failed_free_res:
- release_mem_region(r->start, r->end - r->start + 1);
-failed_free_io:
- iounmap(fbi->mmio_base);
failed_free_mem:
dma_free_writecombine(&dev->dev, fbi->map_size,
fbi->map_cpu, fbi->map_dma);
-failed:
+failed_free_io:
+ iounmap(fbi->mmio_base);
+failed_free_res:
+ release_mem_region(r->start, r->end - r->start + 1);
+failed_fbi:
+ clk_put(fbi->clk);
platform_set_drvdata(dev, NULL);
kfree(fbi);
+failed:
return ret;
}
@@ -1787,7 +1801,7 @@ static struct platform_driver pxafb_driver = {
},
};
-static int __devinit pxafb_init(void)
+static int __init pxafb_init(void)
{
if (pxafb_setup_options())
return -EINVAL;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 470c10ceb0f..10d8a0aa871 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -931,8 +931,16 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
struct gendisk *disk;
int ret;
int part;
+ int perm = 0;
- ret = devcgroup_inode_permission(bdev->bd_inode, file->f_mode);
+ if (file->f_mode & FMODE_READ)
+ perm |= MAY_READ;
+ if (file->f_mode & FMODE_WRITE)
+ perm |= MAY_WRITE;
+ /*
+ * hooks: /n/, see "layering violations".
+ */
+ ret = devcgroup_inode_permission(bdev->bd_inode, perm);
if (ret != 0)
return ret;
diff --git a/fs/buffer.c b/fs/buffer.c
index a073f3f4f01..0f51c0f7c26 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -821,7 +821,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
* contents - it is a noop if I/O is still in
* flight on potentially older contents.
*/
- ll_rw_block(SWRITE, 1, &bh);
+ ll_rw_block(SWRITE_SYNC, 1, &bh);
brelse(bh);
spin_lock(lock);
}
@@ -2940,16 +2940,19 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
for (i = 0; i < nr; i++) {
struct buffer_head *bh = bhs[i];
- if (rw == SWRITE)
+ if (rw == SWRITE || rw == SWRITE_SYNC)
lock_buffer(bh);
else if (test_set_buffer_locked(bh))
continue;
- if (rw == WRITE || rw == SWRITE) {
+ if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) {
if (test_clear_buffer_dirty(bh)) {
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
- submit_bh(WRITE, bh);
+ if (rw == SWRITE_SYNC)
+ submit_bh(WRITE_SYNC, bh);
+ else
+ submit_bh(WRITE, bh);
continue;
}
} else {
@@ -2978,7 +2981,7 @@ int sync_dirty_buffer(struct buffer_head *bh)
if (test_clear_buffer_dirty(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_write_sync;
- ret = submit_bh(WRITE, bh);
+ ret = submit_bh(WRITE_SYNC, bh);
wait_on_buffer(bh);
if (buffer_eopnotsupp(bh)) {
clear_buffer_eopnotsupp(bh);
diff --git a/fs/dcache.c b/fs/dcache.c
index 3ee588d5f58..6068c25b393 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -17,6 +17,7 @@
#include <linux/syscalls.h>
#include <linux/string.h>
#include <linux/mm.h>
+#include <linux/fdtable.h>
#include <linux/fs.h>
#include <linux/fsnotify.h>
#include <linux/slab.h>
@@ -106,9 +107,10 @@ static void dentry_lru_remove(struct dentry *dentry)
/*
* Release the dentry's inode, using the filesystem
* d_iput() operation if defined.
- * Called with dcache_lock and per dentry lock held, drops both.
*/
static void dentry_iput(struct dentry * dentry)
+ __releases(dentry->d_lock)
+ __releases(dcache_lock)
{
struct inode *inode = dentry->d_inode;
if (inode) {
@@ -132,12 +134,13 @@ static void dentry_iput(struct dentry * dentry)
* d_kill - kill dentry and return parent
* @dentry: dentry to kill
*
- * Called with dcache_lock and d_lock, releases both. The dentry must
- * already be unhashed and removed from the LRU.
+ * The dentry must already be unhashed and removed from the LRU.
*
* If this is the root of the dentry tree, return NULL.
*/
static struct dentry *d_kill(struct dentry *dentry)
+ __releases(dentry->d_lock)
+ __releases(dcache_lock)
{
struct dentry *parent;
@@ -383,11 +386,11 @@ restart:
* Try to prune ancestors as well. This is necessary to prevent
* quadratic behavior of shrink_dcache_parent(), but is also expected
* to be beneficial in reducing dentry cache fragmentation.
- *
- * Called with dcache_lock, drops it and then regains.
- * Called with dentry->d_lock held, drops it.
*/
static void prune_one_dentry(struct dentry * dentry)
+ __releases(dentry->d_lock)
+ __releases(dcache_lock)
+ __acquires(dcache_lock)
{
__d_drop(dentry);
dentry = d_kill(dentry);
@@ -1604,10 +1607,9 @@ static int d_isparent(struct dentry *p1, struct dentry *p2)
*
* Note: If ever the locking in lock_rename() changes, then please
* remember to update this too...
- *
- * On return, dcache_lock will have been unlocked.
*/
static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+ __releases(dcache_lock)
{
struct mutex *m1 = NULL, *m2 = NULL;
struct dentry *ret;
@@ -1743,11 +1745,9 @@ out_nolock:
shouldnt_be_hashed:
spin_unlock(&dcache_lock);
BUG();
- goto shouldnt_be_hashed;
}
-static int prepend(char **buffer, int *buflen, const char *str,
- int namelen)
+static int prepend(char **buffer, int *buflen, const char *str, int namelen)
{
*buflen -= namelen;
if (*buflen < 0)
@@ -1757,8 +1757,13 @@ static int prepend(char **buffer, int *buflen, const char *str,
return 0;
}
+static int prepend_name(char **buffer, int *buflen, struct qstr *name)
+{
+ return prepend(buffer, buflen, name->name, name->len);
+}
+
/**
- * d_path - return the path of a dentry
+ * __d_path - return the path of a dentry
* @path: the dentry/vfsmount to report
* @root: root vfsmnt/dentry (may be modified by this function)
* @buffer: buffer to return value in
@@ -1779,9 +1784,10 @@ char *__d_path(const struct path *path, struct path *root,
{
struct dentry *dentry = path->dentry;
struct vfsmount *vfsmnt = path->mnt;
- char * end = buffer+buflen;
- char * retval;
+ char *end = buffer + buflen;
+ char *retval;
+ spin_lock(&vfsmount_lock);
prepend(&end, &buflen, "\0", 1);
if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
(prepend(&end, &buflen, " (deleted)", 10) != 0))
@@ -1800,38 +1806,37 @@ char *__d_path(const struct path *path, struct path *root,
break;
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
/* Global root? */
- spin_lock(&vfsmount_lock);
if (vfsmnt->mnt_parent == vfsmnt) {
- spin_unlock(&vfsmount_lock);
goto global_root;
}
dentry = vfsmnt->mnt_mountpoint;
vfsmnt = vfsmnt->mnt_parent;
- spin_unlock(&vfsmount_lock);
continue;
}
parent = dentry->d_parent;
prefetch(parent);
- if ((prepend(&end, &buflen, dentry->d_name.name,
- dentry->d_name.len) != 0) ||
+ if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
(prepend(&end, &buflen, "/", 1) != 0))
goto Elong;
retval = end;
dentry = parent;
}
+out:
+ spin_unlock(&vfsmount_lock);
return retval;
global_root:
retval += 1; /* hit the slash */
- if (prepend(&retval, &buflen, dentry->d_name.name,
- dentry->d_name.len) != 0)
+ if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
goto Elong;
root->mnt = vfsmnt;
root->dentry = dentry;
- return retval;
+ goto out;
+
Elong:
- return ERR_PTR(-ENAMETOOLONG);
+ retval = ERR_PTR(-ENAMETOOLONG);
+ goto out;
}
/**
@@ -1845,9 +1850,9 @@ Elong:
*
* Returns the buffer or an error code if the path was too long.
*
- * "buflen" should be positive. Caller holds the dcache_lock.
+ * "buflen" should be positive.
*/
-char *d_path(struct path *path, char *buf, int buflen)
+char *d_path(const struct path *path, char *buf, int buflen)
{
char *res;
struct path root;
@@ -1915,16 +1920,11 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
retval = end-1;
*retval = '/';
- for (;;) {
- struct dentry *parent;
- if (IS_ROOT(dentry))
- break;
+ while (!IS_ROOT(dentry)) {
+ struct dentry *parent = dentry->d_parent;
- parent = dentry->d_parent;
prefetch(parent);
-
- if ((prepend(&end, &buflen, dentry->d_name.name,
- dentry->d_name.len) != 0) ||
+ if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
(prepend(&end, &buflen, "/", 1) != 0))
goto Elong;
@@ -1975,7 +1975,7 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
error = -ENOENT;
/* Has the current directory has been unlinked? */
spin_lock(&dcache_lock);
- if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
+ if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
unsigned long len;
struct path tmp = root;
char * cwd;
diff --git a/fs/locks.c b/fs/locks.c
index 11dbf08651b..dce8c747371 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -561,9 +561,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
/* insert into file's list */
fl->fl_next = *pos;
*pos = fl;
-
- if (fl->fl_ops && fl->fl_ops->fl_insert)
- fl->fl_ops->fl_insert(fl);
}
/*
@@ -586,9 +583,6 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
fl->fl_fasync = NULL;
}
- if (fl->fl_ops && fl->fl_ops->fl_remove)
- fl->fl_ops->fl_remove(fl);
-
if (fl->fl_nspid) {
put_pid(fl->fl_nspid);
fl->fl_nspid = NULL;
diff --git a/fs/namei.c b/fs/namei.c
index c7e43536c49..01e67dddcc3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -581,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
int result;
/* make sure the stuff we saved doesn't go away */
- dget(save.dentry);
- mntget(save.mnt);
+ path_get(&save);
result = __link_path_walk(name, nd);
if (result == -ESTALE) {
/* nd->path had been dropped */
nd->path = save;
- dget(nd->path.dentry);
- mntget(nd->path.mnt);
+ path_get(&nd->path);
nd->flags |= LOOKUP_REVAL;
result = __link_path_walk(name, nd);
}
@@ -1216,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
nd->flags = flags;
nd->depth = 0;
- nd->path.mnt = mntget(mnt);
- nd->path.dentry = dget(dentry);
+ nd->path.dentry = dentry;
+ nd->path.mnt = mnt;
+ path_get(&nd->path);
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
@@ -2857,16 +2856,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
struct nameidata nd;
void *cookie;
+ int res;
nd.depth = 0;
cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
- if (!IS_ERR(cookie)) {
- int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
- if (dentry->d_inode->i_op->put_link)
- dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
- cookie = ERR_PTR(res);
- }
- return PTR_ERR(cookie);
+ if (IS_ERR(cookie))
+ return PTR_ERR(cookie);
+
+ res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+ if (dentry->d_inode->i_op->put_link)
+ dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+ return res;
}
int vfs_follow_link(struct nameidata *nd, const char *link)
diff --git a/fs/pipe.c b/fs/pipe.c
index ec228bc9f88..700f4e0d957 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1003,8 +1003,7 @@ struct file *create_write_pipe(void)
void free_write_pipe(struct file *f)
{
free_pipe_info(f->f_dentry->d_inode);
- dput(f->f_path.dentry);
- mntput(f->f_path.mnt);
+ path_put(&f->f_path);
put_filp(f);
}
@@ -1015,8 +1014,8 @@ struct file *create_read_pipe(struct file *wrf)
return ERR_PTR(-ENFILE);
/* Grab pipe from the writer */
- f->f_path.mnt = mntget(wrf->f_path.mnt);
- f->f_path.dentry = dget(wrf->f_path.dentry);
+ f->f_path = wrf->f_path;
+ path_get(&wrf->f_path);
f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
f->f_pos = 0;
@@ -1068,8 +1067,7 @@ int do_pipe(int *fd)
err_fdr:
put_unused_fd(fdr);
err_read_pipe:
- dput(fr->f_dentry);
- mntput(fr->f_vfsmnt);
+ path_put(&fr->f_path);
put_filp(fr);
err_write_pipe:
free_write_pipe(fw);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 7a5f69be6ac..44cc702f96c 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -682,38 +682,26 @@ static int udf_vrs(struct super_block *sb, int silent)
/*
* Check whether there is an anchor block in the given block
*/
-static int udf_check_anchor_block(struct super_block *sb, sector_t block,
- bool varconv)
+static int udf_check_anchor_block(struct super_block *sb, sector_t block)
{
- struct buffer_head *bh = NULL;
- tag *t;
+ struct buffer_head *bh;
uint16_t ident;
- uint32_t location;
- if (varconv) {
- if (udf_fixed_to_variable(block) >=
- sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
- return 0;
- bh = sb_bread(sb, udf_fixed_to_variable(block));
- }
- else
- bh = sb_bread(sb, block);
+ if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
+ udf_fixed_to_variable(block) >=
+ sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
+ return 0;
+ bh = udf_read_tagged(sb, block, block, &ident);
if (!bh)
return 0;
-
- t = (tag *)bh->b_data;
- ident = le16_to_cpu(t->tagIdent);
- location = le32_to_cpu(t->tagLocation);
brelse(bh);
- if (ident != TAG_IDENT_AVDP)
- return 0;
- return location == block;
+
+ return ident == TAG_IDENT_AVDP;
}
/* Search for an anchor volume descriptor pointer */
-static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
- sector_t lastblock)
+static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock)
{
sector_t last[6];
int i;
@@ -739,7 +727,7 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
sb->s_blocksize_bits)
continue;
- if (udf_check_anchor_block(sb, last[i], varconv)) {
+ if (udf_check_anchor_block(sb, last[i])) {
sbi->s_anchor[0] = last[i];
sbi->s_anchor[1] = last[i] - 256;
return last[i];
@@ -748,17 +736,17 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
if (last[i] < 256)
continue;
- if (udf_check_anchor_block(sb, last[i] - 256, varconv)) {
+ if (udf_check_anchor_block(sb, last[i] - 256)) {
sbi->s_anchor[1] = last[i] - 256;
return last[i];
}
}
- if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) {
+ if (udf_check_anchor_block(sb, sbi->s_session + 256)) {
sbi->s_anchor[0] = sbi->s_session + 256;
return last[0];
}
- if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) {
+ if (udf_check_anchor_block(sb, sbi->s_session + 512)) {
sbi->s_anchor[0] = sbi->s_session + 512;
return last[0];
}
@@ -780,23 +768,24 @@ static void udf_find_anchor(struct super_block *sb)
int i;
struct udf_sb_info *sbi = UDF_SB(sb);
- lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block);
+ lastblock = udf_scan_anchors(sb, sbi->s_last_block);
if (lastblock)
goto check_anchor;
/* No anchor found? Try VARCONV conversion of block numbers */
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
/* Firstly, we try to not convert number of the last block */
- lastblock = udf_scan_anchors(sb, 1,
+ lastblock = udf_scan_anchors(sb,
udf_variable_to_fixed(sbi->s_last_block));
- if (lastblock) {
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ if (lastblock)
goto check_anchor;
- }
/* Secondly, we try with converted number of the last block */
- lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block);
- if (lastblock)
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ lastblock = udf_scan_anchors(sb, sbi->s_last_block);
+ if (!lastblock) {
+ /* VARCONV didn't help. Clear it. */
+ UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
+ }
check_anchor:
/*
diff --git a/fs/utimes.c b/fs/utimes.c
index af059d5cb48..b6b664e7145 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -40,14 +40,9 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
#endif
-static bool nsec_special(long nsec)
-{
- return nsec == UTIME_OMIT || nsec == UTIME_NOW;
-}
-
static bool nsec_valid(long nsec)
{
- if (nsec_special(nsec))
+ if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
return true;
return nsec >= 0 && nsec <= 999999999;
@@ -102,7 +97,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
if (error)
goto dput_and_out;
- /* Don't worry, the checks are done in inode_change_ok() */
+ if (times && times[0].tv_nsec == UTIME_NOW &&
+ times[1].tv_nsec == UTIME_NOW)
+ times = NULL;
+
+ /* In most cases, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
error = -EPERM;
@@ -124,28 +123,34 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
newattrs.ia_valid |= ATTR_MTIME_SET;
}
- }
- /*
- * If times is NULL or both times are either UTIME_OMIT or
- * UTIME_NOW, then need to check permissions, because
- * inode_change_ok() won't do it.
- */
- if (!times || (nsec_special(times[0].tv_nsec) &&
- nsec_special(times[1].tv_nsec))) {
+ /*
+ * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT
+ * cases, we need to make an extra check that is not done by
+ * inode_change_ok().
+ */
+ if (((times[0].tv_nsec == UTIME_NOW &&
+ times[1].tv_nsec == UTIME_OMIT)
+ ||
+ (times[0].tv_nsec == UTIME_OMIT &&
+ times[1].tv_nsec == UTIME_NOW))
+ && !is_owner_or_cap(inode))
+ goto mnt_drop_write_and_out;
+ } else {
+
+ /*
+ * If times is NULL (or both times are UTIME_NOW),
+ * then we need to check permissions, because
+ * inode_change_ok() won't do it.
+ */
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto mnt_drop_write_and_out;
if (!is_owner_or_cap(inode)) {
- if (f) {
- if (!(f->f_mode & FMODE_WRITE))
- goto mnt_drop_write_and_out;
- } else {
- error = vfs_permission(&nd, MAY_WRITE);
- if (error)
- goto mnt_drop_write_and_out;
- }
+ error = permission(inode, MAY_WRITE, NULL);
+ if (error)
+ goto mnt_drop_write_and_out;
}
}
mutex_lock(&inode->i_mutex);
@@ -169,14 +174,6 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __
if (utimes) {
if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
return -EFAULT;
- if ((tstimes[0].tv_nsec == UTIME_OMIT ||
- tstimes[0].tv_nsec == UTIME_NOW) &&
- tstimes[0].tv_sec != 0)
- return -EINVAL;
- if ((tstimes[1].tv_nsec == UTIME_OMIT ||
- tstimes[1].tv_nsec == UTIME_NOW) &&
- tstimes[1].tv_sec != 0)
- return -EINVAL;
/* Nothing to do, we must not even check the path. */
if (tstimes[0].tv_nsec == UTIME_OMIT &&
diff --git a/include/asm-arm/arch-at91/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h
index c2b13c28015..2001e81f226 100644
--- a/include/asm-arm/arch-at91/at91_pmc.h
+++ b/include/asm-arm/arch-at91/at91_pmc.h
@@ -39,10 +39,14 @@
#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */
#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [SAM9RL, CAP9] */
+#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
+#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
+#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
+#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */
#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
-#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [AT91SAM926x only] */
+#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */
#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */
#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */
@@ -97,6 +101,7 @@
#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */
#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
+#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */
#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
diff --git a/include/asm-arm/arch-at91/at91cap9.h b/include/asm-arm/arch-at91/at91cap9.h
index bac83adb505..6f14d9053ac 100644
--- a/include/asm-arm/arch-at91/at91cap9.h
+++ b/include/asm-arm/arch-at91/at91cap9.h
@@ -118,7 +118,7 @@
#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */
#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */
-#define AT91CAP9_UDPHS_BASE 0x00600000 /* USB High Speed Device Port */
+#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */
#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */
#define CONFIG_DRAM_BASE AT91_CHIPSELECT_6
diff --git a/include/asm-arm/arch-at91/at91cap9_matrix.h b/include/asm-arm/arch-at91/at91cap9_matrix.h
index a641686b6c3..ddbd4873c84 100644
--- a/include/asm-arm/arch-at91/at91cap9_matrix.h
+++ b/include/asm-arm/arch-at91/at91cap9_matrix.h
@@ -106,6 +106,11 @@
#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */
#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */
+#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */
+#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */
+#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */
+#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */
+
#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */
#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
diff --git a/include/asm-arm/arch-at91/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h
index c8934fe34dc..889872a3f2a 100644
--- a/include/asm-arm/arch-at91/at91sam9260.h
+++ b/include/asm-arm/arch-at91/at91sam9260.h
@@ -6,6 +6,8 @@
* Common definitions.
* Based on AT91SAM9260 datasheet revision A (Preliminary).
*
+ * Includes also definitions for AT91SAM9XE and AT91SAM9G families
+ *
* 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
@@ -123,5 +125,14 @@
#define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */
#define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */
+#define AT91SAM9G20_ROM_BASE 0x00100000 /* Internal ROM base address */
+#define AT91SAM9G20_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
+
+#define AT91SAM9G20_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */
+#define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */
+#define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */
+#define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */
+
+#define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */
#endif
diff --git a/include/asm-arm/arch-at91/at91sam9rl.h b/include/asm-arm/arch-at91/at91sam9rl.h
index 16d2832f6c0..622e56f81d4 100644
--- a/include/asm-arm/arch-at91/at91sam9rl.h
+++ b/include/asm-arm/arch-at91/at91sam9rl.h
@@ -110,6 +110,6 @@
#define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */
#define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */
-#define AT91SAM9RL_UDPHS_BASE 0x00600000 /* USB Device HS controller */
+#define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */
#endif
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index dc189f01c5b..94de788da76 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -36,6 +36,7 @@
#include <linux/i2c.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
+#include <linux/usb/atmel_usba_udc.h>
/* USB Device */
struct at91_udc_data {
@@ -45,6 +46,9 @@ struct at91_udc_data {
};
extern void __init at91_add_device_udc(struct at91_udc_data *data);
+ /* USB High Speed Device */
+extern void __init at91_add_device_usba(struct usba_platform_data *data);
+
/* Compact Flash */
struct at91_cf_data {
u8 irq_pin; /* I/O IRQ */
@@ -73,7 +77,7 @@ struct at91_eth_data {
};
extern void __init at91_add_device_eth(struct at91_eth_data *data);
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9)
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9)
#define eth_platform_data at91_eth_data
#endif
diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h
index 7145166826a..52df794205c 100644
--- a/include/asm-arm/arch-at91/cpu.h
+++ b/include/asm-arm/arch-at91/cpu.h
@@ -21,6 +21,7 @@
#define ARCH_ID_AT91SAM9260 0x019803a0
#define ARCH_ID_AT91SAM9261 0x019703a0
#define ARCH_ID_AT91SAM9263 0x019607a0
+#define ARCH_ID_AT91SAM9G20 0x019905a0
#define ARCH_ID_AT91SAM9RL64 0x019b03a0
#define ARCH_ID_AT91CAP9 0x039A03A0
@@ -63,6 +64,12 @@ static inline unsigned long at91_arch_identify(void)
#define cpu_is_at91sam9260() (0)
#endif
+#ifdef CONFIG_ARCH_AT91SAM9G20
+#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20)
+#else
+#define cpu_is_at91sam9g20() (0)
+#endif
+
#ifdef CONFIG_ARCH_AT91SAM9261
#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261)
#else
diff --git a/include/asm-arm/arch-at91/hardware.h b/include/asm-arm/arch-at91/hardware.h
index 2c826d8247a..016a3a3f663 100644
--- a/include/asm-arm/arch-at91/hardware.h
+++ b/include/asm-arm/arch-at91/hardware.h
@@ -18,7 +18,7 @@
#if defined(CONFIG_ARCH_AT91RM9200)
#include <asm/arch/at91rm9200.h>
-#elif defined(CONFIG_ARCH_AT91SAM9260)
+#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
#include <asm/arch/at91sam9260.h>
#elif defined(CONFIG_ARCH_AT91SAM9261)
#include <asm/arch/at91sam9261.h>
diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h
index f1933b0fa43..298d8313cda 100644
--- a/include/asm-arm/arch-at91/timex.h
+++ b/include/asm-arm/arch-at91/timex.h
@@ -27,14 +27,29 @@
#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK)
-#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261)
+#elif defined(CONFIG_ARCH_AT91SAM9260)
+
+#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260)
+#define AT91SAM9_MASTER_CLOCK 90000000
+#else
+#define AT91SAM9_MASTER_CLOCK 99300000
+#endif
+
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9261)
#define AT91SAM9_MASTER_CLOCK 99300000
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
#elif defined(CONFIG_ARCH_AT91SAM9263)
+#if defined(CONFIG_MACH_USB_A9263)
+#define AT91SAM9_MASTER_CLOCK 90000000
+#else
#define AT91SAM9_MASTER_CLOCK 99959500
+#endif
+
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
#elif defined(CONFIG_ARCH_AT91SAM9RL)
@@ -42,6 +57,11 @@
#define AT91SAM9_MASTER_CLOCK 100000000
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+#elif defined(CONFIG_ARCH_AT91SAM9G20)
+
+#define AT91SAM9_MASTER_CLOCK 132096000
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
#elif defined(CONFIG_ARCH_AT91CAP9)
#define AT91CAP9_MASTER_CLOCK 100000000
diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h
index daad8ee2d19..74610c2c63d 100644
--- a/include/asm-arm/arch-ebsa285/hardware.h
+++ b/include/asm-arm/arch-ebsa285/hardware.h
@@ -14,7 +14,6 @@
#include <asm/arch/memory.h>
-#ifdef CONFIG_ARCH_FOOTBRIDGE
/* Virtual Physical Size
* 0xff800000 0x40000000 1MB X-Bus
* 0xff000000 0x7c000000 1MB PCI I/O space
@@ -50,31 +49,6 @@
#define PCIMEM_SIZE 0x01000000
#define PCIMEM_BASE 0xf0000000
-#elif defined(CONFIG_ARCH_CO285)
-/*
- * This is the COEBSA285 cut-down mapping
- */
-#define PCIMEM_SIZE 0x80000000
-#define PCIMEM_BASE 0x80000000
-
-#define WFLUSH_SIZE 0x01000000
-#define WFLUSH_BASE 0x7d000000
-
-#define ARMCSR_SIZE 0x00100000
-#define ARMCSR_BASE 0x7cf00000
-
-#define XBUS_SIZE 0x00020000
-#define XBUS_BASE 0x7cee0000
-
-#define PCIO_SIZE 0x00010000
-#define PCIO_BASE 0x7ced0000
-
-#else
-
-#error "Undefined footbridge architecture"
-
-#endif
-
#define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000))
#define XBUS_LED_AMBER (1 << 0)
#define XBUS_LED_GREEN (1 << 1)
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
index cbd7ae64bcc..9019a3bf5ab 100644
--- a/include/asm-arm/arch-ebsa285/memory.h
+++ b/include/asm-arm/arch-ebsa285/memory.h
@@ -42,8 +42,6 @@ extern unsigned long __bus_to_virt(unsigned long);
#endif
-#if defined(CONFIG_ARCH_FOOTBRIDGE)
-
/* Task size and page offset at 3GB */
#define TASK_SIZE UL(0xbf000000)
#define PAGE_OFFSET UL(0xc0000000)
@@ -53,23 +51,6 @@ extern unsigned long __bus_to_virt(unsigned long);
*/
#define FLUSH_BASE 0xf9000000
-#elif defined(CONFIG_ARCH_CO285)
-
-/* Task size and page offset at 1.5GB */
-#define TASK_SIZE UL(0x5f000000)
-#define PAGE_OFFSET UL(0x60000000)
-
-/*
- * Cache flushing area.
- */
-#define FLUSH_BASE 0x7e000000
-
-#else
-
-#error "Undefined footbridge architecture"
-
-#endif
-
/*
* Physical DRAM offset.
*/
diff --git a/include/asm-arm/arch-ebsa285/vmalloc.h b/include/asm-arm/arch-ebsa285/vmalloc.h
index 02598200997..e487d7e8c8a 100644
--- a/include/asm-arm/arch-ebsa285/vmalloc.h
+++ b/include/asm-arm/arch-ebsa285/vmalloc.h
@@ -7,8 +7,4 @@
*/
-#ifdef CONFIG_ARCH_FOOTBRIDGE
#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
-#else
-#define VMALLOC_END (PAGE_OFFSET + 0x20000000)
-#endif
diff --git a/include/asm-arm/arch-imx/imx-dma.h b/include/asm-arm/arch-imx/imx-dma.h
index 5b1066da4e1..44d89c35539 100644
--- a/include/asm-arm/arch-imx/imx-dma.h
+++ b/include/asm-arm/arch-imx/imx-dma.h
@@ -88,7 +88,7 @@ int imx_dma_request(imx_dmach_t dma_ch, const char *name);
void imx_dma_free(imx_dmach_t dma_ch);
-int imx_dma_request_by_prio(imx_dmach_t *pdma_ch, const char *name, imx_dma_prio prio);
+imx_dmach_t imx_dma_request_by_prio(const char *name, imx_dma_prio prio);
#endif /* _ASM_ARCH_IMX_DMA_H */
diff --git a/include/asm-arm/arch-iop13xx/dma.h b/include/asm-arm/arch-iop13xx/dma.h
index 2e15da53ff7..d79846fbb39 100644
--- a/include/asm-arm/arch-iop13xx/dma.h
+++ b/include/asm-arm/arch-iop13xx/dma.h
@@ -1,3 +1,3 @@
#ifndef _IOP13XX_DMA_H
-#define _IOP13XX_DMA_H_
+#define _IOP13XX_DMA_H
#endif
diff --git a/include/asm-arm/arch-iop32x/gpio.h b/include/asm-arm/arch-iop32x/gpio.h
new file mode 100644
index 00000000000..708f4ec9db1
--- /dev/null
+++ b/include/asm-arm/arch-iop32x/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_IOP32X_GPIO_H
+#define __ASM_ARCH_IOP32X_GPIO_H
+
+#include <asm/hardware/iop3xx-gpio.h>
+
+#endif
diff --git a/include/asm-arm/arch-iop33x/gpio.h b/include/asm-arm/arch-iop33x/gpio.h
new file mode 100644
index 00000000000..ddd55bba9bb
--- /dev/null
+++ b/include/asm-arm/arch-iop33x/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_IOP33X_GPIO_H
+#define __ASM_ARCH_IOP33X_GPIO_H
+
+#include <asm/hardware/iop3xx-gpio.h>
+
+#endif
diff --git a/include/asm-arm/arch-ixp4xx/fsg.h b/include/asm-arm/arch-ixp4xx/fsg.h
new file mode 100644
index 00000000000..c0100cc7981
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/fsg.h
@@ -0,0 +1,50 @@
+/*
+ * include/asm-arm/arch-ixp4xx/fsg.h
+ *
+ * Freecom FSG-3 platform specific definitions
+ *
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Author: Tomasz Chmielewski <mangoo@wpkg.org>
+ * Maintainers: http://www.nslu2-linux.org
+ *
+ * Based on coyote.h by
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define FSG_SDA_PIN 12
+#define FSG_SCL_PIN 13
+
+/*
+ * FSG PCI IRQs
+ */
+#define FSG_PCI_MAX_DEV 3
+#define FSG_PCI_IRQ_LINES 3
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define FSG_PCI_INTA_PIN 6
+#define FSG_PCI_INTB_PIN 7
+#define FSG_PCI_INTC_PIN 5
+
+/* Buttons */
+
+#define FSG_SB_GPIO 4 /* sync button */
+#define FSG_RB_GPIO 9 /* reset button */
+#define FSG_UB_GPIO 10 /* usb button */
+
+/* LEDs */
+
+#define FSG_LED_WLAN_BIT 0
+#define FSG_LED_WAN_BIT 1
+#define FSG_LED_SATA_BIT 2
+#define FSG_LED_USB_BIT 4
+#define FSG_LED_RING_BIT 5
+#define FSG_LED_SYNC_BIT 7
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 73e8dc36f6a..fa723a62785 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -45,5 +45,6 @@
#include "nslu2.h"
#include "nas100d.h"
#include "dsmg600.h"
+#include "fsg.h"
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index 11801605047..674af4a8414 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -128,4 +128,11 @@
#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7
#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6
+/*
+ * Freecom FSG-3 Board IRQs
+ */
+#define IRQ_FSG_PCI_INTA IRQ_IXP4XX_GPIO6
+#define IRQ_FSG_PCI_INTB IRQ_IXP4XX_GPIO7
+#define IRQ_FSG_PCI_INTC IRQ_IXP4XX_GPIO5
+
#endif
diff --git a/include/asm-arm/arch-msm/irqs.h b/include/asm-arm/arch-msm/irqs.h
index 565430cfaa7..e62a108b185 100644
--- a/include/asm-arm/arch-msm/irqs.h
+++ b/include/asm-arm/arch-msm/irqs.h
@@ -15,6 +15,7 @@
*/
#ifndef __ASM_ARCH_MSM_IRQS_H
+#define __ASM_ARCH_MSM_IRQS_H
/* MSM ARM11 Interrupt Numbers */
/* See 80-VE113-1 A, pp219-221 */
diff --git a/include/asm-arm/arch-msm/timex.h b/include/asm-arm/arch-msm/timex.h
index 154b23fb359..8724487ab4c 100644
--- a/include/asm-arm/arch-msm/timex.h
+++ b/include/asm-arm/arch-msm/timex.h
@@ -14,6 +14,7 @@
*/
#ifndef __ASM_ARCH_MSM_TIMEX_H
+#define __ASM_ARCH_MSM_TIMEX_H
#define CLOCK_TICK_RATE 1000000
diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h
index 0b7b34603f1..0dca11ce21f 100644
--- a/include/asm-arm/arch-ns9xxx/hardware.h
+++ b/include/asm-arm/arch-ns9xxx/hardware.h
@@ -66,13 +66,13 @@
__REGGET(var, reg ## _ ## field) / __REGSHIFT(reg ## _ ## field)
# define REGGETIM_IDX(var, reg, field, idx) \
- __REGGET(var, reg ## _ ## field((idx))) / \
+ __REGGET(var, reg ## _ ## field((idx))) / \
__REGSHIFT(reg ## _ ## field((idx)))
#else
# define __REG(x) io_p2v(x)
-# define __REG2(x, y) io_p2v((x) + (y))
+# define __REG2(x, y) io_p2v((x) + 4 * (y))
#endif
diff --git a/include/asm-arm/arch-omap/board-2430sdp.h b/include/asm-arm/arch-omap/board-2430sdp.h
index e9c65ce3cb1..c7db9004ec3 100644
--- a/include/asm-arm/arch-omap/board-2430sdp.h
+++ b/include/asm-arm/arch-omap/board-2430sdp.h
@@ -36,9 +36,4 @@
#define TWL4030_IRQNUM INT_24XX_SYS_NIRQ
-/* TWL4030 Primary Interrupt Handler (PIH) interrupts */
-#define IH_TWL4030_BASE IH_BOARD_BASE
-#define IH_TWL4030_END (IH_TWL4030_BASE+8)
-#define NR_IRQS (IH_TWL4030_END)
-
#endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h
index 0f6404435ea..c5d0f32a40a 100644
--- a/include/asm-arm/arch-omap/board-h3.h
+++ b/include/asm-arm/arch-omap/board-h3.h
@@ -30,12 +30,6 @@
/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
#define OMAP1710_ETHR_START 0x04000300
-#define MAXIRQNUM (IH_BOARD_BASE)
-#define MAXFIQNUM MAXIRQNUM
-#define MAXSWINUM MAXIRQNUM
-
-#define NR_IRQS (MAXIRQNUM + 1)
-
extern void h3_mmc_init(void);
extern void h3_mmc_slot_cover_handler(void *arg, int state);
diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h
index 56d2c98e143..9ca03dec9d3 100644
--- a/include/asm-arm/arch-omap/board-innovator.h
+++ b/include/asm-arm/arch-omap/board-innovator.h
@@ -36,9 +36,6 @@
#define OMAP1510P1_EMIFS_PRI_VALUE 0x00
#define OMAP1510P1_EMIFF_PRI_VALUE 0x00
-#define NR_FPGA_IRQS 24
-#define NR_IRQS (IH_BOARD_BASE + NR_FPGA_IRQS)
-
#ifndef __ASSEMBLY__
void fpga_write(unsigned char val, int reg);
unsigned char fpga_read(int reg);
diff --git a/include/asm-arm/arch-omap/board-perseus2.h b/include/asm-arm/arch-omap/board-perseus2.h
index eb74420cb43..d7429cb0f72 100644
--- a/include/asm-arm/arch-omap/board-perseus2.h
+++ b/include/asm-arm/arch-omap/board-perseus2.h
@@ -36,10 +36,4 @@
#define OMAP_SDRAM_DEVICE D256M_1X16_4B
#endif
-#define MAXIRQNUM IH_BOARD_BASE
-#define MAXFIQNUM MAXIRQNUM
-#define MAXSWINUM MAXIRQNUM
-
-#define NR_IRQS (MAXIRQNUM + 1)
-
#endif
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
index 12a5e4de951..4c7b3514f71 100644
--- a/include/asm-arm/arch-omap/clock.h
+++ b/include/asm-arm/arch-omap/clock.h
@@ -33,12 +33,24 @@ struct dpll_data {
void __iomem *mult_div1_reg;
u32 mult_mask;
u32 div1_mask;
+ u16 last_rounded_m;
+ u8 last_rounded_n;
+ unsigned long last_rounded_rate;
+ unsigned int rate_tolerance;
+ u16 max_multiplier;
+ u8 max_divider;
+ u32 max_tolerance;
# if defined(CONFIG_ARCH_OMAP3)
+ u8 modes;
void __iomem *control_reg;
u32 enable_mask;
u8 auto_recal_bit;
u8 recal_en_bit;
u8 recal_st_bit;
+ void __iomem *autoidle_reg;
+ u32 autoidle_mask;
+ void __iomem *idlest_reg;
+ u8 idlest_bit;
# endif
};
@@ -66,11 +78,14 @@ struct clk {
void __iomem *clksel_reg;
u32 clksel_mask;
const struct clksel *clksel;
- const struct dpll_data *dpll_data;
+ struct dpll_data *dpll_data;
#else
__u8 rate_offset;
__u8 src_offset;
#endif
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+#endif
};
struct cpufreq_frequency_table;
diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h
index 36a3b62d4d8..8ac03071f60 100644
--- a/include/asm-arm/arch-omap/common.h
+++ b/include/asm-arm/arch-omap/common.h
@@ -47,8 +47,23 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
}
#endif
+/* IO bases for various OMAP processors */
+struct omap_globals {
+ void __iomem *tap; /* Control module ID code */
+ void __iomem *sdrc; /* SDRAM Controller */
+ void __iomem *sms; /* SDRAM Memory Scheduler */
+ void __iomem *ctrl; /* System Control Module */
+ void __iomem *prm; /* Power and Reset Management */
+ void __iomem *cm; /* Clock Management */
+};
+
void omap2_set_globals_242x(void);
void omap2_set_globals_243x(void);
void omap2_set_globals_343x(void);
+/* These get called from omap2_set_globals_xxxx(), do not call these */
+void omap2_set_globals_memory(struct omap_globals *);
+void omap2_set_globals_control(struct omap_globals *);
+void omap2_set_globals_prcm(struct omap_globals *);
+
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/control.h b/include/asm-arm/arch-omap/control.h
index 59c0686f8be..987553e3eeb 100644
--- a/include/asm-arm/arch-omap/control.h
+++ b/include/asm-arm/arch-omap/control.h
@@ -167,8 +167,7 @@
#ifndef __ASSEMBLY__
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-extern void omap_ctrl_base_set(u32 base);
-extern u32 omap_ctrl_base_get(void);
+extern void __iomem *omap_ctrl_base_get(void);
extern u8 omap_ctrl_readb(u16 offset);
extern u16 omap_ctrl_readw(u16 offset);
extern u32 omap_ctrl_readl(u16 offset);
@@ -176,7 +175,6 @@ extern void omap_ctrl_writeb(u8 val, u16 offset);
extern void omap_ctrl_writew(u16 val, u16 offset);
extern void omap_ctrl_writel(u32 val, u16 offset);
#else
-#define omap_ctrl_base_set(x) WARN_ON(1)
#define omap_ctrl_base_get() 0
#define omap_ctrl_readb(x) 0
#define omap_ctrl_readw(x) 0
diff --git a/include/asm-arm/arch-omap/cpu.h b/include/asm-arm/arch-omap/cpu.h
index e8a4cf52778..52db09f8328 100644
--- a/include/asm-arm/arch-omap/cpu.h
+++ b/include/asm-arm/arch-omap/cpu.h
@@ -3,7 +3,7 @@
*
* OMAP cpu type detection
*
- * Copyright (C) 2004 Nokia Corporation
+ * Copyright (C) 2004, 2008 Nokia Corporation
*
* Written by Tony Lindgren <tony.lindgren@nokia.com>
*
@@ -26,6 +26,12 @@
#ifndef __ASM_ARCH_OMAP_CPU_H
#define __ASM_ARCH_OMAP_CPU_H
+struct omap_chip_id {
+ u8 oc;
+};
+
+#define OMAP_CHIP_INIT(x) { .oc = x }
+
extern unsigned int system_rev;
#define omap2_cpu_rev() ((system_rev >> 12) & 0x0f)
@@ -345,6 +351,33 @@ IS_OMAP_TYPE(3430, 0x3430)
#define OMAP2430_REV_ES1_0 0x24300000
#define OMAP3430_REV_ES1_0 0x34300000
#define OMAP3430_REV_ES2_0 0x34301000
+#define OMAP3430_REV_ES2_1 0x34302000
+#define OMAP3430_REV_ES2_2 0x34303000
+
+/*
+ * omap_chip bits
+ *
+ * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
+ * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates
+ * something that is only valid on that particular ES revision.
+ *
+ * These bits may be ORed together to indicate structures that are
+ * available on multiple chip types.
+ *
+ * To test whether a particular structure matches the current OMAP chip type,
+ * use omap_chip_is().
+ *
+ */
+#define CHIP_IS_OMAP2420 (1 << 0)
+#define CHIP_IS_OMAP2430 (1 << 1)
+#define CHIP_IS_OMAP3430 (1 << 2)
+#define CHIP_IS_OMAP3430ES1 (1 << 3)
+#define CHIP_IS_OMAP3430ES2 (1 << 4)
+
+#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
+
+int omap_chip_is(struct omap_chip_id oci);
+
/*
* Macro to detect device type i.e. EMU/HS/TST/GP/BAD
@@ -362,6 +395,8 @@ IS_OMAP_TYPE(3430, 0x3430)
#define is_device_type_gp() (get_device_type() == DEVICE_TYPE_GP)
#define is_device_type_bad() (get_device_type() == DEVICE_TYPE_BAD)
-#endif
+void omap2_check_revision(void);
+
+#endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */
#endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index 24acf090030..f4dcb958786 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -22,108 +22,128 @@
#define __ASM_ARCH_DMA_H
/* Hardware registers for omap1 */
-#define OMAP_DMA_BASE (0xfffed800)
-#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
-#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
-#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
-#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
-#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
-#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
-#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
-#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
-#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
-#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
-#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
-#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
-#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
-#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
-#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
-#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
-#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
-#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
-#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
-#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
-
-/* Hardware registers for omap2 */
-#if defined(CONFIG_ARCH_OMAP3)
-#define OMAP_DMA4_BASE (L4_34XX_BASE + 0x56000)
-#else /* CONFIG_ARCH_OMAP2 */
-#define OMAP_DMA4_BASE (L4_24XX_BASE + 0x56000)
-#endif
-
-#define OMAP_DMA4_REVISION (OMAP_DMA4_BASE + 0x00)
-#define OMAP_DMA4_GCR_REG (OMAP_DMA4_BASE + 0x78)
-#define OMAP_DMA4_IRQSTATUS_L0 (OMAP_DMA4_BASE + 0x08)
-#define OMAP_DMA4_IRQSTATUS_L1 (OMAP_DMA4_BASE + 0x0c)
-#define OMAP_DMA4_IRQSTATUS_L2 (OMAP_DMA4_BASE + 0x10)
-#define OMAP_DMA4_IRQSTATUS_L3 (OMAP_DMA4_BASE + 0x14)
-#define OMAP_DMA4_IRQENABLE_L0 (OMAP_DMA4_BASE + 0x18)
-#define OMAP_DMA4_IRQENABLE_L1 (OMAP_DMA4_BASE + 0x1c)
-#define OMAP_DMA4_IRQENABLE_L2 (OMAP_DMA4_BASE + 0x20)
-#define OMAP_DMA4_IRQENABLE_L3 (OMAP_DMA4_BASE + 0x24)
-#define OMAP_DMA4_SYSSTATUS (OMAP_DMA4_BASE + 0x28)
-#define OMAP_DMA4_OCP_SYSCONFIG (OMAP_DMA4_BASE + 0x2c)
-#define OMAP_DMA4_CAPS_0 (OMAP_DMA4_BASE + 0x64)
-#define OMAP_DMA4_CAPS_2 (OMAP_DMA4_BASE + 0x6c)
-#define OMAP_DMA4_CAPS_3 (OMAP_DMA4_BASE + 0x70)
-#define OMAP_DMA4_CAPS_4 (OMAP_DMA4_BASE + 0x74)
-
-#ifdef CONFIG_ARCH_OMAP1
-
-#define OMAP_LOGICAL_DMA_CH_COUNT 17
+#define OMAP1_DMA_BASE (0xfffed800)
+
+#define OMAP1_DMA_GCR 0x400
+#define OMAP1_DMA_GSCR 0x404
+#define OMAP1_DMA_GRST 0x408
+#define OMAP1_DMA_HW_ID 0x442
+#define OMAP1_DMA_PCH2_ID 0x444
+#define OMAP1_DMA_PCH0_ID 0x446
+#define OMAP1_DMA_PCH1_ID 0x448
+#define OMAP1_DMA_PCHG_ID 0x44a
+#define OMAP1_DMA_PCHD_ID 0x44c
+#define OMAP1_DMA_CAPS_0_U 0x44e
+#define OMAP1_DMA_CAPS_0_L 0x450
+#define OMAP1_DMA_CAPS_1_U 0x452
+#define OMAP1_DMA_CAPS_1_L 0x454
+#define OMAP1_DMA_CAPS_2 0x456
+#define OMAP1_DMA_CAPS_3 0x458
+#define OMAP1_DMA_CAPS_4 0x45a
+#define OMAP1_DMA_PCH2_SR 0x460
+#define OMAP1_DMA_PCH0_SR 0x480
+#define OMAP1_DMA_PCH1_SR 0x482
+#define OMAP1_DMA_PCHD_SR 0x4c0
+
+/* Hardware registers for omap2 and omap3 */
+#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
+#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
+
+#define OMAP_DMA4_REVISION 0x00
+#define OMAP_DMA4_GCR 0x78
+#define OMAP_DMA4_IRQSTATUS_L0 0x08
+#define OMAP_DMA4_IRQSTATUS_L1 0x0c
+#define OMAP_DMA4_IRQSTATUS_L2 0x10
+#define OMAP_DMA4_IRQSTATUS_L3 0x14
+#define OMAP_DMA4_IRQENABLE_L0 0x18
+#define OMAP_DMA4_IRQENABLE_L1 0x1c
+#define OMAP_DMA4_IRQENABLE_L2 0x20
+#define OMAP_DMA4_IRQENABLE_L3 0x24
+#define OMAP_DMA4_SYSSTATUS 0x28
+#define OMAP_DMA4_OCP_SYSCONFIG 0x2c
+#define OMAP_DMA4_CAPS_0 0x64
+#define OMAP_DMA4_CAPS_2 0x6c
+#define OMAP_DMA4_CAPS_3 0x70
+#define OMAP_DMA4_CAPS_4 0x74
+
+#define OMAP1_LOGICAL_DMA_CH_COUNT 17
+#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
/* Common channel specific registers for omap1 */
-#define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00)
-#define OMAP_DMA_CCR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x02)
-#define OMAP_DMA_CICR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x04)
-#define OMAP_DMA_CSR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x06)
-#define OMAP_DMA_CEN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x10)
-#define OMAP_DMA_CFN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x12)
-#define OMAP_DMA_CSFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x14)
-#define OMAP_DMA_CSEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x16)
-#define OMAP_DMA_CSAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x18)
-#define OMAP_DMA_CDAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
-#define OMAP_DMA_CDEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
-#define OMAP_DMA_CDFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
-#define OMAP_DMA_CLNK_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x28)
-
-#else
-
-#define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
+#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00)
+#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00)
+#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02)
+#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04)
+#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06)
+#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10)
+#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12)
+#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14)
+#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16)
+#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18) /* 15xx only */
+#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18)
+#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a)
+#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c)
+#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e)
+#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28)
/* Common channel specific registers for omap2 */
-#define OMAP_DMA_CCR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x80)
-#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x84)
-#define OMAP_DMA_CICR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x88)
-#define OMAP_DMA_CSR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x8c)
-#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x90)
-#define OMAP_DMA_CEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x94)
-#define OMAP_DMA_CFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x98)
-#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa4)
-#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa8)
-#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xac)
-#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb0)
-#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb4)
-#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb8)
-
-#endif
+#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80)
+#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80)
+#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84)
+#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88)
+#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c)
+#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90)
+#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94)
+#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98)
+#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4)
+#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8)
+#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac)
+#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0)
+#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4)
+#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8)
/* Channel specific registers only on omap1 */
-#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08)
-#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
-#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
-#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
-#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20)
-#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24)
-#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22)
-#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
+#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08)
+#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a)
+#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c)
+#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e)
+#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20)
+#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22)
+#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24)
+#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a) /* not on 15xx */
+#define OMAP1_DMA_CCEN(n) 0
+#define OMAP1_DMA_CCFN(n) 0
/* Channel specific registers only on omap2 */
-#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x9c)
-#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa0)
-#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xbc)
-#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc0)
-#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc4)
+#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c)
+#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0)
+#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc)
+#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0)
+#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4)
+
+/* Dummy defines to keep multi-omap compiles happy */
+#define OMAP1_DMA_REVISION 0
+#define OMAP1_DMA_IRQSTATUS_L0 0
+#define OMAP1_DMA_IRQENABLE_L0 0
+#define OMAP1_DMA_OCP_SYSCONFIG 0
+#define OMAP_DMA4_HW_ID 0
+#define OMAP_DMA4_CAPS_0_L 0
+#define OMAP_DMA4_CAPS_0_U 0
+#define OMAP_DMA4_CAPS_1_L 0
+#define OMAP_DMA4_CAPS_1_U 0
+#define OMAP_DMA4_GSCR 0
+#define OMAP_DMA4_CPC(n) 0
+
+#define OMAP_DMA4_LCH_CTRL(n) 0
+#define OMAP_DMA4_COLOR_L(n) 0
+#define OMAP_DMA4_COLOR_U(n) 0
+#define OMAP_DMA4_CCR2(n) 0
+#define OMAP1_DMA_CSSA(n) 0
+#define OMAP1_DMA_CDSA(n) 0
+#define OMAP_DMA4_CSSA_L(n) 0
+#define OMAP_DMA4_CSSA_U(n) 0
+#define OMAP_DMA4_CDSA_L(n) 0
+#define OMAP_DMA4_CDSA_U(n) 0
/*----------------------------------------------------------------------------*/
@@ -196,63 +216,98 @@
#define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */
#define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */
#define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */
-#define OMAP24XX_DMA_VLYNQ_TX 7 /* S_DMA_6 */
+#define OMAP242X_DMA_VLYNQ_TX 7 /* S_DMA_6 */
+#define OMAP24XX_DMA_EXT_DMAREQ2 7 /* S_DMA_6 */
#define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */
#define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */
#define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */
#define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */
#define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */
#define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */
-#define OMAP24XX_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */
-#define OMAP24XX_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */
-#define OMAP24XX_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */
-#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */
-#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */
-#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
-#define OMAP24XX_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */
-#define OMAP24XX_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */
-#define OMAP24XX_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */
-#define OMAP24XX_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */
-#define OMAP24XX_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */
-#define OMAP24XX_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */
-#define OMAP24XX_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */
+#define OMAP34XX_DMA_SHA2MD5_RX 13 /* S_DMA_12 */
+#define OMAP242X_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */
+#define OMAP242X_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */
+#define OMAP242X_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */
+#define OMAP242X_DMA_EAC_AC_RD 17 /* S_DMA_16 */
+#define OMAP242X_DMA_EAC_AC_WR 18 /* S_DMA_17 */
+#define OMAP242X_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
+#define OMAP242X_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */
+#define OMAP242X_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */
+#define OMAP242X_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */
+#define OMAP242X_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */
+#define OMAP242X_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */
+#define OMAP242X_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */
+#define OMAP242X_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */
+#define OMAP243X_DMA_EXT_DMAREQ3 14 /* S_DMA_13 */
+#define OMAP24XX_DMA_SPI3_TX0 15 /* S_DMA_14 */
+#define OMAP24XX_DMA_SPI3_RX0 16 /* S_DMA_15 */
+#define OMAP24XX_DMA_MCBSP3_TX 17 /* S_DMA_16 */
+#define OMAP24XX_DMA_MCBSP3_RX 18 /* S_DMA_17 */
+#define OMAP24XX_DMA_MCBSP4_TX 19 /* S_DMA_18 */
+#define OMAP24XX_DMA_MCBSP4_RX 20 /* S_DMA_19 */
+#define OMAP24XX_DMA_MCBSP5_TX 21 /* S_DMA_20 */
+#define OMAP24XX_DMA_MCBSP5_RX 22 /* S_DMA_21 */
+#define OMAP24XX_DMA_SPI3_TX1 23 /* S_DMA_22 */
+#define OMAP24XX_DMA_SPI3_RX1 24 /* S_DMA_23 */
+#define OMAP243X_DMA_EXT_DMAREQ4 25 /* S_DMA_24 */
+#define OMAP243X_DMA_EXT_DMAREQ5 26 /* S_DMA_25 */
+#define OMAP34XX_DMA_I2C3_TX 25 /* S_DMA_24 */
+#define OMAP34XX_DMA_I2C3_RX 26 /* S_DMA_25 */
#define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */
#define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */
#define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */
#define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */
-#define OMAP24XX_DMA_MCBSP1_TX 31 /* SDMA_30 */
-#define OMAP24XX_DMA_MCBSP1_RX 32 /* SDMA_31 */
-#define OMAP24XX_DMA_MCBSP2_TX 33 /* SDMA_32 */
-#define OMAP24XX_DMA_MCBSP2_RX 34 /* SDMA_33 */
-#define OMAP24XX_DMA_SPI1_TX0 35 /* SDMA_34 */
-#define OMAP24XX_DMA_SPI1_RX0 36 /* SDMA_35 */
-#define OMAP24XX_DMA_SPI1_TX1 37 /* SDMA_36 */
-#define OMAP24XX_DMA_SPI1_RX1 38 /* SDMA_37 */
-#define OMAP24XX_DMA_SPI1_TX2 39 /* SDMA_38 */
-#define OMAP24XX_DMA_SPI1_RX2 40 /* SDMA_39 */
-#define OMAP24XX_DMA_SPI1_TX3 41 /* SDMA_40 */
-#define OMAP24XX_DMA_SPI1_RX3 42 /* SDMA_41 */
-#define OMAP24XX_DMA_SPI2_TX0 43 /* SDMA_42 */
-#define OMAP24XX_DMA_SPI2_RX0 44 /* SDMA_43 */
-#define OMAP24XX_DMA_SPI2_TX1 45 /* SDMA_44 */
-#define OMAP24XX_DMA_SPI2_RX1 46 /* SDMA_45 */
-
-#define OMAP24XX_DMA_UART1_TX 49 /* SDMA_48 */
-#define OMAP24XX_DMA_UART1_RX 50 /* SDMA_49 */
-#define OMAP24XX_DMA_UART2_TX 51 /* SDMA_50 */
-#define OMAP24XX_DMA_UART2_RX 52 /* SDMA_51 */
-#define OMAP24XX_DMA_UART3_TX 53 /* SDMA_52 */
-#define OMAP24XX_DMA_UART3_RX 54 /* SDMA_53 */
-#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* SDMA_54 */
-#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* SDMA_55 */
-#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* SDMA_56 */
-#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* SDMA_57 */
-#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* SDMA_58 */
-#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* SDMA_59 */
-#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */
-#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */
-#define OMAP24XX_DMA_MS 63 /* SDMA_62 */
-#define OMAP24XX_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */
+#define OMAP24XX_DMA_MCBSP1_TX 31 /* S_DMA_30 */
+#define OMAP24XX_DMA_MCBSP1_RX 32 /* S_DMA_31 */
+#define OMAP24XX_DMA_MCBSP2_TX 33 /* S_DMA_32 */
+#define OMAP24XX_DMA_MCBSP2_RX 34 /* S_DMA_33 */
+#define OMAP24XX_DMA_SPI1_TX0 35 /* S_DMA_34 */
+#define OMAP24XX_DMA_SPI1_RX0 36 /* S_DMA_35 */
+#define OMAP24XX_DMA_SPI1_TX1 37 /* S_DMA_36 */
+#define OMAP24XX_DMA_SPI1_RX1 38 /* S_DMA_37 */
+#define OMAP24XX_DMA_SPI1_TX2 39 /* S_DMA_38 */
+#define OMAP24XX_DMA_SPI1_RX2 40 /* S_DMA_39 */
+#define OMAP24XX_DMA_SPI1_TX3 41 /* S_DMA_40 */
+#define OMAP24XX_DMA_SPI1_RX3 42 /* S_DMA_41 */
+#define OMAP24XX_DMA_SPI2_TX0 43 /* S_DMA_42 */
+#define OMAP24XX_DMA_SPI2_RX0 44 /* S_DMA_43 */
+#define OMAP24XX_DMA_SPI2_TX1 45 /* S_DMA_44 */
+#define OMAP24XX_DMA_SPI2_RX1 46 /* S_DMA_45 */
+#define OMAP24XX_DMA_MMC2_TX 47 /* S_DMA_46 */
+#define OMAP24XX_DMA_MMC2_RX 48 /* S_DMA_47 */
+#define OMAP24XX_DMA_UART1_TX 49 /* S_DMA_48 */
+#define OMAP24XX_DMA_UART1_RX 50 /* S_DMA_49 */
+#define OMAP24XX_DMA_UART2_TX 51 /* S_DMA_50 */
+#define OMAP24XX_DMA_UART2_RX 52 /* S_DMA_51 */
+#define OMAP24XX_DMA_UART3_TX 53 /* S_DMA_52 */
+#define OMAP24XX_DMA_UART3_RX 54 /* S_DMA_53 */
+#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* S_DMA_54 */
+#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* S_DMA_55 */
+#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* S_DMA_56 */
+#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* S_DMA_57 */
+#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* S_DMA_58 */
+#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* S_DMA_59 */
+#define OMAP24XX_DMA_MMC1_TX 61 /* S_DMA_60 */
+#define OMAP24XX_DMA_MMC1_RX 62 /* S_DMA_61 */
+#define OMAP24XX_DMA_MS 63 /* S_DMA_62 */
+#define OMAP242X_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */
+#define OMAP243X_DMA_EXT_DMAREQ6 64 /* S_DMA_63 */
+#define OMAP34XX_DMA_EXT_DMAREQ3 64 /* S_DMA_63 */
+#define OMAP34XX_DMA_AES2_TX 65 /* S_DMA_64 */
+#define OMAP34XX_DMA_AES2_RX 66 /* S_DMA_65 */
+#define OMAP34XX_DMA_DES2_TX 67 /* S_DMA_66 */
+#define OMAP34XX_DMA_DES2_RX 68 /* S_DMA_67 */
+#define OMAP34XX_DMA_SHA1MD5_RX 69 /* S_DMA_68 */
+#define OMAP34XX_DMA_SPI4_TX0 70 /* S_DMA_69 */
+#define OMAP34XX_DMA_SPI4_RX0 71 /* S_DMA_70 */
+#define OMAP34XX_DSS_DMA0 72 /* S_DMA_71 */
+#define OMAP34XX_DSS_DMA1 73 /* S_DMA_72 */
+#define OMAP34XX_DSS_DMA2 74 /* S_DMA_73 */
+#define OMAP34XX_DSS_DMA3 75 /* S_DMA_74 */
+#define OMAP34XX_DMA_MMC3_TX 77 /* S_DMA_76 */
+#define OMAP34XX_DMA_MMC3_RX 78 /* S_DMA_77 */
+#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */
+#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */
/*----------------------------------------------------------------------------*/
@@ -358,6 +413,11 @@ enum omap_dma_burst_mode {
OMAP_DMA_DATA_BURST_16,
};
+enum end_type {
+ OMAP_DMA_LITTLE_ENDIAN = 0,
+ OMAP_DMA_BIG_ENDIAN
+};
+
enum omap_dma_color_mode {
OMAP_DMA_COLOR_DIS = 0,
OMAP_DMA_CONSTANT_FILL,
@@ -370,24 +430,34 @@ enum omap_dma_write_mode {
OMAP_DMA_WRITE_LAST_NON_POSTED
};
+enum omap_dma_channel_mode {
+ OMAP_DMA_LCH_2D = 0,
+ OMAP_DMA_LCH_G,
+ OMAP_DMA_LCH_P,
+ OMAP_DMA_LCH_PD
+};
+
struct omap_dma_channel_params {
int data_type; /* data type 8,16,32 */
int elem_count; /* number of elements in a frame */
int frame_count; /* number of frames in a element */
int src_port; /* Only on OMAP1 REVISIT: Is this needed? */
- int src_amode; /* constant , post increment, indexed , double indexed */
+ int src_amode; /* constant, post increment, indexed,
+ double indexed */
unsigned long src_start; /* source address : physical */
int src_ei; /* source element index */
int src_fi; /* source frame index */
int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */
- int dst_amode; /* constant , post increment, indexed , double indexed */
+ int dst_amode; /* constant, post increment, indexed,
+ double indexed */
unsigned long dst_start; /* source address : physical */
int dst_ei; /* source element index */
int dst_fi; /* source frame index */
- int trigger; /* trigger attached if the channel is synchronized */
+ int trigger; /* trigger attached if the channel is
+ synchronized */
int sync_mode; /* sycn on element, frame , block or packet */
int src_or_dst_synch; /* source synch(1) or destination synch(0) */
@@ -404,8 +474,8 @@ struct omap_dma_channel_params {
extern void omap_set_dma_priority(int lch, int dst_port, int priority);
extern int omap_request_dma(int dev_id, const char *dev_name,
- void (* callback)(int lch, u16 ch_status, void *data),
- void *data, int *dma_ch);
+ void (*callback)(int lch, u16 ch_status, void *data),
+ void *data, int *dma_ch);
extern void omap_enable_dma_irq(int ch, u16 irq_bits);
extern void omap_disable_dma_irq(int ch, u16 irq_bits);
extern void omap_free_dma(int ch);
@@ -418,6 +488,7 @@ extern void omap_set_dma_transfer_params(int lch, int data_type,
extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
u32 color);
extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
+extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
unsigned long src_start,
@@ -436,23 +507,26 @@ extern void omap_set_dma_dest_burst_mode(int lch,
enum omap_dma_burst_mode burst_mode);
extern void omap_set_dma_params(int lch,
- struct omap_dma_channel_params * params);
+ struct omap_dma_channel_params *params);
-extern void omap_dma_link_lch (int lch_head, int lch_queue);
-extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
+extern void omap_dma_link_lch(int lch_head, int lch_queue);
+extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
extern int omap_set_dma_callback(int lch,
- void (* callback)(int lch, u16 ch_status, void *data),
+ void (*callback)(int lch, u16 ch_status, void *data),
void *data);
extern dma_addr_t omap_get_dma_src_pos(int lch);
extern dma_addr_t omap_get_dma_dst_pos(int lch);
-extern int omap_get_dma_src_addr_counter(int lch);
extern void omap_clear_dma(int lch);
+extern int omap_get_dma_active_status(int lch);
extern int omap_dma_running(void);
extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
int tparams);
extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
unsigned char write_prio);
+extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
+extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
+extern int omap_get_dma_index(int lch, int *ei, int *fi);
/* Chaining APIs */
#ifndef CONFIG_ARCH_OMAP1
@@ -478,7 +552,7 @@ extern int omap_dma_chain_status(int chain_id);
#endif
/* LCD DMA functions */
-extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
+extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
void *data);
extern void omap_free_lcd_dma(void);
extern void omap_setup_lcd_dma(void);
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
index fefb276ed40..02b29e8437a 100644
--- a/include/asm-arm/arch-omap/dmtimer.h
+++ b/include/asm-arm/arch-omap/dmtimer.h
@@ -66,6 +66,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer);
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
diff --git a/include/asm-arm/arch-omap/fpga.h b/include/asm-arm/arch-omap/fpga.h
index 6a883e0bdbb..f420881d2a3 100644
--- a/include/asm-arm/arch-omap/fpga.h
+++ b/include/asm-arm/arch-omap/fpga.h
@@ -169,30 +169,29 @@ struct h2p2_dbg_fpga {
#define OMAP1510_INT_FPGA (IH_GPIO_BASE + 13)
/* IRQ Numbers for interrupts muxed through the FPGA */
-#define OMAP1510_IH_FPGA_BASE IH_BOARD_BASE
-#define OMAP1510_INT_FPGA_ATN (OMAP1510_IH_FPGA_BASE + 0)
-#define OMAP1510_INT_FPGA_ACK (OMAP1510_IH_FPGA_BASE + 1)
-#define OMAP1510_INT_FPGA2 (OMAP1510_IH_FPGA_BASE + 2)
-#define OMAP1510_INT_FPGA3 (OMAP1510_IH_FPGA_BASE + 3)
-#define OMAP1510_INT_FPGA4 (OMAP1510_IH_FPGA_BASE + 4)
-#define OMAP1510_INT_FPGA5 (OMAP1510_IH_FPGA_BASE + 5)
-#define OMAP1510_INT_FPGA6 (OMAP1510_IH_FPGA_BASE + 6)
-#define OMAP1510_INT_FPGA7 (OMAP1510_IH_FPGA_BASE + 7)
-#define OMAP1510_INT_FPGA8 (OMAP1510_IH_FPGA_BASE + 8)
-#define OMAP1510_INT_FPGA9 (OMAP1510_IH_FPGA_BASE + 9)
-#define OMAP1510_INT_FPGA10 (OMAP1510_IH_FPGA_BASE + 10)
-#define OMAP1510_INT_FPGA11 (OMAP1510_IH_FPGA_BASE + 11)
-#define OMAP1510_INT_FPGA12 (OMAP1510_IH_FPGA_BASE + 12)
-#define OMAP1510_INT_ETHER (OMAP1510_IH_FPGA_BASE + 13)
-#define OMAP1510_INT_FPGAUART1 (OMAP1510_IH_FPGA_BASE + 14)
-#define OMAP1510_INT_FPGAUART2 (OMAP1510_IH_FPGA_BASE + 15)
-#define OMAP1510_INT_FPGA_TS (OMAP1510_IH_FPGA_BASE + 16)
-#define OMAP1510_INT_FPGA17 (OMAP1510_IH_FPGA_BASE + 17)
-#define OMAP1510_INT_FPGA_CAM (OMAP1510_IH_FPGA_BASE + 18)
-#define OMAP1510_INT_FPGA_RTC_A (OMAP1510_IH_FPGA_BASE + 19)
-#define OMAP1510_INT_FPGA_RTC_B (OMAP1510_IH_FPGA_BASE + 20)
-#define OMAP1510_INT_FPGA_CD (OMAP1510_IH_FPGA_BASE + 21)
-#define OMAP1510_INT_FPGA22 (OMAP1510_IH_FPGA_BASE + 22)
-#define OMAP1510_INT_FPGA23 (OMAP1510_IH_FPGA_BASE + 23)
+#define OMAP1510_INT_FPGA_ATN (OMAP_FPGA_IRQ_BASE + 0)
+#define OMAP1510_INT_FPGA_ACK (OMAP_FPGA_IRQ_BASE + 1)
+#define OMAP1510_INT_FPGA2 (OMAP_FPGA_IRQ_BASE + 2)
+#define OMAP1510_INT_FPGA3 (OMAP_FPGA_IRQ_BASE + 3)
+#define OMAP1510_INT_FPGA4 (OMAP_FPGA_IRQ_BASE + 4)
+#define OMAP1510_INT_FPGA5 (OMAP_FPGA_IRQ_BASE + 5)
+#define OMAP1510_INT_FPGA6 (OMAP_FPGA_IRQ_BASE + 6)
+#define OMAP1510_INT_FPGA7 (OMAP_FPGA_IRQ_BASE + 7)
+#define OMAP1510_INT_FPGA8 (OMAP_FPGA_IRQ_BASE + 8)
+#define OMAP1510_INT_FPGA9 (OMAP_FPGA_IRQ_BASE + 9)
+#define OMAP1510_INT_FPGA10 (OMAP_FPGA_IRQ_BASE + 10)
+#define OMAP1510_INT_FPGA11 (OMAP_FPGA_IRQ_BASE + 11)
+#define OMAP1510_INT_FPGA12 (OMAP_FPGA_IRQ_BASE + 12)
+#define OMAP1510_INT_ETHER (OMAP_FPGA_IRQ_BASE + 13)
+#define OMAP1510_INT_FPGAUART1 (OMAP_FPGA_IRQ_BASE + 14)
+#define OMAP1510_INT_FPGAUART2 (OMAP_FPGA_IRQ_BASE + 15)
+#define OMAP1510_INT_FPGA_TS (OMAP_FPGA_IRQ_BASE + 16)
+#define OMAP1510_INT_FPGA17 (OMAP_FPGA_IRQ_BASE + 17)
+#define OMAP1510_INT_FPGA_CAM (OMAP_FPGA_IRQ_BASE + 18)
+#define OMAP1510_INT_FPGA_RTC_A (OMAP_FPGA_IRQ_BASE + 19)
+#define OMAP1510_INT_FPGA_RTC_B (OMAP_FPGA_IRQ_BASE + 20)
+#define OMAP1510_INT_FPGA_CD (OMAP_FPGA_IRQ_BASE + 21)
+#define OMAP1510_INT_FPGA22 (OMAP_FPGA_IRQ_BASE + 22)
+#define OMAP1510_INT_FPGA23 (OMAP_FPGA_IRQ_BASE + 23)
#endif
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 91d85b3417b..45fdfccbd5d 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -284,6 +284,7 @@
#include "omap1510.h"
#include "omap24xx.h"
#include "omap16xx.h"
+#include "omap34xx.h"
#ifndef __ASSEMBLER__
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 160578e1f55..0b13557fd30 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -60,6 +60,7 @@
#define IO_SIZE 0x40000
#define IO_VIRT (IO_PHYS - IO_OFFSET)
#define IO_ADDRESS(pa) ((pa) - IO_OFFSET)
+#define OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET)
#define io_p2v(pa) ((pa) - IO_OFFSET)
#define io_v2p(va) ((va) + IO_OFFSET)
@@ -91,6 +92,7 @@
#define IO_OFFSET 0x90000000
#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
+#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */
@@ -148,6 +150,7 @@
#define IO_OFFSET 0x90000000
#define IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
+#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
#define io_p2v(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
#define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */
@@ -183,35 +186,12 @@
#define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
#define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v))
-/* 16 bit uses LDRH/STRH, base +/- offset_8 */
-typedef struct { volatile u16 offset[256]; } __regbase16;
-#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \
- ->offset[((vaddr)&0xff)>>1]
-#define __REG16(paddr) __REGV16(io_p2v(paddr))
-
-/* 8/32 bit uses LDR/STR, base +/- offset_12 */
-typedef struct { volatile u8 offset[4096]; } __regbase8;
-#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \
- ->offset[((vaddr)&4095)>>0]
-#define __REG8(paddr) __REGV8(io_p2v(paddr))
-
-typedef struct { volatile u32 offset[4096]; } __regbase32;
-#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \
- ->offset[((vaddr)&4095)>>2]
-#define __REG32(paddr) __REGV32(io_p2v(paddr))
-
extern void omap1_map_common_io(void);
extern void omap1_init_common_hw(void);
extern void omap2_map_common_io(void);
extern void omap2_init_common_hw(void);
-#else
-
-#define __REG8(paddr) io_p2v(paddr)
-#define __REG16(paddr) io_p2v(paddr)
-#define __REG32(paddr) io_p2v(paddr)
-
#endif
#endif
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 87973654e62..7464c694859 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -285,7 +285,41 @@
#define OMAP_MAX_GPIO_LINES 192
#define IH_GPIO_BASE (128 + IH2_BASE)
#define IH_MPUIO_BASE (OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
-#define IH_BOARD_BASE (16 + IH_MPUIO_BASE)
+#define OMAP_IRQ_END (IH_MPUIO_BASE + 16)
+
+/* External FPGA handles interrupts on Innovator boards */
+#define OMAP_FPGA_IRQ_BASE (OMAP_IRQ_END)
+#ifdef CONFIG_MACH_OMAP_INNOVATOR
+#define OMAP_FPGA_NR_IRQS 24
+#else
+#define OMAP_FPGA_NR_IRQS 0
+#endif
+#define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
+
+/* External TWL4030 can handle interrupts on 2430 and 34xx boards */
+#define TWL4030_IRQ_BASE (OMAP_FPGA_IRQ_END)
+#ifdef CONFIG_TWL4030_CORE
+#define TWL4030_BASE_NR_IRQS 8
+#define TWL4030_PWR_NR_IRQS 8
+#else
+#define TWL4030_BASE_NR_IRQS 0
+#define TWL4030_PWR_NR_IRQS 0
+#endif
+#define TWL4030_IRQ_END (TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS)
+#define TWL4030_PWR_IRQ_BASE TWL4030_IRQ_END
+#define TWL4030_PWR_IRQ_END (TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS)
+
+/* External TWL4030 gpio interrupts are optional */
+#define TWL4030_GPIO_IRQ_BASE TWL4030_PWR_IRQ_END
+#ifdef CONFIG_TWL4030_GPIO
+#define TWL4030_GPIO_NR_IRQS 18
+#else
+#define TWL4030_GPIO_NR_IRQS 0
+#endif
+#define TWL4030_GPIO_IRQ_END (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
+
+/* Total number of interrupts depends on the enabled blocks above */
+#define NR_IRQS TWL4030_GPIO_IRQ_END
#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
@@ -293,14 +327,6 @@
extern void omap_init_irq(void);
#endif
-/*
- * The definition of NR_IRQS is in board-specific header file, which is
- * included via hardware.h
- */
#include <asm/hardware.h>
-#ifndef NR_IRQS
-#define NR_IRQS IH_BOARD_BASE
-#endif
-
#endif
diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h
index c7a0cc1c4e9..26c78f67dc8 100644
--- a/include/asm-arm/arch-omap/mcbsp.h
+++ b/include/asm-arm/arch-omap/mcbsp.h
@@ -24,7 +24,11 @@
#ifndef __ASM_ARCH_OMAP_MCBSP_H
#define __ASM_ARCH_OMAP_MCBSP_H
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+
#include <asm/hardware.h>
+#include <asm/arch/clock.h>
#define OMAP730_MCBSP1_BASE 0xfffb1000
#define OMAP730_MCBSP2_BASE 0xfffb1800
@@ -40,6 +44,9 @@
#define OMAP24XX_MCBSP1_BASE 0x48074000
#define OMAP24XX_MCBSP2_BASE 0x48076000
+#define OMAP34XX_MCBSP1_BASE 0x48074000
+#define OMAP34XX_MCBSP2_BASE 0x49022000
+
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
#define OMAP_MCBSP_REG_DRR2 0x00
@@ -74,7 +81,8 @@
#define OMAP_MCBSP_REG_XCERG 0x3A
#define OMAP_MCBSP_REG_XCERH 0x3C
-#define OMAP_MAX_MCBSP_COUNT 3
+#define OMAP_MAX_MCBSP_COUNT 3
+#define MAX_MCBSP_CLOCKS 3
#define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
#define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
@@ -117,7 +125,8 @@
#define OMAP_MCBSP_REG_XCERG 0x74
#define OMAP_MCBSP_REG_XCERH 0x78
-#define OMAP_MAX_MCBSP_COUNT 2
+#define OMAP_MAX_MCBSP_COUNT 2
+#define MAX_MCBSP_CLOCKS 2
#define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
#define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
@@ -298,6 +307,55 @@ struct omap_mcbsp_spi_cfg {
omap_mcbsp_word_length word_length;
};
+/* Platform specific configuration */
+struct omap_mcbsp_ops {
+ void (*request)(unsigned int);
+ void (*free)(unsigned int);
+ int (*check)(unsigned int);
+};
+
+struct omap_mcbsp_platform_data {
+ u32 virt_base;
+ u8 dma_rx_sync, dma_tx_sync;
+ u16 rx_irq, tx_irq;
+ struct omap_mcbsp_ops *ops;
+ char const *clk_name;
+};
+
+struct omap_mcbsp {
+ struct device *dev;
+ u32 io_base;
+ u8 id;
+ u8 free;
+ omap_mcbsp_word_length rx_word_length;
+ omap_mcbsp_word_length tx_word_length;
+
+ omap_mcbsp_io_type_t io_type; /* IRQ or poll */
+ /* IRQ based TX/RX */
+ int rx_irq;
+ int tx_irq;
+
+ /* DMA stuff */
+ u8 dma_rx_sync;
+ short dma_rx_lch;
+ u8 dma_tx_sync;
+ short dma_tx_lch;
+
+ /* Completion queues */
+ struct completion tx_irq_completion;
+ struct completion rx_irq_completion;
+ struct completion tx_dma_completion;
+ struct completion rx_dma_completion;
+
+ /* Protect the field .free, while checking if the mcbsp is in use */
+ spinlock_t lock;
+ struct omap_mcbsp_platform_data *pdata;
+ struct clk *clk;
+};
+
+int omap_mcbsp_init(void);
+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
+ int size);
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
int omap_mcbsp_request(unsigned int id);
void omap_mcbsp_free(unsigned int id);
diff --git a/include/asm-arm/arch-omap/omap34xx.h b/include/asm-arm/arch-omap/omap34xx.h
new file mode 100644
index 00000000000..aa30c6d10ab
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap34xx.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-arm/arch-omap/omap34xx.h
+ *
+ * This file contains the processor specific definitions of the TI OMAP34XX.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_OMAP34XX_H
+#define __ASM_ARCH_OMAP34XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+
+#define L4_34XX_BASE 0x48000000
+#define L4_WK_34XX_BASE 0x48300000
+#define L4_WK_OMAP_BASE L4_WK_34XX_BASE
+#define L4_PER_34XX_BASE 0x49000000
+#define L4_PER_OMAP_BASE L4_PER_34XX_BASE
+#define L4_EMU_34XX_BASE 0x54000000
+#define L4_EMU_BASE L4_EMU_34XX_BASE
+#define L3_34XX_BASE 0x68000000
+#define L3_OMAP_BASE L3_34XX_BASE
+
+#define OMAP3430_32KSYNCT_BASE 0x48320000
+#define OMAP3430_CM_BASE 0x48004800
+#define OMAP3430_PRM_BASE 0x48306800
+#define OMAP343X_SMS_BASE 0x6C000000
+#define OMAP343X_SDRC_BASE 0x6D000000
+#define OMAP34XX_GPMC_BASE 0x6E000000
+#define OMAP343X_SCM_BASE 0x48002000
+#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE
+
+#define OMAP34XX_IC_BASE 0x48200000
+#define OMAP34XX_IVA_INTC_BASE 0x40000000
+#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
+#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000)
+#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
+
+
+#if defined(CONFIG_ARCH_OMAP3430)
+
+#define OMAP2_32KSYNCT_BASE OMAP3430_32KSYNCT_BASE
+#define OMAP2_CM_BASE OMAP3430_CM_BASE
+#define OMAP2_PRM_BASE OMAP3430_PRM_BASE
+#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE)
+
+#endif
+
+#define OMAP34XX_DSP_BASE 0x58000000
+#define OMAP34XX_DSP_MEM_BASE (OMAP34XX_DSP_BASE + 0x0)
+#define OMAP34XX_DSP_IPI_BASE (OMAP34XX_DSP_BASE + 0x1000000)
+#define OMAP34XX_DSP_MMU_BASE (OMAP34XX_DSP_BASE + 0x2000000)
+#endif /* __ASM_ARCH_OMAP34XX_H */
+
diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h
index bb9bb3fd532..be59f4a9828 100644
--- a/include/asm-arm/arch-omap/sram.h
+++ b/include/asm-arm/arch-omap/sram.h
@@ -11,6 +11,7 @@
#ifndef __ARCH_ARM_OMAP_SRAM_H
#define __ARCH_ARM_OMAP_SRAM_H
+extern int __init omap_sram_init(void);
extern void * omap_sram_push(void * start, unsigned long size);
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
@@ -21,17 +22,35 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
/* Do not use these */
-extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
-extern unsigned long sram_reprogram_clock_sz;
+extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap1_sram_reprogram_clock_sz;
-extern void sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
- u32 base_cs, u32 force_unlock);
-extern unsigned long sram_ddr_init_sz;
+extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap24xx_sram_reprogram_clock_sz;
-extern u32 sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
-extern unsigned long sram_set_prcm_sz;
+extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern unsigned long omap242x_sram_ddr_init_sz;
-extern void sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type);
-extern unsigned long sram_reprogram_sdrc_sz;
+extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+ int bypass);
+extern unsigned long omap242x_sram_set_prcm_sz;
+
+extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern unsigned long omap242x_sram_reprogram_sdrc_sz;
+
+
+extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern unsigned long omap243x_sram_ddr_init_sz;
+
+extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+ int bypass);
+extern unsigned long omap243x_sram_set_prcm_sz;
+
+extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern unsigned long omap243x_sram_reprogram_sdrc_sz;
#endif
diff --git a/include/asm-arm/arch-omap/tc.h b/include/asm-arm/arch-omap/tc.h
index 8ded218cbea..65a9c82d3bf 100644
--- a/include/asm-arm/arch-omap/tc.h
+++ b/include/asm-arm/arch-omap/tc.h
@@ -75,16 +75,14 @@
#ifndef __ASSEMBLER__
/* EMIF Slow Interface Configuration Register */
-#define OMAP_EMIFS_CONFIG_REG __REG32(EMIFS_CONFIG)
-
#define OMAP_EMIFS_CONFIG_FR (1 << 4)
#define OMAP_EMIFS_CONFIG_PDE (1 << 3)
#define OMAP_EMIFS_CONFIG_PWD_EN (1 << 2)
#define OMAP_EMIFS_CONFIG_BM (1 << 1)
#define OMAP_EMIFS_CONFIG_WP (1 << 0)
-#define EMIFS_CCS(n) __REG32(EMIFS_CS0_CONFIG + (4 * (n)))
-#define EMIFS_ACS(n) __REG32(EMIFS_ACS0 + (4 * (n)))
+#define EMIFS_CCS(n) (EMIFS_CS0_CONFIG + (4 * (n)))
+#define EMIFS_ACS(n) (EMIFS_ACS0 + (4 * (n)))
/* Almost all documentation for chip and board memory maps assumes
* BM is clear. Most devel boards have a switch to control booting
@@ -93,13 +91,13 @@
*/
static inline u32 omap_cs0_phys(void)
{
- return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM)
+ return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
? OMAP_CS3_PHYS : 0;
}
static inline u32 omap_cs3_phys(void)
{
- return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM)
+ return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
? 0 : OMAP_CS3_PHYS;
}
diff --git a/include/asm-arm/arch-omap/usb.h b/include/asm-arm/arch-omap/usb.h
index 2147d18aaea..ddf1861e6df 100644
--- a/include/asm-arm/arch-omap/usb.h
+++ b/include/asm-arm/arch-omap/usb.h
@@ -34,11 +34,8 @@
/*
* OTG and transceiver registers, for OMAPs starting with ARM926
*/
-#define OTG_REG32(offset) __REG32(OTG_BASE + (offset))
-#define OTG_REG16(offset) __REG16(OTG_BASE + (offset))
-
-#define OTG_REV_REG OTG_REG32(0x00)
-#define OTG_SYSCON_1_REG OTG_REG32(0x04)
+#define OTG_REV (OTG_BASE + 0x00)
+#define OTG_SYSCON_1 (OTG_BASE + 0x04)
# define USB2_TRX_MODE(w) (((w)>>24)&0x07)
# define USB1_TRX_MODE(w) (((w)>>20)&0x07)
# define USB0_TRX_MODE(w) (((w)>>16)&0x07)
@@ -47,7 +44,7 @@
# define DEV_IDLE_EN (1 << 13)
# define OTG_RESET_DONE (1 << 2)
# define OTG_SOFT_RESET (1 << 1)
-#define OTG_SYSCON_2_REG OTG_REG32(0x08)
+#define OTG_SYSCON_2 (OTG_BASE + 0x08)
# define OTG_EN (1 << 31)
# define USBX_SYNCHRO (1 << 30)
# define OTG_MST16 (1 << 29)
@@ -65,7 +62,7 @@
# define HMC_TLLSPEED (1 << 7)
# define HMC_TLLATTACH (1 << 6)
# define OTG_HMC(w) (((w)>>0)&0x3f)
-#define OTG_CTRL_REG OTG_REG32(0x0c)
+#define OTG_CTRL (OTG_BASE + 0x0c)
# define OTG_USB2_EN (1 << 29)
# define OTG_USB2_DP (1 << 28)
# define OTG_USB2_DM (1 << 27)
@@ -92,7 +89,7 @@
# define OTG_PD_VBUS (1 << 2)
# define OTG_PU_VBUS (1 << 1)
# define OTG_PU_ID (1 << 0)
-#define OTG_IRQ_EN_REG OTG_REG16(0x10)
+#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */
# define DRIVER_SWITCH (1 << 15)
# define A_VBUS_ERR (1 << 13)
# define A_REQ_TMROUT (1 << 12)
@@ -102,9 +99,9 @@
# define B_SRP_DONE (1 << 8)
# define B_SRP_STARTED (1 << 7)
# define OPRT_CHG (1 << 0)
-#define OTG_IRQ_SRC_REG OTG_REG16(0x14)
+#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */
// same bits as in IRQ_EN
-#define OTG_OUTCTRL_REG OTG_REG16(0x18)
+#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */
# define OTGVPD (1 << 14)
# define OTGVPU (1 << 13)
# define OTGPUID (1 << 12)
@@ -117,13 +114,13 @@
# define USB0VDR (1 << 2)
# define USB0PDEN (1 << 1)
# define USB0PUEN (1 << 0)
-#define OTG_TEST_REG OTG_REG16(0x20)
-#define OTG_VENDOR_CODE_REG OTG_REG32(0xfc)
+#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */
+#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */
/*-------------------------------------------------------------------------*/
/* OMAP1 */
-#define USB_TRANSCEIVER_CTRL_REG __REG32(0xfffe1000 + 0x0064)
+#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064)
# define CONF_USB2_UNI_R (1 << 8)
# define CONF_USB1_UNI_R (1 << 7)
# define CONF_USB_PORT0_R(x) (((x)>>4)&0x7)
diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
index b4da08d7a33..6bd2295c0e0 100644
--- a/include/asm-arm/arch-rpc/io.h
+++ b/include/asm-arm/arch-rpc/io.h
@@ -126,7 +126,7 @@ static inline unsigned sz __in##fnsuffix (unsigned int port) \
return (unsigned sz)value; \
}
-static inline void __iomem *__ioaddr(unsigned int port)
+static inline void __iomem *__deprecated __ioaddr(unsigned int port)
{
void __iomem *ret;
if (__PORT_PCIO(port))
@@ -232,8 +232,7 @@ DECLARE_IO(int,l,"")
result; \
})
-#define __ioaddrc(port) \
- ((__PORT_PCIO(port) ? PCIO_BASE : IO_BASE) + ((port) << 2))
+#define __ioaddrc(port) __ioaddr(port)
#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h
index 7583895fd33..18e10d2c35e 100644
--- a/include/asm-arm/arch-s3c2410/gpio.h
+++ b/include/asm-arm/arch-s3c2410/gpio.h
@@ -1,68 +1,18 @@
-/*
- * linux/include/asm-arm/arch-s3c2410/gpio.h
+/* linux/include/asm-arm/arch-s3c2410/gpio.h
*
- * S3C2410 GPIO wrappers for arch-neutral GPIO calls
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
*
- * Written by Philipp Zabel <philipp.zabel@gmail.com>
+ * S3C2410 - GPIO lib support
*
* 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
- *
- */
-
-#ifndef __ASM_ARCH_S3C2410_GPIO_H
-#define __ASM_ARCH_S3C2410_GPIO_H
-
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/arch/regs-gpio.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline void gpio_free(unsigned gpio)
-{
- return;
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT);
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT);
- /* REVISIT can we write the value first, to avoid glitching? */
- s3c2410_gpio_setpin(gpio, value);
- return 0;
-}
-
-#define gpio_get_value(gpio) s3c2410_gpio_getpin(gpio)
-#define gpio_set_value(gpio,value) s3c2410_gpio_setpin(gpio, value)
-
-#include <asm-generic/gpio.h> /* cansleep wrappers */
-
-#ifdef CONFIG_CPU_S3C2400
-#define gpio_to_irq(gpio) s3c2400_gpio_getirq(gpio)
-#else
-#define gpio_to_irq(gpio) s3c2410_gpio_getirq(gpio)
-#endif
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
-/* FIXME implement irq_to_gpio() */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
-#endif
+#include <asm-generic/gpio.h>
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index ecae9e7f5e4..37661358b42 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -189,6 +189,8 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9)
#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10)
#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11)
+#define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12)
+#define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14)
#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index b85d426bb52..70b0fe724b6 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -406,6 +406,13 @@ extern void flush_dcache_page(struct page *);
extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+static inline void __flush_icache_all(void)
+{
+ asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
+ :
+ : "r" (0));
+}
+
#define ARCH_HAS_FLUSH_ANON_PAGE
static inline void flush_anon_page(struct vm_area_struct *vma,
struct page *page, unsigned long vmaddr)
diff --git a/include/asm-arm/dyntick.h b/include/asm-arm/dyntick.h
deleted file mode 100644
index 19fab2d2b76..00000000000
--- a/include/asm-arm/dyntick.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASMARM_DYNTICK_H
-#define _ASMARM_DYNTICK_H
-
-#include <asm/mach/time.h>
-
-#endif /* _ASMARM_DYNTICK_H */
diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
index 684fe064523..5e22881a630 100644
--- a/include/asm-arm/ecard.h
+++ b/include/asm-arm/ecard.h
@@ -85,19 +85,6 @@
#define MAX_ECARDS 9
-typedef enum { /* Cards address space */
- ECARD_IOC,
- ECARD_MEMC,
- ECARD_EASI
-} card_type_t;
-
-typedef enum { /* Speed for ECARD_IOC space */
- ECARD_SLOW = 0,
- ECARD_MEDIUM = 1,
- ECARD_FAST = 2,
- ECARD_SYNC = 3
-} card_speed_t;
-
struct ecard_id { /* Card ID structure */
unsigned short manufacturer;
unsigned short product;
@@ -190,16 +177,6 @@ struct in_chunk_dir {
};
/*
- * ecard_claim: claim an expansion card entry
- */
-#define ecard_claim(ec) ((ec)->claimed = 1)
-
-/*
- * ecard_release: release an expansion card entry
- */
-#define ecard_release(ec) ((ec)->claimed = 0)
-
-/*
* Read a chunk from an expansion card
* cd : where to put read data
* ec : expansion card info struct
@@ -209,18 +186,6 @@ struct in_chunk_dir {
extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
/*
- * Obtain the address of a card. This returns the "old style" address
- * and should no longer be used.
- */
-static inline unsigned int __deprecated
-ecard_address(struct expansion_card *ec, card_type_t type, card_speed_t speed)
-{
- extern unsigned int __ecard_address(struct expansion_card *,
- card_type_t, card_speed_t);
- return __ecard_address(ec, type, speed);
-}
-
-/*
* Request and release ecard resources
*/
extern int ecard_request_resources(struct expansion_card *ec);
diff --git a/include/asm-arm/hardware/iop3xx-gpio.h b/include/asm-arm/hardware/iop3xx-gpio.h
new file mode 100644
index 00000000000..0c9331f9ac2
--- /dev/null
+++ b/include/asm-arm/hardware/iop3xx-gpio.h
@@ -0,0 +1,73 @@
+/*
+ * linux/include/asm-arm/hardware/iop3xx-gpio.h
+ *
+ * IOP3xx GPIO wrappers
+ *
+ * Copyright (c) 2008 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Based on IXP4XX gpio.h file
+ *
+ * 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
+ *
+ */
+
+#ifndef __ASM_ARM_HARDWARE_IOP3XX_GPIO_H
+#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H
+
+#include <asm/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define IOP3XX_N_GPIOS 8
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (gpio > IOP3XX_N_GPIOS)
+ return __gpio_get_value(gpio);
+
+ return gpio_line_get(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio > IOP3XX_N_GPIOS) {
+ __gpio_set_value(gpio, value);
+ return;
+ }
+ gpio_line_set(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ if (gpio < IOP3XX_N_GPIOS)
+ return 0;
+ else
+ return __gpio_cansleep(gpio);
+}
+
+/*
+ * The GPIOs are not generating any interrupt
+ * Note : manuals are not clear about this
+ */
+static inline int gpio_to_irq(int gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(int gpio)
+{
+ return -EINVAL;
+}
+
+#endif
+
diff --git a/include/asm-arm/hw_irq.h b/include/asm-arm/hw_irq.h
index 98d594a973d..f1a08a50060 100644
--- a/include/asm-arm/hw_irq.h
+++ b/include/asm-arm/hw_irq.h
@@ -6,15 +6,4 @@
#include <asm/mach/irq.h>
-#if defined(CONFIG_NO_IDLE_HZ)
-# include <asm/dyntick.h>
-# define handle_dynamic_tick(action) \
- if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) { \
- write_seqlock(&xtime_lock); \
- if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) \
- system_timer->dyn_tick->handler(irq, NULL); \
- write_sequnlock(&xtime_lock); \
- }
-#endif
-
#endif
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 47fe34d692d..c8986bb99ed 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -14,8 +14,6 @@
#define KEXEC_ARCH KEXEC_ARCH_ARM
-#define KEXEC_BOOT_PARAMS_SIZE 1536
-
#define KEXEC_ARM_ATAGS_OFFSET 0x1000
#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h
index 5dc357013b7..2fd36ea0130 100644
--- a/include/asm-arm/mach/time.h
+++ b/include/asm-arm/mach/time.h
@@ -41,30 +41,8 @@ struct sys_timer {
#ifndef CONFIG_GENERIC_TIME
unsigned long (*offset)(void);
#endif
-
-#ifdef CONFIG_NO_IDLE_HZ
- struct dyn_tick_timer *dyn_tick;
-#endif
-};
-
-#ifdef CONFIG_NO_IDLE_HZ
-
-#define DYN_TICK_ENABLED (1 << 1)
-
-struct dyn_tick_timer {
- spinlock_t lock;
- unsigned int state; /* Current state */
- int (*enable)(void); /* Enables dynamic tick */
- int (*disable)(void); /* Disables dynamic tick */
- void (*reprogram)(unsigned long); /* Reprograms the timer */
- int (*handler)(int, void *);
};
-void timer_dyn_reprogram(void);
-#else
-#define timer_dyn_reprogram() do { } while (0)
-#endif
-
extern struct sys_timer *system_timer;
extern void timer_tick(void);
diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h
index 6913d02ca5d..91b9dfdfed5 100644
--- a/include/asm-arm/mmu_context.h
+++ b/include/asm-arm/mmu_context.h
@@ -97,6 +97,11 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
#ifdef CONFIG_MMU
unsigned int cpu = smp_processor_id();
+#ifdef CONFIG_SMP
+ /* check for possible thread migration */
+ if (!cpus_empty(next->cpu_vm_mask) && !cpu_isset(cpu, next->cpu_vm_mask))
+ __flush_icache_all();
+#endif
if (!cpu_test_and_set(cpu, next->cpu_vm_mask) || prev != next) {
check_context(next);
cpu_switch_mm(next->pgd, next);
diff --git a/include/asm-arm/plat-s3c/regs-timer.h b/include/asm-arm/plat-s3c/regs-timer.h
index 8b0d594397b..b5bc692f348 100644
--- a/include/asm-arm/plat-s3c/regs-timer.h
+++ b/include/asm-arm/plat-s3c/regs-timer.h
@@ -65,6 +65,15 @@
#define S3C2410_TCFG1_MUX0_TCLK0 (4<<0)
#define S3C2410_TCFG1_MUX0_MASK (15<<0)
+#define S3C2410_TCFG1_MUX_DIV2 (0<<0)
+#define S3C2410_TCFG1_MUX_DIV4 (1<<0)
+#define S3C2410_TCFG1_MUX_DIV8 (2<<0)
+#define S3C2410_TCFG1_MUX_DIV16 (3<<0)
+#define S3C2410_TCFG1_MUX_TCLK (4<<0)
+#define S3C2410_TCFG1_MUX_MASK (15<<0)
+
+#define S3C2410_TCFG1_SHIFT(x) ((x) * 4)
+
/* for each timer, we have an count buffer, an compare buffer and
* an observation buffer
*/
diff --git a/include/asm-arm/plat-s3c24xx/devs.h b/include/asm-arm/plat-s3c24xx/devs.h
index f9d6f0317bc..badaac9d64a 100644
--- a/include/asm-arm/plat-s3c24xx/devs.h
+++ b/include/asm-arm/plat-s3c24xx/devs.h
@@ -21,6 +21,8 @@ extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
extern struct platform_device *s3c24xx_uart_devs[];
extern struct platform_device *s3c24xx_uart_src[];
+extern struct platform_device s3c_device_timer[];
+
extern struct platform_device s3c_device_usb;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -36,11 +38,6 @@ extern struct platform_device s3c_device_spi1;
extern struct platform_device s3c_device_nand;
-extern struct platform_device s3c_device_timer0;
-extern struct platform_device s3c_device_timer1;
-extern struct platform_device s3c_device_timer2;
-extern struct platform_device s3c_device_timer3;
-
extern struct platform_device s3c_device_usbgadget;
/* s3c2440 specific devices */
diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h
deleted file mode 100644
index 1a5c9232a91..00000000000
--- a/include/asm-arm/rtc.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/include/asm-arm/rtc.h
- *
- * Copyright (C) 2003 Deep Blue Solutions Ltd.
- *
- * 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.
- */
-#ifndef ASMARM_RTC_H
-#define ASMARM_RTC_H
-
-struct module;
-
-struct rtc_ops {
- struct module *owner;
- int (*open)(void);
- void (*release)(void);
- int (*ioctl)(unsigned int, unsigned long);
-
- int (*read_time)(struct rtc_time *);
- int (*set_time)(struct rtc_time *);
- int (*read_alarm)(struct rtc_wkalrm *);
- int (*set_alarm)(struct rtc_wkalrm *);
- int (*proc)(char *buf);
-};
-
-void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
-void rtc_update(unsigned long, unsigned long);
-int register_rtc(struct rtc_ops *);
-void unregister_rtc(struct rtc_ops *);
-
-static inline int rtc_periodic_alarm(struct rtc_time *tm)
-{
- return (tm->tm_year == -1) ||
- ((unsigned)tm->tm_mon >= 12) ||
- ((unsigned)(tm->tm_mday - 1) >= 31) ||
- ((unsigned)tm->tm_hour > 23) ||
- ((unsigned)tm->tm_min > 59) ||
- ((unsigned)tm->tm_sec > 59);
-}
-
-#endif
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index 92a6d91d0c1..7cd25b8e7c9 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,6 +1,6 @@
header-y += kvm.h
-ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h)
+ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
unifdef-y += a.out.h
endif
unifdef-y += auxvec.h
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
index 7381916dfcb..bca352e033c 100644
--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -1,6 +1,5 @@
include include/asm-generic/Kbuild.asm
-header-y += a.out.h
header-y += auxvec.h
header-y += ioctls.h
header-y += mman.h
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
index 3707650a169..2b5f2c91db2 100644
--- a/include/asm-x86/msr.h
+++ b/include/asm-x86/msr.h
@@ -18,7 +18,7 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
unsigned long low, high;
asm volatile(".byte 0x0f,0x01,0xf9"
: "=a" (low), "=d" (high), "=c" (*aux));
- return low | ((u64)high >> 32);
+ return low | ((u64)high << 32);
}
/*
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index b6fbb2573e8..71d70d1fbce 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -166,7 +166,7 @@ unifdef-y += acct.h
unifdef-y += adb.h
unifdef-y += adfs_fs.h
unifdef-y += agpgart.h
-ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h)
+ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
unifdef-y += a.out.h
endif
unifdef-y += apm_bios.h
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 63c3bb98558..8b82974bdc1 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -571,7 +571,7 @@ extern void audit_log_lost(const char *message);
extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */
-extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
+extern int audit_filter_user(struct netlink_skb_parms *cb);
extern int audit_filter_type(int type);
extern int audit_receive_filter(int type, int pid, int uid, int seq,
void *data, size_t datasz, uid_t loginuid,
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 2a6639407c8..d982eb89c77 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -300,7 +300,7 @@ extern int d_validate(struct dentry *, struct dentry *);
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *__d_path(const struct path *path, struct path *root, char *, int);
-extern char *d_path(struct path *, char *, int);
+extern char *d_path(const struct path *, char *, int);
extern char *dentry_path(struct dentry *, char *, int);
/* Allocation counts.. */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d490779f18d..d8e2762ed14 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -83,6 +83,7 @@ extern int dir_notify_enable;
#define READ_SYNC (READ | (1 << BIO_RW_SYNC))
#define READ_META (READ | (1 << BIO_RW_META))
#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))
+#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC))
#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
#define SEL_IN 1
@@ -894,8 +895,6 @@ static inline int file_check_writeable(struct file *filp)
typedef struct files_struct *fl_owner_t;
struct file_lock_operations {
- void (*fl_insert)(struct file_lock *); /* lock insertion callback */
- void (*fl_remove)(struct file_lock *); /* lock removal callback */
void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
void (*fl_release_private)(struct file_lock *);
};
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index fb9af6a0fe9..8dc73013219 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -171,7 +171,7 @@ struct i2c_client {
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
- int irq; /* irq issued by device (or -1) */
+ int irq; /* irq issued by device */
struct list_head list; /* DEPRECATED */
struct completion released;
};
diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h
index 80335b7d77c..c4335faebb6 100644
--- a/include/linux/inet_lro.h
+++ b/include/linux/inet_lro.h
@@ -84,7 +84,11 @@ struct net_lro_mgr {
from received packets and eth protocol
is still ETH_P_8021Q */
- u32 ip_summed; /* Set in non generated SKBs in page mode */
+ /*
+ * Set for generated SKBs that are not added to
+ * the frag list in fragmented mode
+ */
+ u32 ip_summed;
u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY
* or CHECKSUM_NONE */
diff --git a/include/linux/input.h b/include/linux/input.h
index e075c4b762f..d150c57e5f0 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -534,8 +534,8 @@ struct input_absinfo {
#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
#define KEY_FRAMEFORWARD 0x1b5
-
#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
#define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f27fd200933..25f87102ab6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -88,6 +88,8 @@ struct wireless_dev;
#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/
#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */
+#ifdef __KERNEL__
+
/*
* Compute the worst case header length according to the protocols
* used.
@@ -114,6 +116,8 @@ struct wireless_dev;
#define MAX_HEADER (LL_MAX_HEADER + 48)
#endif
+#endif /* __KERNEL__ */
+
struct net_device_subqueue
{
/* Give a control state for each queue. This struct may contain
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 06d3e6eb9ca..917707e6151 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -66,8 +66,7 @@ struct thermal_cooling_device {
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
#define CELSIUS_TO_KELVIN(t) ((t)*10+2732)
-#if defined(CONFIG_HWMON) || \
- (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
/* thermal zone devices with the same type share one hwmon device */
struct thermal_hwmon_device {
char type[THERMAL_NAME_LENGTH];
@@ -94,8 +93,7 @@ struct thermal_zone_device {
struct idr idr;
struct mutex lock; /* protect cooling devices list */
struct list_head node;
-#if defined(CONFIG_HWMON) || \
- (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
struct list_head hwmon_node;
struct thermal_hwmon_device *hwmon;
struct thermal_hwmon_attr temp_input; /* hwmon sys attr */
diff --git a/include/media/cx25840.h b/include/media/cx25840.h
index cd599ad29fb..db431d513f2 100644
--- a/include/media/cx25840.h
+++ b/include/media/cx25840.h
@@ -32,12 +32,16 @@ enum cx25840_video_input {
CX25840_COMPOSITE7,
CX25840_COMPOSITE8,
- /* S-Video inputs consist of one luma input (In1-In4) ORed with one
+ /* S-Video inputs consist of one luma input (In1-In8) ORed with one
chroma input (In5-In8) */
CX25840_SVIDEO_LUMA1 = 0x10,
CX25840_SVIDEO_LUMA2 = 0x20,
CX25840_SVIDEO_LUMA3 = 0x30,
CX25840_SVIDEO_LUMA4 = 0x40,
+ CX25840_SVIDEO_LUMA5 = 0x50,
+ CX25840_SVIDEO_LUMA6 = 0x60,
+ CX25840_SVIDEO_LUMA7 = 0x70,
+ CX25840_SVIDEO_LUMA8 = 0x80,
CX25840_SVIDEO_CHROMA4 = 0x400,
CX25840_SVIDEO_CHROMA5 = 0x500,
CX25840_SVIDEO_CHROMA6 = 0x600,
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index bfee8be5d63..b8e8aa91905 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -146,6 +146,7 @@ extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
#endif
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 33f01ae08f7..859f7a6f6f6 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -40,9 +40,9 @@
#define VFL_TYPE_VTX 3
/* Video standard functions */
-extern char *v4l2_norm_to_name(v4l2_std_id id);
+extern const char *v4l2_norm_to_name(v4l2_std_id id);
extern int v4l2_video_std_construct(struct v4l2_standard *vs,
- int id, char *name);
+ int id, const char *name);
/* Prints the ioctl in a human-readable format */
extern void v4l_printk_ioctl(unsigned int cmd);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dae3f9ec115..bcd1623245c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -595,6 +595,15 @@ enum ieee80211_key_alg {
ALG_CCMP,
};
+/**
+ * enum ieee80211_key_len - key length
+ * @WEP40: WEP 5 byte long key
+ * @WEP104: WEP 13 byte long key
+ */
+enum ieee80211_key_len {
+ LEN_WEP40 = 5,
+ LEN_WEP104 = 13,
+};
/**
* enum ieee80211_key_flags - key flags
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index ab502ec1c61..a87fc0312ed 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -178,7 +178,7 @@ extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
struct Qdisc_ops *ops, u32 parentid);
extern void tcf_destroy(struct tcf_proto *tp);
-extern void tcf_destroy_chain(struct tcf_proto *fl);
+extern void tcf_destroy_chain(struct tcf_proto **fl);
static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff_head *list)
diff --git a/kernel/audit.c b/kernel/audit.c
index e8692a5748c..e092f1c0ce3 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -738,7 +738,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
return 0;
- err = audit_filter_user(&NETLINK_CB(skb), msg_type);
+ err = audit_filter_user(&NETLINK_CB(skb));
if (err == 1) {
err = 0;
if (msg_type == AUDIT_USER_TTY) {
@@ -779,7 +779,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
}
/* fallthrough */
case AUDIT_LIST:
- err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
+ err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
uid, seq, data, nlmsg_len(nlh),
loginuid, sessionid, sid);
break;
@@ -798,7 +798,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
}
/* fallthrough */
case AUDIT_LIST_RULES:
- err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
+ err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
uid, seq, data, nlmsg_len(nlh),
loginuid, sessionid, sid);
break;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 0e0bd27e651..98c50cc671b 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1544,6 +1544,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
* @data: payload data
* @datasz: size of payload data
* @loginuid: loginuid of sender
+ * @sessionid: sessionid for netlink audit message
* @sid: SE Linux Security ID of sender
*/
int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
@@ -1720,7 +1721,7 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb,
return 1;
}
-int audit_filter_user(struct netlink_skb_parms *cb, int type)
+int audit_filter_user(struct netlink_skb_parms *cb)
{
enum audit_state state = AUDIT_DISABLED;
struct audit_entry *e;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 421be5fe5cc..543d9ca9b4f 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1078,7 +1078,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
}
EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
-#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ)
+#ifdef CONFIG_NO_HZ
/**
* hrtimer_get_next_event - get the time until next expiry event
*
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c
index f4ffbd0f306..a38895a5b8e 100644
--- a/kernel/rcuclassic.c
+++ b/kernel/rcuclassic.c
@@ -89,8 +89,22 @@ static void force_quiescent_state(struct rcu_data *rdp,
/*
* Don't send IPI to itself. With irqs disabled,
* rdp->cpu is the current cpu.
+ *
+ * cpu_online_map is updated by the _cpu_down()
+ * using stop_machine_run(). Since we're in irqs disabled
+ * section, stop_machine_run() is not exectuting, hence
+ * the cpu_online_map is stable.
+ *
+ * However, a cpu might have been offlined _just_ before
+ * we disabled irqs while entering here.
+ * And rcu subsystem might not yet have handled the CPU_DEAD
+ * notification, leading to the offlined cpu's bit
+ * being set in the rcp->cpumask.
+ *
+ * Hence cpumask = (rcp->cpumask & cpu_online_map) to prevent
+ * sending smp_reschedule() to an offlined CPU.
*/
- cpumask = rcp->cpumask;
+ cpus_and(cpumask, rcp->cpumask, cpu_online_map);
cpu_clear(rdp->cpu, cpumask);
for_each_cpu_mask(cpu, cpumask)
smp_send_reschedule(cpu);
diff --git a/kernel/sched.c b/kernel/sched.c
index 3aaa5c8cb42..94ead43eda6 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5887,6 +5887,7 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
next = pick_next_task(rq, rq->curr);
if (!next)
break;
+ next->sched_class->put_prev_task(rq, next);
migrate_dead(dead_cpu, next);
}
@@ -8501,6 +8502,9 @@ int sched_group_set_rt_period(struct task_group *tg, long rt_period_us)
rt_period = (u64)rt_period_us * NSEC_PER_USEC;
rt_runtime = tg->rt_bandwidth.rt_runtime;
+ if (rt_period == 0)
+ return -EINVAL;
+
return tg_set_bandwidth(tg, rt_period, rt_runtime);
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 29116652dca..f6d2e57b99a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -132,8 +132,6 @@ extern int sysctl_userprocess_debug;
extern int spin_retry;
#endif
-extern int sysctl_hz_timer;
-
#ifdef CONFIG_BSD_PROCESS_ACCT
extern int acct_parm[];
#endif
@@ -563,16 +561,6 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
-#ifdef CONFIG_NO_IDLE_HZ
- {
- .ctl_name = KERN_HZ_TIMER,
- .procname = "hz_timer",
- .data = &sysctl_hz_timer,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
-#endif
{
.ctl_name = KERN_S390_USER_DEBUG_LOGGING,
.procname = "userprocess_debug",
diff --git a/kernel/timer.c b/kernel/timer.c
index ceacc662657..ef3fa6906e8 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -812,7 +812,7 @@ static inline void __run_timers(struct tvec_base *base)
spin_unlock_irq(&base->lock);
}
-#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ)
+#ifdef CONFIG_NO_HZ
/*
* Find out when the next timer event is due to happen. This
* is used on S/390 to stop all activity when a cpus is idle.
@@ -947,14 +947,6 @@ unsigned long get_next_timer_interrupt(unsigned long now)
return cmp_next_hrtimer_event(now, expires);
}
-
-#ifdef CONFIG_NO_IDLE_HZ
-unsigned long next_timer_interrupt(void)
-{
- return get_next_timer_interrupt(jiffies);
-}
-#endif
-
#endif
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index a76a5e122ae..85b18d79be8 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -68,6 +68,7 @@ static int fill_pool(void)
{
gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
struct debug_obj *new;
+ unsigned long flags;
if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL))
return obj_pool_free;
@@ -81,10 +82,10 @@ static int fill_pool(void)
if (!new)
return obj_pool_free;
- spin_lock(&pool_lock);
+ spin_lock_irqsave(&pool_lock, flags);
hlist_add_head(&new->node, &obj_pool);
obj_pool_free++;
- spin_unlock(&pool_lock);
+ spin_unlock_irqrestore(&pool_lock, flags);
}
return obj_pool_free;
}
@@ -110,16 +111,13 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
}
/*
- * Allocate a new object. If the pool is empty and no refill possible,
- * switch off the debugger.
+ * Allocate a new object. If the pool is empty, switch off the debugger.
*/
static struct debug_obj *
alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
{
struct debug_obj *obj = NULL;
- int retry = 0;
-repeat:
spin_lock(&pool_lock);
if (obj_pool.first) {
obj = hlist_entry(obj_pool.first, typeof(*obj), node);
@@ -141,9 +139,6 @@ repeat:
}
spin_unlock(&pool_lock);
- if (fill_pool() && !obj && !retry++)
- goto repeat;
-
return obj;
}
@@ -261,6 +256,8 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
struct debug_obj *obj;
unsigned long flags;
+ fill_pool();
+
db = get_bucket((unsigned long) addr);
spin_lock_irqsave(&db->lock, flags);
diff --git a/lib/ts_bm.c b/lib/ts_bm.c
index d90822c378a..4a7fce72898 100644
--- a/lib/ts_bm.c
+++ b/lib/ts_bm.c
@@ -63,7 +63,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
struct ts_bm *bm = ts_config_priv(conf);
unsigned int i, text_len, consumed = state->offset;
const u8 *text;
- int shift = bm->patlen, bs;
+ int shift = bm->patlen - 1, bs;
for (;;) {
text_len = conf->get_next_block(consumed, &text, conf, state);
diff --git a/net/core/dev.c b/net/core/dev.c
index c421a1f8f0b..fca23a3bf12 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -454,7 +454,7 @@ static int netdev_boot_setup_add(char *name, struct ifmap *map)
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
memset(s[i].name, 0, sizeof(s[i].name));
- strcpy(s[i].name, name);
+ strlcpy(s[i].name, name, IFNAMSIZ);
memcpy(&s[i].map, map, sizeof(s[i].map));
break;
}
@@ -479,7 +479,7 @@ int netdev_boot_setup_check(struct net_device *dev)
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
- !strncmp(dev->name, s[i].name, strlen(s[i].name))) {
+ !strcmp(dev->name, s[i].name)) {
dev->irq = s[i].map.irq;
dev->base_addr = s[i].map.base_addr;
dev->mem_start = s[i].map.mem_start;
@@ -2973,7 +2973,7 @@ EXPORT_SYMBOL(dev_unicast_delete);
/**
* dev_unicast_add - add a secondary unicast address
* @dev: device
- * @addr: address to delete
+ * @addr: address to add
* @alen: length of @addr
*
* Add a secondary unicast address to the device or increase
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index e3e9ab0f74e..277a2302eb3 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -226,7 +226,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
ops = lookup_rules_ops(net, frh->family);
if (ops == NULL) {
- err = EAFNOSUPPORT;
+ err = -EAFNOSUPPORT;
goto errout;
}
@@ -365,7 +365,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
ops = lookup_rules_ops(net, frh->family);
if (ops == NULL) {
- err = EAFNOSUPPORT;
+ err = -EAFNOSUPPORT;
goto errout;
}
diff --git a/net/core/filter.c b/net/core/filter.c
index 4f8369729a4..df374435583 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -68,7 +68,6 @@ static inline void *load_pointer(struct sk_buff *skb, int k,
* sk_filter - run a packet through a socket filter
* @sk: sock associated with &sk_buff
* @skb: buffer to filter
- * @needlock: set to 1 if the sock is not locked by caller.
*
* Run the filter code and then cut skb->data to correct size returned by
* sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e556d31211..366621610e7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1292,12 +1292,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
{
unsigned int nr_pages = spd->nr_pages;
unsigned int poff, plen, len, toff, tlen;
- int headlen, seg;
+ int headlen, seg, error = 0;
toff = *offset;
tlen = *total_len;
- if (!tlen)
+ if (!tlen) {
+ error = 1;
goto err;
+ }
/*
* if the offset is greater than the linear part, go directly to
@@ -1339,7 +1341,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
* just jump directly to update and return, no point
* in going over fragments when the output is full.
*/
- if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb))
+ error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb);
+ if (error)
goto done;
tlen -= plen;
@@ -1369,7 +1372,8 @@ map_frag:
if (!plen)
break;
- if (spd_fill_page(spd, f->page, plen, poff, skb))
+ error = spd_fill_page(spd, f->page, plen, poff, skb);
+ if (error)
break;
tlen -= plen;
@@ -1382,7 +1386,10 @@ done:
return 0;
}
err:
- return 1;
+ /* update the offset to reflect the linear part skip, if any */
+ if (!error)
+ *offset = toff;
+ return error;
}
/*
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 4ed429bd595..0546a0bc97e 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -192,14 +192,21 @@ EXPORT_SYMBOL(inet_frag_evictor);
static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
struct inet_frag_queue *qp_in, struct inet_frags *f,
- unsigned int hash, void *arg)
+ void *arg)
{
struct inet_frag_queue *qp;
#ifdef CONFIG_SMP
struct hlist_node *n;
#endif
+ unsigned int hash;
write_lock(&f->lock);
+ /*
+ * While we stayed w/o the lock other CPU could update
+ * the rnd seed, so we need to re-calculate the hash
+ * chain. Fortunatelly the qp_in can be used to get one.
+ */
+ hash = f->hashfn(qp_in);
#ifdef CONFIG_SMP
/* With SMP race we have to recheck hash table, because
* such entry could be created on other cpu, while we
@@ -247,7 +254,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
}
static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
- struct inet_frags *f, void *arg, unsigned int hash)
+ struct inet_frags *f, void *arg)
{
struct inet_frag_queue *q;
@@ -255,7 +262,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
if (q == NULL)
return NULL;
- return inet_frag_intern(nf, q, f, hash, arg);
+ return inet_frag_intern(nf, q, f, arg);
}
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
@@ -264,7 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frag_queue *q;
struct hlist_node *n;
- read_lock(&f->lock);
hlist_for_each_entry(q, n, &f->hash[hash], list) {
if (q->net == nf && f->match(q, key)) {
atomic_inc(&q->refcnt);
@@ -274,6 +280,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
}
read_unlock(&f->lock);
- return inet_frag_create(nf, f, key, hash);
+ return inet_frag_create(nf, f, key);
}
EXPORT_SYMBOL(inet_frag_find);
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index 4a4d49fca1f..cfd034a2b96 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -383,8 +383,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
out2: /* send aggregated SKBs to stack */
lro_flush(lro_mgr, lro_desc);
-out: /* Original SKB has to be posted to stack */
- skb->ip_summed = lro_mgr->ip_summed;
+out:
return 1;
}
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index cd6ce6ac635..37221f65915 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -229,6 +229,8 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
arg.iph = iph;
arg.user = user;
+
+ read_lock(&ip4_frags.lock);
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fc54a48fde1..850825dc86e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -260,6 +260,8 @@
#include <linux/socket.h>
#include <linux/random.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
#include <linux/cache.h>
#include <linux/err.h>
#include <linux/crypto.h>
@@ -2620,7 +2622,7 @@ __setup("thash_entries=", set_thash_entries);
void __init tcp_init(void)
{
struct sk_buff *skb = NULL;
- unsigned long limit;
+ unsigned long nr_pages, limit;
int order, i, max_share;
BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -2689,8 +2691,9 @@ void __init tcp_init(void)
* is up to 1/2 at 256 MB, decreasing toward zero with the amount of
* memory, with a floor of 128 pages.
*/
- limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
- limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+ nr_pages = totalram_pages - totalhigh_pages;
+ limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+ limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
limit = max(limit, 128UL);
sysctl_tcp_mem[0] = limit / 4 * 3;
sysctl_tcp_mem[1] = limit;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 12695be2c25..ffe869ac1bc 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2291,7 +2291,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
}
seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
- "%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
+ "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n",
i, src, srcp, dest, destp, sk->sk_state,
tp->write_seq - tp->snd_una,
sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
@@ -2303,8 +2303,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
icsk->icsk_probes_out,
sock_i_ino(sk),
atomic_read(&sk->sk_refcnt), sk,
- icsk->icsk_rto,
- icsk->icsk_ack.ato,
+ jiffies_to_clock_t(icsk->icsk_rto),
+ jiffies_to_clock_t(icsk->icsk_ack.ato),
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
tp->snd_cwnd,
tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 27a5e8b48d9..f405cea21a8 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
.priority = NF_IP6_PRI_MANGLE,
},
{
- .hook = ip6t_local_hook,
+ .hook = ip6t_route_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_LOCAL_IN,
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index e65e26e210e..cf20bc4fd60 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
arg.id = id;
arg.src = src;
arg.dst = dst;
+
+ read_lock_bh(&nf_frags.lock);
hash = ip6qhashfn(id, src, dst);
- local_bh_disable();
q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
local_bh_enable();
if (q == NULL)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 798cabc7535..a60d7d12971 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -247,6 +247,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
arg.id = id;
arg.src = src;
arg.dst = dst;
+
+ read_lock(&ip6_frags.lock);
hash = ip6qhashfn(id, src, dst);
q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d1f3e19b06c..7ff687020fa 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
static inline struct rt6_info *rt6_device_match(struct net *net,
struct rt6_info *rt,
int oif,
- int strict)
+ int flags)
{
struct rt6_info *local = NULL;
struct rt6_info *sprt;
@@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
if (dev->flags & IFF_LOOPBACK) {
if (sprt->rt6i_idev == NULL ||
sprt->rt6i_idev->dev->ifindex != oif) {
- if (strict && oif)
+ if (flags & RT6_LOOKUP_F_IFACE && oif)
continue;
if (local && (!oif ||
local->rt6i_idev->dev->ifindex == oif))
@@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
if (local)
return local;
- if (strict)
+ if (flags & RT6_LOOKUP_F_IFACE)
return net->ipv6.ip6_null_entry;
}
return rt;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cb46749d4c3..40ea9c36d24 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2036,7 +2036,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
seq_printf(seq,
"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n",
+ "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n",
i,
src->s6_addr32[0], src->s6_addr32[1],
src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -2052,8 +2052,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
icsk->icsk_probes_out,
sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp,
- icsk->icsk_rto,
- icsk->icsk_ack.ato,
+ jiffies_to_clock_t(icsk->icsk_rto),
+ jiffies_to_clock_t(icsk->icsk_ack.ato),
(icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 150d66dbda9..220e83be3ef 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -380,6 +380,15 @@ void ieee80211_key_free(struct ieee80211_key *key)
if (!key)
return;
+ if (!key->sdata) {
+ /* The key has not been linked yet, simply free it
+ * and don't Oops */
+ if (key->conf.alg == ALG_CCMP)
+ ieee80211_aes_key_free(key->u.ccmp.tfm);
+ kfree(key);
+ return;
+ }
+
spin_lock_irqsave(&key->sdata->local->key_lock, flags);
__ieee80211_key_free(key);
spin_unlock_irqrestore(&key->sdata->local->key_lock, flags);
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 6106cb79060..e8404212ad5 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -95,6 +95,13 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
}
}
+ if (alg == ALG_WEP &&
+ key_len != LEN_WEP40 && key_len != LEN_WEP104) {
+ ieee80211_key_free(key);
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
ieee80211_key_link(key, sdata, sta);
if (set_tx_key || (!sta && !sdata->default_key && key))
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 635b996c8c3..5d09e8698b5 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -323,8 +323,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
struct ieee80211_hw *hw = &local->hw;
int queue;
- tcf_destroy_chain(q->filter_list);
- q->filter_list = NULL;
+ tcf_destroy_chain(&q->filter_list);
for (queue=0; queue < hw->queues; queue++) {
skb_queue_purge(&q->requeued[queue]);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ba94004fe32..271cd01d57a 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -331,12 +331,13 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
I. Upper bound for valid data: seq <= sender.td_maxend
II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
- III. Upper bound for valid ack: sack <= receiver.td_end
- IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW
+ III. Upper bound for valid (s)ack: sack <= receiver.td_end
+ IV. Lower bound for valid (s)ack: sack >= receiver.td_end - MAXACKWINDOW
- where sack is the highest right edge of sack block found in the packet.
+ where sack is the highest right edge of sack block found in the packet
+ or ack in the case of packet without SACK option.
- The upper bound limit for a valid ack is not ignored -
+ The upper bound limit for a valid (s)ack is not ignored -
we doesn't have to deal with fragments.
*/
@@ -606,12 +607,12 @@ static bool tcp_in_window(const struct nf_conn *ct,
before(seq, sender->td_maxend + 1),
after(end, sender->td_end - receiver->td_maxwin - 1),
before(sack, receiver->td_end + 1),
- after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+ after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
if (before(seq, sender->td_maxend + 1) &&
after(end, sender->td_end - receiver->td_maxwin - 1) &&
before(sack, receiver->td_end + 1) &&
- after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
+ after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
/*
* Take into account window scaling (RFC 1323).
*/
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 0099da5b259..52b2611a6eb 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1534,7 +1534,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
}
}
list_for_each_entry_rcu(addr6, &iface->addr6_list, list) {
- if (addr6->valid || iter_addr6++ < skip_addr6)
+ if (!addr6->valid || iter_addr6++ < skip_addr6)
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 9b97f8006c9..349aba18955 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -886,7 +886,7 @@ retry:
return netlink_unicast_kernel(sk, skb);
if (sk_filter(sk, skb)) {
- int err = skb->len;
+ err = skb->len;
kfree_skb(skb);
sock_put(sk);
return err;
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index 47bbf45ae5d..2d106cfe1d2 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -132,6 +132,7 @@ errout:
* @maxtype: maximum attribute type to be expected
* @head: head of attribute stream
* @len: length of attribute stream
+ * @policy: validation policy
*
* Parses a stream of attributes and stores a pointer to each attribute in
* the tb array accessable via the attribute type. Attributes with a type
@@ -194,7 +195,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
/**
* nla_strlcpy - Copy string attribute payload into a sized buffer
* @dst: where to copy the string to
- * @src: attribute to copy the string from
+ * @nla: attribute to copy the string from
* @dstsize: size of destination buffer
*
* Copies at most dstsize - 1 bytes into the destination buffer.
@@ -340,9 +341,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
}
/**
- * nla_reserve - reserve room for attribute without header
+ * nla_reserve_nohdr - reserve room for attribute without header
* @skb: socket buffer to reserve room on
- * @len: length of attribute payload
+ * @attrlen: length of attribute payload
*
* Reserves room for attribute payload without a header.
*
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 82adfe6447d..9437b27ff84 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -106,17 +106,6 @@ config NET_SCH_PRIO
To compile this code as a module, choose M here: the
module will be called sch_prio.
-config NET_SCH_RR
- tristate "Multi Band Round Robin Queuing (RR)"
- select NET_SCH_PRIO
- ---help---
- Say Y here if you want to use an n-band round robin packet
- scheduler.
-
- The module uses sch_prio for its framework and is aliased as
- sch_rr, so it will load sch_prio, although it is referred
- to using sch_rr.
-
config NET_SCH_RED
tristate "Random Early Detection (RED)"
---help---
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index c40773cdbe4..10f01ad0438 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1252,12 +1252,12 @@ void tcf_destroy(struct tcf_proto *tp)
kfree(tp);
}
-void tcf_destroy_chain(struct tcf_proto *fl)
+void tcf_destroy_chain(struct tcf_proto **fl)
{
struct tcf_proto *tp;
- while ((tp = fl) != NULL) {
- fl = tp->next;
+ while ((tp = *fl) != NULL) {
+ *fl = tp->next;
tcf_destroy(tp);
}
}
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 33527341638..db0e23ae85f 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -160,7 +160,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
*prev = flow->next;
pr_debug("atm_tc_put: qdisc %p\n", flow->q);
qdisc_destroy(flow->q);
- tcf_destroy_chain(flow->filter_list);
+ tcf_destroy_chain(&flow->filter_list);
if (flow->sock) {
pr_debug("atm_tc_put: f_count %d\n",
file_count(flow->sock->file));
@@ -586,10 +586,11 @@ static void atm_tc_destroy(struct Qdisc *sch)
struct atm_flow_data *flow;
pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
+ for (flow = p->flows; flow; flow = flow->next)
+ tcf_destroy_chain(&flow->filter_list);
+
/* races ? */
while ((flow = p->flows)) {
- tcf_destroy_chain(flow->filter_list);
- flow->filter_list = NULL;
if (flow->ref > 1)
printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow,
flow->ref);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 09969c1fbc0..2a3c97f7dc6 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1704,7 +1704,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
BUG_TRAP(!cl->filters);
- tcf_destroy_chain(cl->filter_list);
+ tcf_destroy_chain(&cl->filter_list);
qdisc_destroy(cl->q);
qdisc_put_rtab(cl->R_tab);
gen_kill_estimator(&cl->bstats, &cl->rate_est);
@@ -1728,10 +1728,8 @@ cbq_destroy(struct Qdisc* sch)
* be bound to classes which have been destroyed already. --TGR '04
*/
for (h = 0; h < 16; h++) {
- for (cl = q->classes[h]; cl; cl = cl->next) {
- tcf_destroy_chain(cl->filter_list);
- cl->filter_list = NULL;
- }
+ for (cl = q->classes[h]; cl; cl = cl->next)
+ tcf_destroy_chain(&cl->filter_list);
}
for (h = 0; h < 16; h++) {
struct cbq_class *next;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 64465bacbe7..c4c1317cd47 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -416,7 +416,7 @@ static void dsmark_destroy(struct Qdisc *sch)
pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
- tcf_destroy_chain(p->filter_list);
+ tcf_destroy_chain(&p->filter_list);
qdisc_destroy(p->q);
kfree(p->mask);
}
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index d355e5e47fe..13afa721439 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
return sch;
errout:
- return ERR_PTR(-err);
+ return ERR_PTR(err);
}
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index fdfaa3fcc16..e817aa00441 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1123,7 +1123,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
{
struct hfsc_sched *q = qdisc_priv(sch);
- tcf_destroy_chain(cl->filter_list);
+ tcf_destroy_chain(&cl->filter_list);
qdisc_destroy(cl->qdisc);
gen_kill_estimator(&cl->bstats, &cl->rate_est);
if (cl != &q->root)
@@ -1541,6 +1541,10 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
unsigned int i;
for (i = 0; i < HFSC_HSIZE; i++) {
+ list_for_each_entry(cl, &q->clhash[i], hlist)
+ tcf_destroy_chain(&cl->filter_list);
+ }
+ for (i = 0; i < HFSC_HSIZE; i++) {
list_for_each_entry_safe(cl, next, &q->clhash[i], hlist)
hfsc_destroy_class(sch, cl);
}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 6807c97985a..3fb58f428f7 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1238,7 +1238,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
qdisc_put_rtab(cl->rate);
qdisc_put_rtab(cl->ceil);
- tcf_destroy_chain(cl->filter_list);
+ tcf_destroy_chain(&cl->filter_list);
while (!list_empty(&cl->children))
htb_destroy_class(sch, list_entry(cl->children.next,
@@ -1267,7 +1267,7 @@ static void htb_destroy(struct Qdisc *sch)
and surprisingly it worked in 2.4. But it must precede it
because filter need its target class alive to be able to call
unbind_filter on it (without Oops). */
- tcf_destroy_chain(q->filter_list);
+ tcf_destroy_chain(&q->filter_list);
while (!list_empty(&q->root))
htb_destroy_class(sch, list_entry(q->root.next,
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 274b1ddb160..956c80ad596 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -104,7 +104,7 @@ static void ingress_destroy(struct Qdisc *sch)
{
struct ingress_qdisc_data *p = qdisc_priv(sch);
- tcf_destroy_chain(p->filter_list);
+ tcf_destroy_chain(&p->filter_list);
}
static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 4aa2b45dad0..5532f1031ab 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -219,7 +219,7 @@ prio_destroy(struct Qdisc* sch)
int prio;
struct prio_sched_data *q = qdisc_priv(sch);
- tcf_destroy_chain(q->filter_list);
+ tcf_destroy_chain(&q->filter_list);
for (prio=0; prio<q->bands; prio++)
qdisc_destroy(q->queues[prio]);
}
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index f0463d757a9..6a97afbfb95 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -520,7 +520,7 @@ static void sfq_destroy(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- tcf_destroy_chain(q->filter_list);
+ tcf_destroy_chain(&q->filter_list);
q->perturb_period = 0;
del_timer_sync(&q->perturb_timer);
}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 657835f227d..783317dacd3 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *);
static int unix_accept(struct socket *, struct socket *, int);
static int unix_getname(struct socket *, struct sockaddr *, int *, int);
static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
-static unsigned int unix_datagram_poll(struct file *, struct socket *,
- poll_table *);
+static unsigned int unix_dgram_poll(struct file *, struct socket *,
+ poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
static int unix_shutdown(struct socket *, int);
static int unix_stream_sendmsg(struct kiocb *, struct socket *,
@@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = {
.socketpair = unix_socketpair,
.accept = sock_no_accept,
.getname = unix_getname,
- .poll = unix_datagram_poll,
+ .poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = sock_no_listen,
.shutdown = unix_shutdown,
@@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = {
.socketpair = unix_socketpair,
.accept = unix_accept,
.getname = unix_getname,
- .poll = unix_datagram_poll,
+ .poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = unix_listen,
.shutdown = unix_shutdown,
@@ -1994,29 +1994,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
return mask;
}
-static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
- poll_table *wait)
+static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
+ poll_table *wait)
{
- struct sock *sk = sock->sk, *peer;
- unsigned int mask;
+ struct sock *sk = sock->sk, *other;
+ unsigned int mask, writable;
poll_wait(file, sk->sk_sleep, wait);
-
- peer = unix_peer_get(sk);
- if (peer) {
- if (peer != sk) {
- /*
- * Writability of a connected socket additionally
- * depends on the state of the receive queue of the
- * peer.
- */
- poll_wait(file, &unix_sk(peer)->peer_wait, wait);
- } else {
- sock_put(peer);
- peer = NULL;
- }
- }
-
mask = 0;
/* exceptional events? */
@@ -2042,14 +2026,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
}
/* writable? */
- if (unix_writable(sk) && !(peer && unix_recvq_full(peer)))
+ writable = unix_writable(sk);
+ if (writable) {
+ other = unix_peer_get(sk);
+ if (other) {
+ if (unix_peer(other) != sk) {
+ poll_wait(file, &unix_sk(other)->peer_wait,
+ wait);
+ if (unix_recvq_full(other))
+ writable = 0;
+ }
+
+ sock_put(other);
+ }
+ }
+
+ if (writable)
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
else
set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
- if (peer)
- sock_put(peer);
-
return mask;
}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 185488da246..855bff4b325 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -80,6 +80,23 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = {
IEEE80211_CHAN_RADAR),
};
+static const struct ieee80211_channel_range ieee80211_EU_channels[] = {
+ /* IEEE 802.11b/g, channels 1..13 */
+ RANGE_PWR(2412, 2472, 20, 6, 0),
+ /* IEEE 802.11a, channel 36*/
+ RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+ /* IEEE 802.11a, channel 40*/
+ RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+ /* IEEE 802.11a, channel 44*/
+ RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+ /* IEEE 802.11a, channels 48..64 */
+ RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_RADAR),
+ /* IEEE 802.11a, channels 100..140 */
+ RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_RADAR),
+};
+
#define REGDOM(_code) \
{ \
.code = __stringify(_code), \
@@ -90,6 +107,7 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = {
static const struct ieee80211_regdomain ieee80211_regdoms[] = {
REGDOM(US),
REGDOM(JP),
+ REGDOM(EU),
};
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index bc35d00a38f..1a426095014 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -41,7 +41,7 @@
#define DBG(x...)
#endif
-#if defined(CONFIG_ARCH_AT91SAM9260)
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
#define NUM_SSC_DEVICES 1
#else
#define NUM_SSC_DEVICES 3