aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci-devices-cciss7
-rw-r--r--Documentation/CodingStyle4
-rw-r--r--Documentation/DocBook/media/v4l/compat.xml3
-rw-r--r--Documentation/DocBook/media/v4l/controls.xml5
-rw-r--r--Documentation/DocBook/media/v4l/io.xml27
-rw-r--r--Documentation/DocBook/media/v4l/v4l2.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-create-bufs.xml139
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml88
-rw-r--r--Documentation/block/switching-sched.txt4
-rw-r--r--Documentation/blockdev/cciss.txt10
-rw-r--r--Documentation/cgroups/cgroups.txt4
-rw-r--r--Documentation/devicetree/bindings/ata/calxeda-sata.txt17
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/board.txt30
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt395
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt42
-rw-r--r--Documentation/filesystems/hfs.txt9
-rw-r--r--Documentation/filesystems/inotify.txt3
-rw-r--r--Documentation/hwmon/w83627ehf28
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt4
-rw-r--r--Documentation/leds/leds-class.txt4
-rw-r--r--Documentation/power/freezing-of-tasks.txt8
-rw-r--r--Documentation/power/runtime_pm.txt10
-rw-r--r--Documentation/serial/computone.txt2
-rw-r--r--Documentation/watchdog/convert_drivers_to_kernel_api.txt195
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/arm/Kconfig15
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/configs/exynos4_defconfig9
-rw-r--r--arch/arm/include/asm/hardware/pl080.h4
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-exynos/Kconfig (renamed from arch/arm/mach-exynos4/Kconfig)90
-rw-r--r--arch/arm/mach-exynos/Makefile (renamed from arch/arm/mach-exynos4/Makefile)13
-rw-r--r--arch/arm/mach-exynos/Makefile.boot (renamed from arch/arm/mach-exynos4/Makefile.boot)0
-rw-r--r--arch/arm/mach-exynos/clock-exynos4210.c (renamed from arch/arm/mach-exynos4/clock-exynos4210.c)0
-rw-r--r--arch/arm/mach-exynos/clock-exynos4212.c (renamed from arch/arm/mach-exynos4/clock-exynos4212.c)0
-rw-r--r--arch/arm/mach-exynos/clock.c (renamed from arch/arm/mach-exynos4/clock.c)215
-rw-r--r--arch/arm/mach-exynos/cpu.c (renamed from arch/arm/mach-exynos4/cpu.c)71
-rw-r--r--arch/arm/mach-exynos/cpuidle.c (renamed from arch/arm/mach-exynos4/cpuidle.c)0
-rw-r--r--arch/arm/mach-exynos/dev-ahci.c (renamed from arch/arm/mach-exynos4/dev-ahci.c)0
-rw-r--r--arch/arm/mach-exynos/dev-audio.c (renamed from arch/arm/mach-exynos4/dev-audio.c)0
-rw-r--r--arch/arm/mach-exynos/dev-dwmci.c (renamed from arch/arm/mach-exynos4/dev-dwmci.c)0
-rw-r--r--arch/arm/mach-exynos/dev-pd.c (renamed from arch/arm/mach-exynos4/dev-pd.c)0
-rw-r--r--arch/arm/mach-exynos/dev-sysmmu.c (renamed from arch/arm/mach-exynos4/dev-sysmmu.c)0
-rw-r--r--arch/arm/mach-exynos/dma.c250
-rw-r--r--arch/arm/mach-exynos/headsmp.S (renamed from arch/arm/mach-exynos4/headsmp.S)0
-rw-r--r--arch/arm/mach-exynos/hotplug.c (renamed from arch/arm/mach-exynos4/hotplug.c)0
-rw-r--r--arch/arm/mach-exynos/include/mach/debug-macro.S (renamed from arch/arm/mach-exynos4/include/mach/debug-macro.S)0
-rw-r--r--arch/arm/mach-exynos/include/mach/dma.h (renamed from arch/arm/mach-exynos4/include/mach/dma.h)4
-rw-r--r--arch/arm/mach-exynos/include/mach/dwmci.h (renamed from arch/arm/mach-exynos4/include/mach/dwmci.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/entry-macro.S (renamed from arch/arm/mach-exynos4/include/mach/entry-macro.S)0
-rw-r--r--arch/arm/mach-exynos/include/mach/exynos4-clock.h (renamed from arch/arm/mach-exynos4/include/mach/exynos4-clock.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio.h (renamed from arch/arm/mach-exynos4/include/mach/gpio.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/hardware.h (renamed from arch/arm/mach-exynos4/include/mach/hardware.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/io.h (renamed from arch/arm/mach-exynos4/include/mach/io.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h (renamed from arch/arm/mach-exynos4/include/mach/irqs.h)4
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h (renamed from arch/arm/mach-exynos4/include/mach/map.h)34
-rw-r--r--arch/arm/mach-exynos/include/mach/memory.h (renamed from arch/arm/mach-exynos4/include/mach/memory.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/pm-core.h (renamed from arch/arm/mach-exynos4/include/mach/pm-core.h)8
-rw-r--r--arch/arm/mach-exynos/include/mach/pmu.h (renamed from arch/arm/mach-exynos4/include/mach/pmu.h)7
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-audss.h (renamed from arch/arm/mach-exynos4/include/mach/regs-audss.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-clock.h (renamed from arch/arm/mach-exynos4/include/mach/regs-clock.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-gpio.h (renamed from arch/arm/mach-exynos4/include/mach/regs-gpio.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-irq.h (renamed from arch/arm/mach-exynos4/include/mach/regs-irq.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mct.h (renamed from arch/arm/mach-exynos4/include/mach/regs-mct.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mem.h (renamed from arch/arm/mach-exynos4/include/mach/regs-mem.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu.h (renamed from arch/arm/mach-exynos4/include/mach/regs-pmu.h)74
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-sysmmu.h (renamed from arch/arm/mach-exynos4/include/mach/regs-sysmmu.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-usb-phy.h (renamed from arch/arm/mach-exynos4/include/mach/regs-usb-phy.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/sysmmu.h (renamed from arch/arm/mach-exynos4/include/mach/sysmmu.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/system.h (renamed from arch/arm/mach-exynos4/include/mach/system.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/timex.h (renamed from arch/arm/mach-exynos4/include/mach/timex.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/uncompress.h (renamed from arch/arm/mach-exynos4/include/mach/uncompress.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/vmalloc.h (renamed from arch/arm/mach-exynos4/include/mach/vmalloc.h)0
-rw-r--r--arch/arm/mach-exynos/init.c (renamed from arch/arm/mach-exynos4/init.c)0
-rw-r--r--arch/arm/mach-exynos/irq-combiner.c (renamed from arch/arm/mach-exynos4/irq-combiner.c)0
-rw-r--r--arch/arm/mach-exynos/irq-eint.c (renamed from arch/arm/mach-exynos4/irq-eint.c)0
-rw-r--r--arch/arm/mach-exynos/mach-armlex4210.c (renamed from arch/arm/mach-exynos4/mach-armlex4210.c)0
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c (renamed from arch/arm/mach-exynos4/mach-nuri.c)192
-rw-r--r--arch/arm/mach-exynos/mach-origen.c700
-rw-r--r--arch/arm/mach-exynos/mach-smdk4x12.c (renamed from arch/arm/mach-exynos4/mach-smdk4x12.c)0
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c (renamed from arch/arm/mach-exynos4/mach-smdkv310.c)49
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c (renamed from arch/arm/mach-exynos4/mach-universal_c210.c)307
-rw-r--r--arch/arm/mach-exynos/mct.c (renamed from arch/arm/mach-exynos4/mct.c)40
-rw-r--r--arch/arm/mach-exynos/platsmp.c (renamed from arch/arm/mach-exynos4/platsmp.c)2
-rw-r--r--arch/arm/mach-exynos/pm.c (renamed from arch/arm/mach-exynos4/pm.c)7
-rw-r--r--arch/arm/mach-exynos/pmu.c230
-rw-r--r--arch/arm/mach-exynos/setup-fimc.c (renamed from arch/arm/mach-exynos4/setup-fimc.c)0
-rw-r--r--arch/arm/mach-exynos/setup-fimd0.c (renamed from arch/arm/mach-exynos4/setup-fimd0.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c0.c (renamed from arch/arm/mach-exynos4/setup-i2c0.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c1.c (renamed from arch/arm/mach-exynos4/setup-i2c1.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c2.c (renamed from arch/arm/mach-exynos4/setup-i2c2.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c3.c (renamed from arch/arm/mach-exynos4/setup-i2c3.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c4.c (renamed from arch/arm/mach-exynos4/setup-i2c4.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c5.c (renamed from arch/arm/mach-exynos4/setup-i2c5.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c6.c (renamed from arch/arm/mach-exynos4/setup-i2c6.c)0
-rw-r--r--arch/arm/mach-exynos/setup-i2c7.c (renamed from arch/arm/mach-exynos4/setup-i2c7.c)0
-rw-r--r--arch/arm/mach-exynos/setup-keypad.c (renamed from arch/arm/mach-exynos4/setup-keypad.c)0
-rw-r--r--arch/arm/mach-exynos/setup-sdhci-gpio.c (renamed from arch/arm/mach-exynos4/setup-sdhci-gpio.c)0
-rw-r--r--arch/arm/mach-exynos/setup-sdhci.c22
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c (renamed from arch/arm/mach-exynos4/setup-usb-phy.c)0
-rw-r--r--arch/arm/mach-exynos4/dma.c172
-rw-r--r--arch/arm/mach-exynos4/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-exynos4/mach-origen.c108
-rw-r--r--arch/arm/mach-exynos4/pmu.c175
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci.c69
-rw-r--r--arch/arm/mach-mmp/Makefile2
-rw-r--r--arch/arm/mach-mmp/brownstone.c11
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h13
-rw-r--r--arch/arm/mach-mmp/include/mach/sram.h35
-rw-r--r--arch/arm/mach-mmp/mmp2.c3
-rw-r--r--arch/arm/mach-mmp/sram.c168
-rw-r--r--arch/arm/mach-pxa/eseries.c2
-rw-r--r--arch/arm/mach-pxa/eseries.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio-pxa.h2
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c4
-rw-r--r--arch/arm/mach-s3c2410/Kconfig1
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h20
-rw-r--r--arch/arm/mach-s3c2410/include/mach/fb.h75
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-fns.h99
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-track.h6
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h1
-rw-r--r--arch/arm/mach-s3c2410/include/mach/pm-core.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c1
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c4
-rw-r--r--arch/arm/mach-s3c2412/dma.c4
-rw-r--r--arch/arm/mach-s3c2412/gpio.c62
-rw-r--r--arch/arm/mach-s3c2416/Kconfig1
-rw-r--r--arch/arm/mach-s3c2416/clock.c50
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c7
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci.c37
-rw-r--r--arch/arm/mach-s3c2440/Kconfig2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c1
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c4
-rw-r--r--arch/arm/mach-s3c2440/s3c2442.c4
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/clock.c160
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c7
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig1
-rw-r--r--arch/arm/mach-s3c64xx/Makefile5
-rw-r--r--arch/arm/mach-s3c64xx/clock.c13
-rw-r--r--arch/arm/mach-s3c64xx/cpu.c4
-rw-r--r--arch/arm/mach-s3c64xx/dev-onenand1.c53
-rw-r--r--arch/arm/mach-s3c64xx/dma.c12
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c290
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/crag6410.h23
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h8
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h45
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h2
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pwm-clock.h56
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-sys.h3
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c182
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c108
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/pm.c4
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c2
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c4
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci.c48
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig18
-rw-r--r--arch/arm/mach-s5p64x0/Makefile4
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c10
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c10
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c3
-rw-r--r--arch/arm/mach-s5p64x0/dma.c269
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/dma.h4
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h4
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/pm-core.h117
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/pwm-clock.h68
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-clock.h33
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-gpio.h21
-rw-r--r--arch/arm/mach-s5p64x0/irq-eint.c2
-rw-r--r--arch/arm/mach-s5p64x0/irq-pm.c92
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c74
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c75
-rw-r--r--arch/arm/mach-s5p64x0/pm.c204
-rw-r--r--arch/arm/mach-s5p64x0/setup-fb-24bpp.c29
-rw-r--r--arch/arm/mach-s5pc100/Kconfig2
-rw-r--r--arch/arm/mach-s5pc100/clock.c15
-rw-r--r--arch/arm/mach-s5pc100/dma.c324
-rw-r--r--arch/arm/mach-s5pc100/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-s5pc100/include/mach/dma.h4
-rw-r--r--arch/arm/mach-s5pc100/include/mach/pwm-clock.h56
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci.c42
-rw-r--r--arch/arm/mach-s5pv210/Kconfig6
-rw-r--r--arch/arm/mach-s5pv210/Makefile2
-rw-r--r--arch/arm/mach-s5pv210/clock.c151
-rw-r--r--arch/arm/mach-s5pv210/cpu.c4
-rw-r--r--arch/arm/mach-s5pv210/dma.c317
-rw-r--r--arch/arm/mach-s5pv210/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-s5pv210/include/mach/dma.h4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h13
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h2
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pwm-clock.h70
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h3
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c57
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci.c41
-rw-r--r--arch/arm/mach-s5pv210/sleep.S52
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c2
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c7
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c24xx/Makefile4
-rw-r--r--arch/arm/plat-s3c24xx/dev-uart.c100
-rw-r--r--arch/arm/plat-s3c24xx/devs.c528
-rw-r--r--arch/arm/plat-s3c24xx/dma.c10
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c96
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c229
-rw-r--r--arch/arm/plat-s3c24xx/include/mach/clkdev.h7
-rw-r--r--arch/arm/plat-s3c24xx/include/mach/pwm-clock.h55
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pll.h62
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-iis.h68
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-spi.h81
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c192
-rw-r--r--arch/arm/plat-s5p/Kconfig27
-rw-r--r--arch/arm/plat-s5p/Makefile14
-rw-r--r--arch/arm/plat-s5p/cpu.c6
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/dev-ehci.c57
-rw-r--r--arch/arm/plat-s5p/dev-fimc0.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc1.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc2.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc3.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimd0.c67
-rw-r--r--arch/arm/plat-s5p/dev-mfc.c50
-rw-r--r--arch/arm/plat-s5p/dev-onenand.c45
-rw-r--r--arch/arm/plat-s5p/dev-pmu.c36
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c10
-rw-r--r--arch/arm/plat-s5p/sleep.S (renamed from arch/arm/mach-exynos4/sleep.S)13
-rw-r--r--arch/arm/plat-samsung/Kconfig36
-rw-r--r--arch/arm/plat-samsung/Makefile37
-rw-r--r--arch/arm/plat-samsung/adc.c43
-rw-r--r--arch/arm/plat-samsung/dev-adc.c46
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c35
-rw-r--r--arch/arm/plat-samsung/dev-backlight.c1
-rw-r--r--arch/arm/plat-samsung/dev-fb.c63
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c62
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c62
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c63
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c66
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c32
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c70
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c61
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c62
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c60
-rw-r--r--arch/arm/plat-samsung/dev-ide.c44
-rw-r--r--arch/arm/plat-samsung/dev-keypad.c50
-rw-r--r--arch/arm/plat-samsung/dev-nand.c125
-rw-r--r--arch/arm/plat-samsung/dev-onenand.c43
-rw-r--r--arch/arm/plat-samsung/dev-pwm.c53
-rw-r--r--arch/arm/plat-samsung/dev-rtc.c43
-rw-r--r--arch/arm/plat-samsung/dev-ts.c59
-rw-r--r--arch/arm/plat-samsung/dev-usb-hsotg.c48
-rw-r--r--arch/arm/plat-samsung/dev-usb.c65
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c40
-rw-r--r--arch/arm/plat-samsung/devs.c1463
-rw-r--r--arch/arm/plat-samsung/dma-ops.c131
-rw-r--r--arch/arm/plat-samsung/gpio-config.c431
-rw-r--r--arch/arm/plat-samsung/gpio.c167
-rw-r--r--arch/arm/plat-samsung/include/plat/adc-core.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/audio-simtec.h (renamed from arch/arm/plat-s3c24xx/include/plat/audio-simtec.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/camport.h (renamed from arch/arm/plat-s5p/include/plat/camport.h)6
-rw-r--r--arch/arm/plat-samsung/include/plat/common-smdk.h (renamed from arch/arm/plat-s3c24xx/include/plat/common-smdk.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq-core.h (renamed from arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h)5
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h151
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h63
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h (renamed from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h)24
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-s3c24xx.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/ehci.h (renamed from arch/arm/plat-s5p/include/plat/ehci.h)6
-rw-r--r--arch/arm/plat-samsung/include/plat/exynos4.h (renamed from arch/arm/plat-s5p/include/plat/exynos4.h)8
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-s3c2410.h72
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/fiq.h (renamed from arch/arm/plat-s3c24xx/include/plat/fiq.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h172
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h34
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h97
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-fns.h98
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/irq.h (renamed from arch/arm/plat-s3c24xx/include/plat/irq.h)25
-rw-r--r--arch/arm/plat-samsung/include/plat/irqs.h (renamed from arch/arm/plat-s5p/include/plat/irqs.h)8
-rw-r--r--arch/arm/plat-samsung/include/plat/mci.h (renamed from arch/arm/plat-s3c24xx/include/plat/mci.h)10
-rw-r--r--arch/arm/plat-samsung/include/plat/mfc.h (renamed from arch/arm/plat-s5p/include/plat/mfc.h)6
-rw-r--r--arch/arm/plat-samsung/include/plat/mipi_csis.h (renamed from arch/arm/plat-s5p/include/plat/mipi_csis.h)6
-rw-r--r--arch/arm/plat-samsung/include/plat/pll.h (renamed from arch/arm/plat-s5p/include/plat/pll.h)134
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/pwm-clock.h (renamed from arch/arm/mach-exynos4/include/mach/pwm-clock.h)39
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-dma.h (renamed from arch/arm/plat-s3c24xx/include/plat/regs-dma.h)112
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-iis.h70
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-spi.h48
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-srom.h (renamed from arch/arm/plat-s5p/include/plat/regs-srom.h)8
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-udc.h (renamed from arch/arm/plat-s3c24xx/include/plat/regs-udc.h)132
-rw-r--r--arch/arm/plat-samsung/include/plat/reset.h (renamed from arch/arm/plat-s5p/include/plat/reset.h)8
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h32
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c2410.h (renamed from arch/arm/plat-s3c24xx/include/plat/s3c2410.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c2412.h (renamed from arch/arm/plat-s3c24xx/include/plat/s3c2412.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c2416.h (renamed from arch/arm/plat-s3c24xx/include/plat/s3c2416.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c2443.h (renamed from arch/arm/plat-s3c24xx/include/plat/s3c2443.h)9
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c244x.h (renamed from arch/arm/plat-s3c24xx/include/plat/s3c244x.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c6400.h (renamed from arch/arm/mach-s3c64xx/include/mach/s3c6400.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c6410.h (renamed from arch/arm/mach-s3c64xx/include/mach/s3c6410.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p-clock.h (renamed from arch/arm/plat-s5p/include/plat/s5p-clock.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p-time.h (renamed from arch/arm/plat-s5p/include/plat/s5p-time.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p6440.h (renamed from arch/arm/plat-s5p/include/plat/s5p6440.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p6450.h (renamed from arch/arm/plat-s5p/include/plat/s5p6450.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5pc100.h (renamed from arch/arm/plat-s5p/include/plat/s5pc100.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/s5pv210.h (renamed from arch/arm/plat-s5p/include/plat/s5pv210.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h57
-rw-r--r--arch/arm/plat-samsung/include/plat/sysmmu.h (renamed from arch/arm/plat-s5p/include/plat/sysmmu.h)6
-rw-r--r--arch/arm/plat-samsung/include/plat/system-reset.h (renamed from arch/arm/plat-s5p/include/plat/system-reset.h)2
-rw-r--r--arch/arm/plat-samsung/include/plat/tv-core.h44
-rw-r--r--arch/arm/plat-samsung/include/plat/udc.h (renamed from arch/arm/plat-s3c24xx/include/plat/udc.h)4
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-phy.h (renamed from arch/arm/plat-s5p/include/plat/usb-phy.h)6
-rw-r--r--arch/arm/plat-samsung/platformdata.c2
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c72
-rw-r--r--arch/arm/plat-samsung/pm.c6
-rw-r--r--arch/arm/plat-samsung/pwm-clock.c13
-rw-r--r--arch/arm/plat-samsung/pwm.c7
-rw-r--r--arch/arm/plat-samsung/s3c-dma-ops.c130
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c1244
-rw-r--r--arch/ia64/include/asm/unistd.h4
-rw-r--r--arch/ia64/kernel/entry.S2
-rw-r--r--arch/m68k/emu/nfblock.c3
-rw-r--r--arch/powerpc/Kconfig7
-rw-r--r--arch/powerpc/Kconfig.debug46
-rw-r--r--arch/powerpc/boot/Makefile3
-rw-r--r--arch/powerpc/boot/dts/digsy_mtc.dts59
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts33
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts33
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts33
-rw-r--r--arch/powerpc/boot/dts/hcu4.dts168
-rw-r--r--arch/powerpc/boot/dts/ksi8560.dts2
-rw-r--r--arch/powerpc/boot/dts/mgcoge.dts9
-rw-r--r--arch/powerpc/boot/dts/mpc5200b.dtsi2
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts3
-rw-r--r--arch/powerpc/boot/dts/p1022ds.dts2
-rw-r--r--arch/powerpc/boot/dts/p2020ds.dts5
-rw-r--r--arch/powerpc/boot/dts/p2041rdb.dts (renamed from arch/powerpc/boot/dts/p2040rdb.dts)17
-rw-r--r--arch/powerpc/boot/dts/p2041si.dtsi (renamed from arch/powerpc/boot/dts/p2040si.dtsi)135
-rw-r--r--arch/powerpc/boot/dts/p3041ds.dts8
-rw-r--r--arch/powerpc/boot/dts/p3041si.dtsi71
-rw-r--r--arch/powerpc/boot/dts/p3060qds.dts238
-rw-r--r--arch/powerpc/boot/dts/p3060si.dtsi719
-rw-r--r--arch/powerpc/boot/dts/p4080ds.dts12
-rw-r--r--arch/powerpc/boot/dts/p4080si.dtsi114
-rw-r--r--arch/powerpc/boot/dts/p5020ds.dts8
-rw-r--r--arch/powerpc/boot/dts/p5020si.dtsi68
-rw-r--r--arch/powerpc/boot/dts/sbc8560.dts2
-rw-r--r--arch/powerpc/boot/dts/yosemite.dts36
-rw-r--r--arch/powerpc/configs/40x/hcu4_defconfig81
-rw-r--r--arch/powerpc/configs/85xx/p1023rds_defconfig2
-rw-r--r--arch/powerpc/configs/85xx/xes_mpc85xx_defconfig2
-rw-r--r--arch/powerpc/configs/corenet32_smp_defconfig11
-rw-r--r--arch/powerpc/configs/corenet64_smp_defconfig5
-rw-r--r--arch/powerpc/configs/mgcoge_defconfig27
-rw-r--r--arch/powerpc/configs/mpc512x_defconfig19
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig12
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig5
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig6
-rw-r--r--arch/powerpc/configs/ppc40x_defconfig1
-rw-r--r--arch/powerpc/configs/ppc6xx_defconfig2
-rw-r--r--arch/powerpc/include/asm/device.h2
-rw-r--r--arch/powerpc/include/asm/firmware.h10
-rw-r--r--arch/powerpc/include/asm/hugetlb.h63
-rw-r--r--arch/powerpc/include/asm/kexec.h2
-rw-r--r--arch/powerpc/include/asm/machdep.h3
-rw-r--r--arch/powerpc/include/asm/mmu-book3e.h7
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h3
-rw-r--r--arch/powerpc/include/asm/mmu.h18
-rw-r--r--arch/powerpc/include/asm/mpic.h2
-rw-r--r--arch/powerpc/include/asm/opal.h443
-rw-r--r--arch/powerpc/include/asm/paca.h8
-rw-r--r--arch/powerpc/include/asm/page.h31
-rw-r--r--arch/powerpc/include/asm/page_64.h11
-rw-r--r--arch/powerpc/include/asm/pte-book3e.h3
-rw-r--r--arch/powerpc/include/asm/reg_booke.h3
-rw-r--r--arch/powerpc/include/asm/rtas.h6
-rw-r--r--arch/powerpc/include/asm/smp.h1
-rw-r--r--arch/powerpc/include/asm/sparsemem.h2
-rw-r--r--arch/powerpc/include/asm/topology.h14
-rw-r--r--arch/powerpc/include/asm/udbg.h3
-rw-r--r--arch/powerpc/include/asm/xics.h19
-rw-r--r--arch/powerpc/kernel/asm-offsets.c10
-rw-r--r--arch/powerpc/kernel/dma-iommu.c28
-rw-r--r--arch/powerpc/kernel/dma-swiotlb.c16
-rw-r--r--arch/powerpc/kernel/dma.c44
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S27
-rw-r--r--arch/powerpc/kernel/head_32.S7
-rw-r--r--arch/powerpc/kernel/head_40x.S15
-rw-r--r--arch/powerpc/kernel/head_44x.S16
-rw-r--r--arch/powerpc/kernel/head_64.S22
-rw-r--r--arch/powerpc/kernel/head_8xx.S13
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S175
-rw-r--r--arch/powerpc/kernel/ibmebus.c22
-rw-r--r--arch/powerpc/kernel/idle_e500.S2
-rw-r--r--arch/powerpc/kernel/iommu.c8
-rw-r--r--arch/powerpc/kernel/legacy_serial.c25
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c3
-rw-r--r--arch/powerpc/kernel/misc_32.S171
-rw-r--r--arch/powerpc/kernel/pci-common.c11
-rw-r--r--arch/powerpc/kernel/power6-pmu.c4
-rw-r--r--arch/powerpc/kernel/power7-pmu.c2
-rw-r--r--arch/powerpc/kernel/prom.c19
-rw-r--r--arch/powerpc/kernel/prom_init.c383
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh4
-rw-r--r--arch/powerpc/kernel/ptrace.c18
-rw-r--r--arch/powerpc/kernel/setup_32.c2
-rw-r--r--arch/powerpc/kernel/setup_64.c22
-rw-r--r--arch/powerpc/kernel/smp.c30
-rw-r--r--arch/powerpc/kernel/swsusp.c2
-rw-r--r--arch/powerpc/kernel/traps.c9
-rw-r--r--arch/powerpc/kernel/udbg.c6
-rw-r--r--arch/powerpc/kernel/vio.c21
-rw-r--r--arch/powerpc/math-emu/math_efp.c100
-rw-r--r--arch/powerpc/mm/Makefile1
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c43
-rw-r--r--arch/powerpc/mm/hash_utils_64.c9
-rw-r--r--arch/powerpc/mm/hugetlbpage-book3e.c121
-rw-r--r--arch/powerpc/mm/hugetlbpage.c379
-rw-r--r--arch/powerpc/mm/init_32.c9
-rw-r--r--arch/powerpc/mm/mem.c8
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c12
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c5
-rw-r--r--arch/powerpc/mm/mmu_decl.h2
-rw-r--r--arch/powerpc/mm/numa.c20
-rw-r--r--arch/powerpc/mm/pgtable.c3
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S24
-rw-r--r--arch/powerpc/mm/tlb_nohash.c67
-rw-r--r--arch/powerpc/platforms/40x/Kconfig8
-rw-r--r--arch/powerpc/platforms/40x/Makefile1
-rw-r--r--arch/powerpc/platforms/40x/hcu4.c61
-rw-r--r--arch/powerpc/platforms/512x/Kconfig1
-rw-r--r--arch/powerpc/platforms/82xx/km82xx.c4
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig9
-rw-r--r--arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c58
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig30
-rw-r--r--arch/powerpc/platforms/85xx/Makefile3
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c11
-rw-r--r--arch/powerpc/platforms/85xx/p2041_rdb.c (renamed from arch/powerpc/platforms/85xx/p2040_rdb.c)18
-rw-r--r--arch/powerpc/platforms/85xx/p3060_qds.c77
-rw-r--r--arch/powerpc/platforms/85xx/sbc8560.c2
-rw-r--r--arch/powerpc/platforms/85xx/smp.c12
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/Kconfig13
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype4
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c21
-rw-r--r--arch/powerpc/platforms/powernv/Kconfig16
-rw-r--r--arch/powerpc/platforms/powernv/Makefile5
-rw-r--r--arch/powerpc/platforms/powernv/opal-nvram.c88
-rw-r--r--arch/powerpc/platforms/powernv/opal-rtc.c97
-rw-r--r--arch/powerpc/platforms/powernv/opal-takeover.S140
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S101
-rw-r--r--arch/powerpc/platforms/powernv/opal.c322
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c234
-rw-r--r--arch/powerpc/platforms/powernv/pci.c427
-rw-r--r--arch/powerpc/platforms/powernv/pci.h48
-rw-r--r--arch/powerpc/platforms/powernv/powernv.h16
-rw-r--r--arch/powerpc/platforms/powernv/setup.c196
-rw-r--r--arch/powerpc/platforms/powernv/smp.c182
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig12
-rw-r--r--arch/powerpc/platforms/ps3/Makefile1
-rw-r--r--arch/powerpc/platforms/ps3/gelic_udbg.c273
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c7
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig1
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c34
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c171
-rw-r--r--arch/powerpc/platforms/wsp/Kconfig11
-rw-r--r--arch/powerpc/platforms/wsp/Makefile2
-rw-r--r--arch/powerpc/platforms/wsp/ics.c48
-rw-r--r--arch/powerpc/platforms/wsp/ics.h5
-rw-r--r--arch/powerpc/platforms/wsp/msi.c102
-rw-r--r--arch/powerpc/platforms/wsp/msi.h19
-rw-r--r--arch/powerpc/platforms/wsp/psr2.c4
-rw-r--r--arch/powerpc/platforms/wsp/wsp.h3
-rw-r--r--arch/powerpc/platforms/wsp/wsp_pci.c1133
-rw-r--r--arch/powerpc/platforms/wsp/wsp_pci.h268
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/axonram.c8
-rw-r--r--arch/powerpc/sysdev/cpm_common.c3
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c28
-rw-r--r--arch/powerpc/sysdev/fsl_msi.h3
-rw-r--r--arch/powerpc/sysdev/mpic.c34
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c101
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.h12
-rw-r--r--arch/powerpc/sysdev/xics/Makefile1
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c2
-rw-r--r--arch/powerpc/sysdev/xics/ics-opal.c244
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c8
-rw-r--r--arch/powerpc/xmon/xmon.c4
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c10
-rw-r--r--arch/sh/boards/mach-migor/setup.c4
-rw-r--r--arch/tile/include/arch/Kbuild17
-rw-r--r--arch/tile/include/arch/abi.h99
-rw-r--r--arch/tile/include/arch/opcode.h (renamed from arch/tile/include/asm/opcode_constants.h)17
-rw-r--r--arch/tile/include/arch/opcode_tilegx.h (renamed from arch/tile/include/asm/opcode_constants_64.h)806
-rw-r--r--arch/tile/include/arch/opcode_tilepro.h1471
-rw-r--r--arch/tile/include/asm/Kbuild2
-rw-r--r--arch/tile/include/asm/opcode-tile_32.h1513
-rw-r--r--arch/tile/include/asm/opcode-tile_64.h1248
-rw-r--r--arch/tile/include/asm/opcode_constants_32.h480
-rw-r--r--arch/tile/include/asm/sigcontext.h18
-rw-r--r--arch/tile/include/asm/tile-desc.h (renamed from arch/tile/include/asm/opcode-tile.h)19
-rw-r--r--arch/tile/include/asm/tile-desc_32.h553
-rw-r--r--arch/tile/include/asm/tile-desc_64.h483
-rw-r--r--arch/tile/kernel/backtrace.c19
-rw-r--r--arch/tile/kernel/module.c2
-rw-r--r--arch/tile/kernel/single_step.c9
-rw-r--r--arch/tile/kernel/tile-desc_32.c2242
-rw-r--r--arch/tile/kernel/tile-desc_64.c28
-rw-r--r--arch/tile/kernel/traps.c5
-rw-r--r--arch/tile/lib/exports.c2
-rw-r--r--block/blk-cgroup.c111
-rw-r--r--block/blk-cgroup.h2
-rw-r--r--block/blk-core.c461
-rw-r--r--block/blk-flush.c3
-rw-r--r--block/blk-sysfs.c7
-rw-r--r--block/blk-tag.c6
-rw-r--r--block/blk-throttle.c106
-rw-r--r--block/blk.h20
-rw-r--r--block/elevator.c39
-rw-r--r--block/genhd.c12
-rw-r--r--block/ioctl.c2
-rw-r--r--block/scsi_ioctl.c3
-rw-r--r--drivers/acpi/sleep.c8
-rw-r--r--drivers/ata/ahci_platform.c7
-rw-r--r--drivers/base/power/runtime.c23
-rw-r--r--drivers/block/aoe/aoeblk.c14
-rw-r--r--drivers/block/brd.c4
-rw-r--r--drivers/block/cciss.c76
-rw-r--r--drivers/block/cciss.h1
-rw-r--r--drivers/block/cpqarray.c2
-rw-r--r--drivers/block/drbd/drbd_int.h2
-rw-r--r--drivers/block/drbd/drbd_req.c8
-rw-r--r--drivers/block/loop.c251
-rw-r--r--drivers/block/nbd.c69
-rw-r--r--drivers/block/pktcdvd.c11
-rw-r--r--drivers/block/ps3vram.c6
-rw-r--r--drivers/block/umem.c4
-rw-r--r--drivers/block/xen-blkback/blkback.c130
-rw-r--r--drivers/block/xen-blkback/common.h98
-rw-r--r--drivers/block/xen-blkback/xenbus.c76
-rw-r--r--drivers/block/xen-blkfront.c123
-rw-r--r--drivers/dma/Kconfig3
-rw-r--r--drivers/dma/amba-pl08x.c640
-rw-r--r--drivers/dma/at_hdmac.c164
-rw-r--r--drivers/dma/at_hdmac_regs.h24
-rw-r--r--drivers/dma/dmatest.c23
-rw-r--r--drivers/dma/dw_dmac.c5
-rw-r--r--drivers/dma/ep93xx_dma.c1
-rw-r--r--drivers/dma/imx-dma.c1
-rw-r--r--drivers/dma/imx-sdma.c48
-rw-r--r--drivers/dma/intel_mid_dma.c9
-rw-r--r--drivers/dma/ipu/ipu_idmac.c65
-rw-r--r--drivers/dma/mpc512x_dma.c1
-rw-r--r--drivers/dma/mxs-dma.c45
-rw-r--r--drivers/dma/pch_dma.c7
-rw-r--r--drivers/dma/pl330.c231
-rw-r--r--drivers/dma/shdma.c129
-rw-r--r--drivers/dma/shdma.h7
-rw-r--r--drivers/dma/timb_dma.c5
-rw-r--r--drivers/edac/cpc925_edac.c67
-rw-r--r--drivers/edac/ppc4xx_edac.c2
-rw-r--r--drivers/firmware/edd.c6
-rw-r--r--drivers/gpio/Kconfig24
-rw-r--r--drivers/gpio/Makefile7
-rw-r--r--drivers/gpio/gpio-exynos4.c385
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c (renamed from arch/powerpc/sysdev/mpc8xxx_gpio.c)3
-rw-r--r--drivers/gpio/gpio-plat-samsung.c205
-rw-r--r--drivers/gpio/gpio-s5pc100.c354
-rw-r--r--drivers/gpio/gpio-s5pv210.c287
-rw-r--r--drivers/gpio/gpio-samsung.c2712
-rw-r--r--drivers/hwmon/Kconfig20
-rw-r--r--drivers/hwmon/ad7414.c7
-rw-r--r--drivers/hwmon/ad7418.c27
-rw-r--r--drivers/hwmon/ads1015.c21
-rw-r--r--drivers/hwmon/ads7828.c12
-rw-r--r--drivers/hwmon/asb100.c10
-rw-r--r--drivers/hwmon/coretemp.c3
-rw-r--r--drivers/hwmon/ds1621.c24
-rw-r--r--drivers/hwmon/ds620.c42
-rw-r--r--drivers/hwmon/gl518sm.c4
-rw-r--r--drivers/hwmon/gl520sm.c4
-rw-r--r--drivers/hwmon/ibmaem.c60
-rw-r--r--drivers/hwmon/jc42.c52
-rw-r--r--drivers/hwmon/lm73.c30
-rw-r--r--drivers/hwmon/lm75.c9
-rw-r--r--drivers/hwmon/lm77.c4
-rw-r--r--drivers/hwmon/lm90.c146
-rw-r--r--drivers/hwmon/lm92.c26
-rw-r--r--drivers/hwmon/max16065.c4
-rw-r--r--drivers/hwmon/sht21.c26
-rw-r--r--drivers/hwmon/smm665.c15
-rw-r--r--drivers/hwmon/smsc47b397.c13
-rw-r--r--drivers/hwmon/tmp102.c44
-rw-r--r--drivers/hwmon/w83627ehf.c213
-rw-r--r--drivers/hwmon/w83781d.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c10
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c11
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h4
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c31
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c33
-rw-r--r--drivers/md/dm.c25
-rw-r--r--drivers/md/faulty.c14
-rw-r--r--drivers/md/linear.c17
-rw-r--r--drivers/md/md.c12
-rw-r--r--drivers/md/md.h2
-rw-r--r--drivers/md/multipath.c8
-rw-r--r--drivers/md/raid0.c22
-rw-r--r--drivers/md/raid1.c9
-rw-r--r--drivers/md/raid10.c19
-rw-r--r--drivers/md/raid5.c8
-rw-r--r--drivers/media/dvb/ddbridge/Makefile2
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c105
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf-demod.c614
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf-demod.h55
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.c228
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.h2
-rw-r--r--drivers/media/dvb/ngene/Makefile2
-rw-r--r--drivers/media/radio/radio-tea5764.c4
-rw-r--r--drivers/media/video/Kconfig9
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/atmel-isi.c142
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx25821/Kconfig (renamed from drivers/staging/cx25821/Kconfig)0
-rw-r--r--drivers/media/video/cx25821/Makefile (renamed from drivers/staging/cx25821/Makefile)0
-rw-r--r--drivers/media/video/cx25821/cx25821-alsa.c (renamed from drivers/staging/cx25821/cx25821-alsa.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.c (renamed from drivers/staging/cx25821/cx25821-audio-upstream.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.h (renamed from drivers/staging/cx25821/cx25821-audio-upstream.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio.h (renamed from drivers/staging/cx25821/cx25821-audio.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-biffuncs.h (renamed from drivers/staging/cx25821/cx25821-biffuncs.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-cards.c (renamed from drivers/staging/cx25821/cx25821-cards.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-core.c (renamed from drivers/staging/cx25821/cx25821-core.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-gpio.c (renamed from drivers/staging/cx25821/cx25821-gpio.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-i2c.c (renamed from drivers/staging/cx25821/cx25821-i2c.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-defines.h (renamed from drivers/staging/cx25821/cx25821-medusa-defines.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-reg.h (renamed from drivers/staging/cx25821/cx25821-medusa-reg.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.c (renamed from drivers/staging/cx25821/cx25821-medusa-video.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.h (renamed from drivers/staging/cx25821/cx25821-medusa-video.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-reg.h (renamed from drivers/staging/cx25821/cx25821-reg.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-sram.h (renamed from drivers/staging/cx25821/cx25821-sram.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.c (renamed from drivers/staging/cx25821/cx25821-video-upstream-ch2.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.h (renamed from drivers/staging/cx25821/cx25821-video-upstream-ch2.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.c (renamed from drivers/staging/cx25821/cx25821-video-upstream.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.h (renamed from drivers/staging/cx25821/cx25821-video-upstream.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video.c (renamed from drivers/staging/cx25821/cx25821-video.c)2
-rw-r--r--drivers/media/video/cx25821/cx25821-video.h (renamed from drivers/staging/cx25821/cx25821-video.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821.h (renamed from drivers/staging/cx25821/cx25821.h)3
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c2
-rw-r--r--drivers/media/video/imx074.c54
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c3
-rw-r--r--drivers/media/video/mem2mem_testdev.c7
-rw-r--r--drivers/media/video/mt9m001.c328
-rw-r--r--drivers/media/video/mt9m111.c260
-rw-r--r--drivers/media/video/mt9t031.c347
-rw-r--r--drivers/media/video/mt9t112.c269
-rw-r--r--drivers/media/video/mt9v022.c447
-rw-r--r--drivers/media/video/mx1_camera.c71
-rw-r--r--drivers/media/video/mx2_camera.c78
-rw-r--r--drivers/media/video/mx3_camera.c359
-rw-r--r--drivers/media/video/omap/omap_vout.c10
-rw-r--r--drivers/media/video/omap1_camera.c62
-rw-r--r--drivers/media/video/omap3isp/isp.c3
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c86
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c125
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c91
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c2
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c2
-rw-r--r--drivers/media/video/omap3isp/isphist.c2
-rw-r--r--drivers/media/video/omap3isp/isppreview.c419
-rw-r--r--drivers/media/video/omap3isp/isppreview.h9
-rw-r--r--drivers/media/video/omap3isp/ispreg.h3
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c104
-rw-r--r--drivers/media/video/omap3isp/ispstat.c52
-rw-r--r--drivers/media/video/omap3isp/ispstat.h2
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c11
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h1
-rw-r--r--drivers/media/video/ov2640.c178
-rw-r--r--drivers/media/video/ov5642.c288
-rw-r--r--drivers/media/video/ov6650.c504
-rw-r--r--drivers/media/video/ov772x.c198
-rw-r--r--drivers/media/video/ov9640.c186
-rw-r--r--drivers/media/video/ov9640.h4
-rw-r--r--drivers/media/video/ov9740.c151
-rw-r--r--drivers/media/video/pwc/pwc-if.c6
-rw-r--r--drivers/media/video/pxa_camera.c140
-rw-r--r--drivers/media/video/rj54n1cb0c.c223
-rw-r--r--drivers/media/video/s5k6aa.c1680
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c6
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c6
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c4
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.c7
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.c5
-rw-r--r--drivers/media/video/s5p-tv/mixer_video.c4
-rw-r--r--drivers/media/video/saa7134/saa7134.h12
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c491
-rw-r--r--drivers/media/video/sh_mobile_csi2.c132
-rw-r--r--drivers/media/video/soc_camera.c273
-rw-r--r--drivers/media/video/soc_camera_platform.c45
-rw-r--r--drivers/media/video/soc_mediabus.c33
-rw-r--r--drivers/media/video/tw9910.c268
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c76
-rw-r--r--drivers/media/video/v4l2-ctrls.c1
-rw-r--r--drivers/media/video/v4l2-device.c36
-rw-r--r--drivers/media/video/v4l2-ioctl.c36
-rw-r--r--drivers/media/video/videobuf2-core.c391
-rw-r--r--drivers/media/video/vivi.c6
-rw-r--r--drivers/mmc/host/s3cmci.c6
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_net.c3
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_net.h6
-rw-r--r--drivers/of/fdt.c7
-rw-r--r--drivers/of/platform.c28
-rw-r--r--drivers/pcmcia/pxa2xx_base.c1
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x2xx.c3
-rw-r--r--drivers/s390/block/dcssblk.c7
-rw-r--r--drivers/s390/block/xpram.c5
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h5
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_els.c23
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c2
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c37
-rw-r--r--drivers/scsi/device_handler/scsi_dh.c10
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c3
-rw-r--r--drivers/scsi/fcoe/fcoe.c13
-rw-r--r--drivers/scsi/hosts.c9
-rw-r--r--drivers/scsi/hpsa.c228
-rw-r--r--drivers/scsi/hpsa.h10
-rw-r--r--drivers/scsi/hpsa_cmd.h5
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/ipr.h1
-rw-r--r--drivers/scsi/isci/host.c23
-rw-r--r--drivers/scsi/isci/init.c2
-rw-r--r--drivers/scsi/isci/port.c146
-rw-r--r--drivers/scsi/isci/port.h6
-rw-r--r--drivers/scsi/isci/probe_roms.h4
-rw-r--r--drivers/scsi/isci/remote_device.c85
-rw-r--r--drivers/scsi/isci/remote_device.h5
-rw-r--r--drivers/scsi/isci/request.c52
-rw-r--r--drivers/scsi/isci/request.h6
-rw-r--r--drivers/scsi/isci/task.c698
-rw-r--r--drivers/scsi/isci/task.h35
-rw-r--r--drivers/scsi/libfc/fc_exch.c7
-rw-r--r--drivers/scsi/libfc/fc_lport.c100
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h11
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h153
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h113
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c247
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h32
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c67
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c9
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c634
-rw-r--r--drivers/scsi/mvsas/mv_init.c10
-rw-r--r--drivers/scsi/pmcraid.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c2
-rw-r--r--drivers/scsi/scsi_lib.c9
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c2
-rw-r--r--drivers/scsi/sd.c12
-rw-r--r--drivers/scsi/sd.h6
-rw-r--r--drivers/scsi/st.c4
-rw-r--r--drivers/spi/spi-s3c64xx.c175
-rw-r--r--drivers/staging/Kconfig16
-rw-r--r--drivers/staging/Makefile8
-rw-r--r--drivers/staging/cx25821/README6
-rw-r--r--drivers/staging/media/Kconfig37
-rw-r--r--drivers/staging/media/Makefile7
-rw-r--r--drivers/staging/media/as102/Kconfig7
-rw-r--r--drivers/staging/media/as102/Makefile6
-rw-r--r--drivers/staging/media/as102/as102_drv.c351
-rw-r--r--drivers/staging/media/as102/as102_drv.h141
-rw-r--r--drivers/staging/media/as102/as102_fe.c603
-rw-r--r--drivers/staging/media/as102/as102_fw.c251
-rw-r--r--drivers/staging/media/as102/as102_fw.h42
-rw-r--r--drivers/staging/media/as102/as102_usb_drv.c478
-rw-r--r--drivers/staging/media/as102/as102_usb_drv.h59
-rw-r--r--drivers/staging/media/as102/as10x_cmd.c452
-rw-r--r--drivers/staging/media/as102/as10x_cmd.h540
-rw-r--r--drivers/staging/media/as102/as10x_cmd_cfg.c215
-rw-r--r--drivers/staging/media/as102/as10x_cmd_stream.c223
-rw-r--r--drivers/staging/media/as102/as10x_handle.h58
-rw-r--r--drivers/staging/media/as102/as10x_types.h198
-rw-r--r--drivers/staging/media/cxd2099/Kconfig (renamed from drivers/staging/cxd2099/Kconfig)0
-rw-r--r--drivers/staging/media/cxd2099/Makefile (renamed from drivers/staging/cxd2099/Makefile)0
-rw-r--r--drivers/staging/media/cxd2099/TODO (renamed from drivers/staging/cxd2099/TODO)0
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c (renamed from drivers/staging/cxd2099/cxd2099.c)0
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.h (renamed from drivers/staging/cxd2099/cxd2099.h)0
-rw-r--r--drivers/staging/media/dt3155v4l/Kconfig (renamed from drivers/staging/dt3155v4l/Kconfig)0
-rw-r--r--drivers/staging/media/dt3155v4l/Makefile (renamed from drivers/staging/dt3155v4l/Makefile)0
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c (renamed from drivers/staging/dt3155v4l/dt3155v4l.c)0
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.h (renamed from drivers/staging/dt3155v4l/dt3155v4l.h)0
-rw-r--r--drivers/staging/media/easycap/Kconfig (renamed from drivers/staging/easycap/Kconfig)0
-rw-r--r--drivers/staging/media/easycap/Makefile (renamed from drivers/staging/easycap/Makefile)0
-rw-r--r--drivers/staging/media/easycap/README (renamed from drivers/staging/easycap/README)0
-rw-r--r--drivers/staging/media/easycap/easycap.h (renamed from drivers/staging/easycap/easycap.h)0
-rw-r--r--drivers/staging/media/easycap/easycap_ioctl.c (renamed from drivers/staging/easycap/easycap_ioctl.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_low.c (renamed from drivers/staging/easycap/easycap_low.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_main.c (renamed from drivers/staging/easycap/easycap_main.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_settings.c (renamed from drivers/staging/easycap/easycap_settings.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_sound.c (renamed from drivers/staging/easycap/easycap_sound.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_testcard.c (renamed from drivers/staging/easycap/easycap_testcard.c)0
-rw-r--r--drivers/staging/media/go7007/Kconfig (renamed from drivers/staging/go7007/Kconfig)0
-rw-r--r--drivers/staging/media/go7007/Makefile (renamed from drivers/staging/go7007/Makefile)0
-rw-r--r--drivers/staging/media/go7007/README (renamed from drivers/staging/go7007/README)0
-rw-r--r--drivers/staging/media/go7007/go7007-driver.c (renamed from drivers/staging/go7007/go7007-driver.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-fw.c (renamed from drivers/staging/go7007/go7007-fw.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-i2c.c (renamed from drivers/staging/go7007/go7007-i2c.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-priv.h (renamed from drivers/staging/go7007/go7007-priv.h)0
-rw-r--r--drivers/staging/media/go7007/go7007-usb.c (renamed from drivers/staging/go7007/go7007-usb.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c (renamed from drivers/staging/go7007/go7007-v4l2.c)0
-rw-r--r--drivers/staging/media/go7007/go7007.h (renamed from drivers/staging/go7007/go7007.h)0
-rw-r--r--drivers/staging/media/go7007/go7007.txt (renamed from drivers/staging/go7007/go7007.txt)0
-rw-r--r--drivers/staging/media/go7007/s2250-board.c (renamed from drivers/staging/go7007/s2250-board.c)0
-rw-r--r--drivers/staging/media/go7007/s2250-loader.c (renamed from drivers/staging/go7007/s2250-loader.c)0
-rw-r--r--drivers/staging/media/go7007/s2250-loader.h (renamed from drivers/staging/go7007/s2250-loader.h)0
-rw-r--r--drivers/staging/media/go7007/saa7134-go7007.c (renamed from drivers/staging/go7007/saa7134-go7007.c)0
-rw-r--r--drivers/staging/media/go7007/snd-go7007.c (renamed from drivers/staging/go7007/snd-go7007.c)0
-rw-r--r--drivers/staging/media/go7007/wis-i2c.h (renamed from drivers/staging/go7007/wis-i2c.h)0
-rw-r--r--drivers/staging/media/go7007/wis-ov7640.c (renamed from drivers/staging/go7007/wis-ov7640.c)0
-rw-r--r--drivers/staging/media/go7007/wis-saa7113.c (renamed from drivers/staging/go7007/wis-saa7113.c)0
-rw-r--r--drivers/staging/media/go7007/wis-saa7115.c (renamed from drivers/staging/go7007/wis-saa7115.c)0
-rw-r--r--drivers/staging/media/go7007/wis-sony-tuner.c (renamed from drivers/staging/go7007/wis-sony-tuner.c)0
-rw-r--r--drivers/staging/media/go7007/wis-tw2804.c (renamed from drivers/staging/go7007/wis-tw2804.c)0
-rw-r--r--drivers/staging/media/go7007/wis-tw9903.c (renamed from drivers/staging/go7007/wis-tw9903.c)0
-rw-r--r--drivers/staging/media/go7007/wis-uda1342.c (renamed from drivers/staging/go7007/wis-uda1342.c)0
-rw-r--r--drivers/staging/media/lirc/Kconfig (renamed from drivers/staging/lirc/Kconfig)0
-rw-r--r--drivers/staging/media/lirc/Makefile (renamed from drivers/staging/lirc/Makefile)0
-rw-r--r--drivers/staging/media/lirc/TODO (renamed from drivers/staging/lirc/TODO)0
-rw-r--r--drivers/staging/media/lirc/TODO.lirc_zilog (renamed from drivers/staging/lirc/TODO.lirc_zilog)0
-rw-r--r--drivers/staging/media/lirc/lirc_bt829.c (renamed from drivers/staging/lirc/lirc_bt829.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_ene0100.h (renamed from drivers/staging/lirc/lirc_ene0100.h)0
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c (renamed from drivers/staging/lirc/lirc_igorplugusb.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c (renamed from drivers/staging/lirc/lirc_imon.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c (renamed from drivers/staging/lirc/lirc_parallel.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.h (renamed from drivers/staging/lirc/lirc_parallel.h)0
-rw-r--r--drivers/staging/media/lirc/lirc_sasem.c (renamed from drivers/staging/lirc/lirc_sasem.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c (renamed from drivers/staging/lirc/lirc_serial.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_sir.c (renamed from drivers/staging/lirc/lirc_sir.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_ttusbir.c (renamed from drivers/staging/lirc/lirc_ttusbir.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c (renamed from drivers/staging/lirc/lirc_zilog.c)0
-rw-r--r--drivers/staging/media/solo6x10/Kconfig (renamed from drivers/staging/solo6x10/Kconfig)0
-rw-r--r--drivers/staging/media/solo6x10/Makefile (renamed from drivers/staging/solo6x10/Makefile)0
-rw-r--r--drivers/staging/media/solo6x10/TODO (renamed from drivers/staging/solo6x10/TODO)0
-rw-r--r--drivers/staging/media/solo6x10/core.c (renamed from drivers/staging/solo6x10/core.c)0
-rw-r--r--drivers/staging/media/solo6x10/disp.c (renamed from drivers/staging/solo6x10/disp.c)0
-rw-r--r--drivers/staging/media/solo6x10/enc.c (renamed from drivers/staging/solo6x10/enc.c)0
-rw-r--r--drivers/staging/media/solo6x10/g723.c (renamed from drivers/staging/solo6x10/g723.c)0
-rw-r--r--drivers/staging/media/solo6x10/gpio.c (renamed from drivers/staging/solo6x10/gpio.c)0
-rw-r--r--drivers/staging/media/solo6x10/i2c.c (renamed from drivers/staging/solo6x10/i2c.c)0
-rw-r--r--drivers/staging/media/solo6x10/jpeg.h (renamed from drivers/staging/solo6x10/jpeg.h)0
-rw-r--r--drivers/staging/media/solo6x10/offsets.h (renamed from drivers/staging/solo6x10/offsets.h)0
-rw-r--r--drivers/staging/media/solo6x10/osd-font.h (renamed from drivers/staging/solo6x10/osd-font.h)0
-rw-r--r--drivers/staging/media/solo6x10/p2m.c (renamed from drivers/staging/solo6x10/p2m.c)0
-rw-r--r--drivers/staging/media/solo6x10/registers.h (renamed from drivers/staging/solo6x10/registers.h)0
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h (renamed from drivers/staging/solo6x10/solo6x10.h)0
-rw-r--r--drivers/staging/media/solo6x10/tw28.c (renamed from drivers/staging/solo6x10/tw28.c)0
-rw-r--r--drivers/staging/media/solo6x10/tw28.h (renamed from drivers/staging/solo6x10/tw28.h)0
-rw-r--r--drivers/staging/media/solo6x10/v4l2-enc.c (renamed from drivers/staging/solo6x10/v4l2-enc.c)0
-rw-r--r--drivers/staging/media/solo6x10/v4l2.c (renamed from drivers/staging/solo6x10/v4l2.c)0
-rw-r--r--drivers/staging/zram/zram_drv.c5
-rw-r--r--drivers/tty/hvc/Kconfig9
-rw-r--r--drivers/tty/hvc/Makefile1
-rw-r--r--drivers/tty/hvc/hvc_opal.c424
-rw-r--r--drivers/tty/hvc/hvcs.c6
-rw-r--r--drivers/tty/hvc/hvsi_lib.c4
-rw-r--r--drivers/tty/serial/8250.c23
-rw-r--r--drivers/tty/serial/sh-sci.c25
-rw-r--r--drivers/usb/core/driver.c5
-rw-r--r--drivers/virt/fsl_hypervisor.c1
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/coh901327_wdt.c2
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/iTCO_wdt.c19
-rw-r--r--drivers/watchdog/mpcore_wdt.c3
-rw-r--r--drivers/watchdog/octeon-wdt-main.c2
-rw-r--r--drivers/watchdog/s3c2410_wdt.c176
-rw-r--r--drivers/watchdog/sb_wdog.c4
-rw-r--r--drivers/watchdog/sc520_wdt.c2
-rw-r--r--drivers/watchdog/w83627hf_wdt.c33
-rw-r--r--drivers/watchdog/wdt.c2
-rw-r--r--drivers/watchdog/wdt_pci.c2
-rw-r--r--drivers/watchdog/wm831x_wdt.c318
-rw-r--r--fs/bio.c1
-rw-r--r--fs/block_dev.c15
-rw-r--r--fs/exofs/Kconfig2
-rw-r--r--fs/nfs/callback_xdr.c12
-rw-r--r--fs/nfs/file.c9
-rw-r--r--fs/nfs/nfs4filelayout.c7
-rw-r--r--fs/nfs/nfs4proc.c6
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/nfs/objlayout/objio_osd.c872
-rw-r--r--fs/nfs/objlayout/objlayout.c209
-rw-r--r--fs/nfs/objlayout/objlayout.h48
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/pnfs.c25
-rw-r--r--fs/nfs/write.c3
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/squashfs/Kconfig22
-rw-r--r--fs/squashfs/squashfs_fs.h7
-rw-r--r--fs/squashfs/super.c2
-rw-r--r--fs/statfs.c2
-rw-r--r--include/linux/amba/pl08x.h30
-rw-r--r--include/linux/amba/pl330.h6
-rw-r--r--include/linux/bio.h8
-rw-r--r--include/linux/blk_types.h11
-rw-r--r--include/linux/blkdev.h40
-rw-r--r--include/linux/cpu.h4
-rw-r--r--include/linux/dma-mapping.h3
-rw-r--r--include/linux/dmaengine.h13
-rw-r--r--include/linux/elevator.h6
-rw-r--r--include/linux/freezer.h11
-rw-r--r--include/linux/genhd.h6
-rw-r--r--include/linux/loop.h2
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/of.h10
-rw-r--r--include/linux/opp.h4
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/serial_sci.h2
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/topology.h4
-rw-r--r--include/linux/videodev2.h27
-rw-r--r--include/media/ov772x.h26
-rw-r--r--include/media/s5k6aa.h51
-rw-r--r--include/media/soc_camera.h104
-rw-r--r--include/media/soc_camera_platform.h4
-rw-r--r--include/media/soc_mediabus.h2
-rw-r--r--include/media/v4l2-ioctl.h2
-rw-r--r--include/media/v4l2-subdev.h5
-rw-r--r--include/media/videobuf2-core.h50
-rw-r--r--include/xen/interface/io/blkif.h36
-rw-r--r--kernel/cpu.c74
-rw-r--r--kernel/freezer.c2
-rw-r--r--kernel/power/qos.c3
-rw-r--r--kernel/sched.c2
-rw-r--r--mm/bounce.c9
-rw-r--r--net/sunrpc/auth_unix.c3
-rw-r--r--net/sunrpc/rpcb_clnt.c88
-rw-r--r--net/sunrpc/sunrpc_syms.c3
-rw-r--r--net/sunrpc/svc.c48
-rw-r--r--sound/core/control.c4
-rw-r--r--sound/core/hwdep.c9
-rw-r--r--sound/pci/hda/hda_hwdep.c2
-rw-r--r--sound/pci/hda/hda_intel.c4
-rw-r--r--sound/pci/hda/hda_local.h7
-rw-r--r--sound/pci/hda/patch_hdmi.c5
-rw-r--r--sound/pci/hda/patch_realtek.c29
-rw-r--r--sound/pci/hda/patch_sigmatel.c67
-rw-r--r--sound/pci/hda/patch_via.c5
-rw-r--r--sound/pci/intel8x0.c29
-rw-r--r--sound/pci/rme9652/hdsp.c2
-rw-r--r--sound/pci/rme9652/hdspm.c42
-rw-r--r--sound/soc/codecs/tlv320aic23.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c1
-rw-r--r--sound/soc/codecs/wm5100.c12
-rw-r--r--sound/soc/codecs/wm8711.c4
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8940.c2
-rw-r--r--sound/soc/codecs/wm8962.c30
-rw-r--r--sound/soc/samsung/ac97.c10
-rw-r--r--sound/soc/samsung/dma.c148
-rw-r--r--sound/soc/samsung/dma.h4
-rw-r--r--sound/usb/misc/ua101.c28
988 files changed, 40422 insertions, 22957 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
index f5bb0a3bb8c0..53d99edd1d75 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
@@ -71,3 +71,10 @@ Description: Value of 1 indicates the controller can honor the reset_devices
71 a dump device, as kdump requires resetting the device in order 71 a dump device, as kdump requires resetting the device in order
72 to work reliably. 72 to work reliably.
73 73
74Where: /sys/bus/pci/devices/<dev>/ccissX/transport_mode
75Date: July 2011
76Kernel Version: 3.0
77Contact: iss_storagedev@hp.com
78Description: Value of "simple" indicates that the controller has been placed
79 in "simple mode". Value of "performant" indicates that the
80 controller has been placed in "performant mode".
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index c940239d9678..2b90d328b3ba 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -166,8 +166,8 @@ if (condition)
166else 166else
167 do_that(); 167 do_that();
168 168
169This does not apply if one branch of a conditional statement is a single 169This does not apply if only one branch of a conditional statement is a single
170statement. Use braces in both branches. 170statement; in the latter case use braces in both branches:
171 171
172if (condition) { 172if (condition) {
173 do_this(); 173 do_this();
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 91410b6e7e08..b68698f96e7f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2486,6 +2486,9 @@ ioctls.</para>
2486 <listitem> 2486 <listitem>
2487 <para>Flash API. <xref linkend="flash-controls" /></para> 2487 <para>Flash API. <xref linkend="flash-controls" /></para>
2488 </listitem> 2488 </listitem>
2489 <listitem>
2490 <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
2491 </listitem>
2489 </itemizedlist> 2492 </itemizedlist>
2490 </section> 2493 </section>
2491 2494
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 23fdf79f8cf3..3bc5ee8b2c74 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -232,8 +232,9 @@ control is deprecated. New drivers and applications should use the
232 <entry>Enables a power line frequency filter to avoid 232 <entry>Enables a power line frequency filter to avoid
233flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are: 233flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
234<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0), 234<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
235<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and 235<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1),
236<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry> 236<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2) and
237<constant>V4L2_CID_POWER_LINE_FREQUENCY_AUTO</constant> (3).</entry>
237 </row> 238 </row>
238 <row> 239 <row>
239 <entry><constant>V4L2_CID_HUE_AUTO</constant></entry> 240 <entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index c57d1ec6291c..3f47df1aa54a 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -927,6 +927,33 @@ ioctl is called.</entry>
927Applications set or clear this flag before calling the 927Applications set or clear this flag before calling the
928<constant>VIDIOC_QBUF</constant> ioctl.</entry> 928<constant>VIDIOC_QBUF</constant> ioctl.</entry>
929 </row> 929 </row>
930 <row>
931 <entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
932 <entry>0x0400</entry>
933 <entry>The buffer has been prepared for I/O and can be queued by the
934application. Drivers set or clear this flag when the
935<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
936 linkend="vidioc-qbuf">VIDIOC_PREPARE_BUF</link>, <link
937 linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
938 linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called.</entry>
939 </row>
940 <row>
941 <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
942 <entry>0x0400</entry>
943 <entry>Caches do not have to be invalidated for this buffer.
944Typically applications shall use this flag if the data captured in the buffer
945is not going to be touched by the CPU, instead the buffer will, probably, be
946passed on to a DMA-capable hardware unit for further processing or output.
947</entry>
948 </row>
949 <row>
950 <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
951 <entry>0x0800</entry>
952 <entry>Caches do not have to be cleaned for this buffer.
953Typically applications shall use this flag for output buffers if the data
954in this buffer has not been created by the CPU but by some DMA-capable unit,
955in which case caches have not been used.</entry>
956 </row>
930 </tbody> 957 </tbody>
931 </tgroup> 958 </tgroup>
932 </table> 959 </table>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 40132c277647..2ab365c10fb9 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
469 &sub-close; 469 &sub-close;
470 &sub-ioctl; 470 &sub-ioctl;
471 <!-- All ioctls go here. --> 471 <!-- All ioctls go here. -->
472 &sub-create-bufs;
472 &sub-cropcap; 473 &sub-cropcap;
473 &sub-dbg-g-chip-ident; 474 &sub-dbg-g-chip-ident;
474 &sub-dbg-g-register; 475 &sub-dbg-g-register;
@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
511 &sub-queryctrl; 512 &sub-queryctrl;
512 &sub-query-dv-preset; 513 &sub-query-dv-preset;
513 &sub-querystd; 514 &sub-querystd;
515 &sub-prepare-buf;
514 &sub-reqbufs; 516 &sub-reqbufs;
515 &sub-s-hw-freq-seek; 517 &sub-s-hw-freq-seek;
516 &sub-streamon; 518 &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644
index 000000000000..73ae8a6cd004
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -0,0 +1,139 @@
1<refentry id="vidioc-create-bufs">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_CREATE_BUFS</refname>
9 <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_CREATE_BUFS</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>This ioctl is used to create buffers for <link linkend="mmap">memory
52mapped</link> or <link linkend="userp">user pointer</link>
53I/O. It can be used as an alternative or in addition to the
54<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
55is required. This ioctl can be called multiple times to create buffers of
56different sizes.</para>
57
58 <para>To allocate device buffers applications initialize relevant fields of
59the <structname>v4l2_create_buffers</structname> structure. They set the
60<structfield>type</structfield> field in the
61<structname>v4l2_format</structname> structure, embedded in this
62structure, to the respective stream or buffer type.
63<structfield>count</structfield> must be set to the number of required buffers.
64<structfield>memory</structfield> specifies the required I/O method. The
65<structfield>format</structfield> field shall typically be filled in using
66either the <constant>VIDIOC_TRY_FMT</constant> or
67<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
68<structfield>sizeimage</structfield> fields to fit their specific needs. The
69<structfield>reserved</structfield> array must be zeroed.</para>
70
71 <para>When the ioctl is called with a pointer to this structure the driver
72will attempt to allocate up to the requested number of buffers and store the
73actual number allocated and the starting index in the
74<structfield>count</structfield> and the <structfield>index</structfield> fields
75respectively. On return <structfield>count</structfield> can be smaller than
76the number requested. The driver may also increase buffer sizes if required,
77however, it will not update <structfield>sizeimage</structfield> field values.
78The user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
79information.</para>
80
81 <table pgwide="1" frame="none" id="v4l2-create-buffers">
82 <title>struct <structname>v4l2_create_buffers</structname></title>
83 <tgroup cols="3">
84 &cs-str;
85 <tbody valign="top">
86 <row>
87 <entry>__u32</entry>
88 <entry><structfield>index</structfield></entry>
89 <entry>The starting buffer index, returned by the driver.</entry>
90 </row>
91 <row>
92 <entry>__u32</entry>
93 <entry><structfield>count</structfield></entry>
94 <entry>The number of buffers requested or granted.</entry>
95 </row>
96 <row>
97 <entry>&v4l2-memory;</entry>
98 <entry><structfield>memory</structfield></entry>
99 <entry>Applications set this field to
100<constant>V4L2_MEMORY_MMAP</constant> or
101<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
102 </row>
103 <row>
104 <entry>&v4l2-format;</entry>
105 <entry><structfield>format</structfield></entry>
106 <entry>Filled in by the application, preserved by the driver.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>reserved</structfield>[8]</entry>
111 <entry>A place holder for future extensions.</entry>
112 </row>
113 </tbody>
114 </tgroup>
115 </table>
116 </refsect1>
117
118 <refsect1>
119 &return-value;
120
121 <variablelist>
122 <varlistentry>
123 <term><errorcode>ENOMEM</errorcode></term>
124 <listitem>
125 <para>No memory to allocate buffers for <link linkend="mmap">memory
126mapped</link> I/O.</para>
127 </listitem>
128 </varlistentry>
129 <varlistentry>
130 <term><errorcode>EINVAL</errorcode></term>
131 <listitem>
132 <para>The buffer type (<structfield>type</structfield> field) or the
133requested I/O method (<structfield>memory</structfield>) is not
134supported.</para>
135 </listitem>
136 </varlistentry>
137 </variablelist>
138 </refsect1>
139</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644
index 000000000000..7bde698760e4
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -0,0 +1,88 @@
1<refentry id="vidioc-prepare-buf">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_PREPARE_BUF</refname>
9 <refpurpose>Prepare a buffer for I/O</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_PREPARE_BUF</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>Applications can optionally call the
52<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
53to the driver before actually enqueuing it, using the
54<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
55Such preparations may include cache invalidation or cleaning. Performing them
56in advance saves time during the actual I/O. In case such cache operations are
57not required, the application can use one of
58<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
59<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
60step.</para>
61
62 <para>The <structname>v4l2_buffer</structname> structure is
63specified in <xref linkend="buffer" />.</para>
64 </refsect1>
65
66 <refsect1>
67 &return-value;
68
69 <variablelist>
70 <varlistentry>
71 <term><errorcode>EBUSY</errorcode></term>
72 <listitem>
73 <para>File I/O is in progress.</para>
74 </listitem>
75 </varlistentry>
76 <varlistentry>
77 <term><errorcode>EINVAL</errorcode></term>
78 <listitem>
79 <para>The buffer <structfield>type</structfield> is not
80supported, or the <structfield>index</structfield> is out of bounds,
81or no buffers have been allocated yet, or the
82<structfield>userptr</structfield> or
83<structfield>length</structfield> are invalid.</para>
84 </listitem>
85 </varlistentry>
86 </variablelist>
87 </refsect1>
88</refentry>
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt
index 71cfbdc0f74d..3b2612e342f1 100644
--- a/Documentation/block/switching-sched.txt
+++ b/Documentation/block/switching-sched.txt
@@ -1,6 +1,6 @@
1To choose IO schedulers at boot time, use the argument 'elevator=deadline'. 1To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
2'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are 2'noop' and 'cfq' (the default) are also available. IO schedulers are assigned
3assigned globally at boot time only presently. 3globally at boot time only presently.
4 4
5Each io queue has a set of io scheduler tunables associated with it. These 5Each io queue has a set of io scheduler tunables associated with it. These
6tunables control how the io scheduler works. You can find these entries 6tunables control how the io scheduler works. You can find these entries
diff --git a/Documentation/blockdev/cciss.txt b/Documentation/blockdev/cciss.txt
index c00c6a5ab21f..71464e09ec18 100644
--- a/Documentation/blockdev/cciss.txt
+++ b/Documentation/blockdev/cciss.txt
@@ -78,6 +78,16 @@ The device naming scheme is:
78/dev/cciss/c1d1p2 Controller 1, disk 1, partition 2 78/dev/cciss/c1d1p2 Controller 1, disk 1, partition 2
79/dev/cciss/c1d1p3 Controller 1, disk 1, partition 3 79/dev/cciss/c1d1p3 Controller 1, disk 1, partition 3
80 80
81CCISS simple mode support
82-------------------------
83
84The "cciss_simple_mode=1" boot parameter may be used to prevent the driver
85from putting the controller into "performant" mode. The difference is that
86with simple mode, each command completion requires an interrupt, while with
87"performant mode" (the default, and ordinarily better performing) it is
88possible to have multiple command completions indicated by a single
89interrupt.
90
81SCSI tape drive and medium changer support 91SCSI tape drive and medium changer support
82------------------------------------------ 92------------------------------------------
83 93
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index cd67e90003c0..9c452ef2328c 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -454,8 +454,8 @@ mounted hierarchy, to remove a task from its current cgroup you must
454move it into a new cgroup (possibly the root cgroup) by writing to the 454move it into a new cgroup (possibly the root cgroup) by writing to the
455new cgroup's tasks file. 455new cgroup's tasks file.
456 456
457Note: If the ns cgroup is active, moving a process to another cgroup can 457Note: Due to some restrictions enforced by some cgroup subsystems, moving
458fail. 458a process to another cgroup can fail.
459 459
4602.3 Mounting hierarchies by name 4602.3 Mounting hierarchies by name
461-------------------------------- 461--------------------------------
diff --git a/Documentation/devicetree/bindings/ata/calxeda-sata.txt b/Documentation/devicetree/bindings/ata/calxeda-sata.txt
new file mode 100644
index 000000000000..79caa5651f53
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/calxeda-sata.txt
@@ -0,0 +1,17 @@
1* Calxeda SATA Controller
2
3SATA nodes are defined to describe on-chip Serial ATA controllers.
4Each SATA controller should have its own node.
5
6Required properties:
7- compatible : compatible list, contains "calxeda,hb-ahci"
8- interrupts : <interrupt mapping for SATA IRQ>
9- reg : <registers mapping>
10
11Example:
12 sata@ffe08000 {
13 compatible = "calxeda,hb-ahci";
14 reg = <0xffe08000 0x1000>;
15 interrupts = <115>;
16 };
17
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/board.txt b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
index 39e941515a36..380914e965e0 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
@@ -1,3 +1,8 @@
1Freescale Reference Board Bindings
2
3This document describes device tree bindings for various devices that
4exist on some Freescale reference boards.
5
1* Board Control and Status (BCSR) 6* Board Control and Status (BCSR)
2 7
3Required properties: 8Required properties:
@@ -12,25 +17,26 @@ Example:
12 reg = <f8000000 8000>; 17 reg = <f8000000 8000>;
13 }; 18 };
14 19
15* Freescale on board FPGA 20* Freescale on-board FPGA
16 21
17This is the memory-mapped registers for on board FPGA. 22This is the memory-mapped registers for on board FPGA.
18 23
19Required properities: 24Required properities:
20- compatible : should be "fsl,fpga-pixis". 25- compatible: should be a board-specific string followed by a string
21- reg : should contain the address and the length of the FPPGA register 26 indicating the type of FPGA. Example:
22 set. 27 "fsl,<board>-fpga", "fsl,fpga-pixis"
28- reg: should contain the address and the length of the FPGA register set.
23- interrupt-parent: should specify phandle for the interrupt controller. 29- interrupt-parent: should specify phandle for the interrupt controller.
24- interrupts : should specify event (wakeup) IRQ. 30- interrupts: should specify event (wakeup) IRQ.
25 31
26Example (MPC8610HPCD): 32Example (P1022DS):
27 33
28 board-control@e8000000 { 34 board-control@3,0 {
29 compatible = "fsl,fpga-pixis"; 35 compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
30 reg = <0xe8000000 32>; 36 reg = <3 0 0x30>;
31 interrupt-parent = <&mpic>; 37 interrupt-parent = <&mpic>;
32 interrupts = <8 8>; 38 interrupts = <8 8 0 0>;
33 }; 39 };
34 40
35* Freescale BCSR GPIO banks 41* Freescale BCSR GPIO banks
36 42
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt b/Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt
new file mode 100644
index 000000000000..9d54eb5a295f
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt
@@ -0,0 +1,395 @@
1===================================================================
2Debug Control and Status Register (DCSR) Binding
3Copyright 2011 Freescale Semiconductor Inc.
4
5NOTE: The bindings described in this document are preliminary and subject
6to change. Some of the compatible strings that contain only generic names
7may turn out to be inappropriate, or need additional properties to describe
8the integration of the block with the rest of the chip.
9
10=====================================================================
11Debug Control and Status Register Memory Map
12
13Description
14
15This node defines the base address and range for the
16defined DCSR Memory Map. Child nodes will describe the individual
17debug blocks defined within this memory space.
18
19PROPERTIES
20
21 - compatible
22 Usage: required
23 Value type: <string>
24 Definition: Must include "fsl,dcsr" and "simple-bus".
25 The DCSR space exists in the memory-mapped bus.
26
27 - #address-cells
28 Usage: required
29 Value type: <u32>
30 Definition: A standard property. Defines the number of cells
31 or representing physical addresses in child nodes.
32
33 - #size-cells
34 Usage: required
35 Value type: <u32>
36 Definition: A standard property. Defines the number of cells
37 or representing the size of physical addresses in
38 child nodes.
39
40 - ranges
41 Usage: required
42 Value type: <prop-encoded-array>
43 Definition: A standard property. Specifies the physical address
44 range of the DCSR space.
45
46EXAMPLE
47 dcsr: dcsr@f00000000 {
48 #address-cells = <1>;
49 #size-cells = <1>;
50 compatible = "fsl,dcsr", "simple-bus";
51 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
52 };
53
54=====================================================================
55Event Processing Unit
56
57This node represents the region of DCSR space allocated to the EPU
58
59PROPERTIES
60
61 - compatible
62 Usage: required
63 Value type: <string>
64 Definition: Must include "fsl,dcsr-epu"
65
66 - interrupts
67 Usage: required
68 Value type: <prop_encoded-array>
69 Definition: Specifies the interrupts generated by the EPU.
70 The value of the interrupts property consists of three
71 interrupt specifiers. The format of the specifier is defined
72 by the binding document describing the node's interrupt parent.
73
74 The EPU counters can be configured to assert the performance
75 monitor interrupt signal based on either counter overflow or value
76 match. Which counter asserted the interrupt is captured in an EPU
77 Counter Interrupt Status Register (EPCPUISR).
78
79 The EPU unit can also be configured to assert either or both of
80 two interrupt signals based on debug event sources within the SoC.
81 The interrupt signals are epu_xt_int0 and epu_xt_int1.
82 Which event source asserted the interrupt is captured in an EPU
83 Interrupt Status Register (EPISR0,EPISR1).
84
85 Interrupt numbers are lised in order (perfmon, event0, event1).
86
87 - interrupt-parent
88 Usage: required
89 Value type: <phandle>
90 Definition: A single <phandle> value that points
91 to the interrupt parent to which the child domain
92 is being mapped. Value must be "&mpic"
93
94 - reg
95 Usage: required
96 Value type: <prop-encoded-array>
97 Definition: A standard property. Specifies the physical address
98 offset and length of the DCSR space registers of the device
99 configuration block.
100
101EXAMPLE
102 dcsr-epu@0 {
103 compatible = "fsl,dcsr-epu";
104 interrupts = <52 2 0 0
105 84 2 0 0
106 85 2 0 0>;
107 interrupt-parent = <&mpic>;
108 reg = <0x0 0x1000>;
109 };
110
111=======================================================================
112Nexus Port Controller
113
114This node represents the region of DCSR space allocated to the NPC
115
116PROPERTIES
117
118 - compatible
119 Usage: required
120 Value type: <string>
121 Definition: Must include "fsl,dcsr-npc"
122
123 - reg
124 Usage: required
125 Value type: <prop-encoded-array>
126 Definition: A standard property. Specifies the physical address
127 offset and length of the DCSR space registers of the device
128 configuration block.
129 The Nexus Port controller occupies two regions in the DCSR space
130 with distinct functionality.
131
132 The first register range describes the Nexus Port Controller
133 control and status registers.
134
135 The second register range describes the Nexus Port Controller
136 internal trace buffer. The NPC trace buffer is a small memory buffer
137 which stages the nexus trace data for transmission via the Aurora port
138 or to a DDR based trace buffer. In some configurations the NPC trace
139 buffer can be the only trace buffer used.
140
141
142EXAMPLE
143 dcsr-npc {
144 compatible = "fsl,dcsr-npc";
145 reg = <0x1000 0x1000 0x1000000 0x8000>;
146 };
147
148=======================================================================
149Nexus Concentrator
150
151This node represents the region of DCSR space allocated to the NXC
152
153PROPERTIES
154
155 - compatible
156 Usage: required
157 Value type: <string>
158 Definition: Must include "fsl,dcsr-nxc"
159
160 - reg
161 Usage: required
162 Value type: <prop-encoded-array>
163 Definition: A standard property. Specifies the physical address
164 offset and length of the DCSR space registers of the device
165 configuration block.
166
167EXAMPLE
168 dcsr-nxc@2000 {
169 compatible = "fsl,dcsr-nxc";
170 reg = <0x2000 0x1000>;
171 };
172=======================================================================
173CoreNet Debug Controller
174
175This node represents the region of DCSR space allocated to
176the CoreNet Debug controller.
177
178PROPERTIES
179
180 - compatible
181 Usage: required
182 Value type: <string>
183 Definition: Must include "fsl,dcsr-corenet"
184
185 - reg
186 Usage: required
187 Value type: <prop-encoded-array>
188 Definition: A standard property. Specifies the physical address
189 offset and length of the DCSR space registers of the device
190 configuration block.
191 The CoreNet Debug controller occupies two regions in the DCSR space
192 with distinct functionality.
193
194 The first register range describes the CoreNet Debug Controller
195 functionalty to perform transaction and transaction attribute matches.
196
197 The second register range describes the CoreNet Debug Controller
198 functionalty to trigger event notifications and debug traces.
199
200EXAMPLE
201 dcsr-corenet {
202 compatible = "fsl,dcsr-corenet";
203 reg = <0x8000 0x1000 0xB0000 0x1000>;
204 };
205
206=======================================================================
207Data Path Debug controller
208
209This node represents the region of DCSR space allocated to
210the DPAA Debug Controller. This controller controls debug configuration
211for the QMAN and FMAN blocks.
212
213PROPERTIES
214
215 - compatible
216 Usage: required
217 Value type: <string>
218 Definition: Must include both an identifier specific to the SoC
219 or Debug IP of the form "fsl,<soc>-dcsr-dpaa" in addition to the
220 generic compatible string "fsl,dcsr-dpaa".
221
222 - reg
223 Usage: required
224 Value type: <prop-encoded-array>
225 Definition: A standard property. Specifies the physical address
226 offset and length of the DCSR space registers of the device
227 configuration block.
228
229EXAMPLE
230 dcsr-dpaa@9000 {
231 compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa";
232 reg = <0x9000 0x1000>;
233 };
234
235=======================================================================
236OCeaN Debug controller
237
238This node represents the region of DCSR space allocated to
239the OCN Debug Controller.
240
241PROPERTIES
242
243 - compatible
244 Usage: required
245 Value type: <string>
246 Definition: Must include both an identifier specific to the SoC
247 or Debug IP of the form "fsl,<soc>-dcsr-ocn" in addition to the
248 generic compatible string "fsl,dcsr-ocn".
249
250 - reg
251 Usage: required
252 Value type: <prop-encoded-array>
253 Definition: A standard property. Specifies the physical address
254 offset and length of the DCSR space registers of the device
255 configuration block.
256
257EXAMPLE
258 dcsr-ocn@11000 {
259 compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn";
260 reg = <0x11000 0x1000>;
261 };
262
263=======================================================================
264DDR Controller Debug controller
265
266This node represents the region of DCSR space allocated to
267the OCN Debug Controller.
268
269PROPERTIES
270
271 - compatible
272 Usage: required
273 Value type: <string>
274 Definition: Must include "fsl,dcsr-ddr"
275
276 - dev-handle
277 Usage: required
278 Definition: A phandle to associate this debug node with its
279 component controller.
280
281 - reg
282 Usage: required
283 Value type: <prop-encoded-array>
284 Definition: A standard property. Specifies the physical address
285 offset and length of the DCSR space registers of the device
286 configuration block.
287
288EXAMPLE
289 dcsr-ddr@12000 {
290 compatible = "fsl,dcsr-ddr";
291 dev-handle = <&ddr1>;
292 reg = <0x12000 0x1000>;
293 };
294
295=======================================================================
296Nexus Aurora Link Controller
297
298This node represents the region of DCSR space allocated to
299the NAL Controller.
300
301PROPERTIES
302
303 - compatible
304 Usage: required
305 Value type: <string>
306 Definition: Must include both an identifier specific to the SoC
307 or Debug IP of the form "fsl,<soc>-dcsr-nal" in addition to the
308 generic compatible string "fsl,dcsr-nal".
309
310 - reg
311 Usage: required
312 Value type: <prop-encoded-array>
313 Definition: A standard property. Specifies the physical address
314 offset and length of the DCSR space registers of the device
315 configuration block.
316
317EXAMPLE
318 dcsr-nal@18000 {
319 compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal";
320 reg = <0x18000 0x1000>;
321 };
322
323
324=======================================================================
325Run Control and Power Management
326
327This node represents the region of DCSR space allocated to
328the RCPM Debug Controller. This functionlity is limited to the
329control the debug operations of the SoC and cores.
330
331PROPERTIES
332
333 - compatible
334 Usage: required
335 Value type: <string>
336 Definition: Must include both an identifier specific to the SoC
337 or Debug IP of the form "fsl,<soc>-dcsr-rcpm" in addition to the
338 generic compatible string "fsl,dcsr-rcpm".
339
340 - reg
341 Usage: required
342 Value type: <prop-encoded-array>
343 Definition: A standard property. Specifies the physical address
344 offset and length of the DCSR space registers of the device
345 configuration block.
346
347EXAMPLE
348 dcsr-rcpm@22000 {
349 compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm";
350 reg = <0x22000 0x1000>;
351 };
352
353=======================================================================
354Core Service Bridge Proxy
355
356This node represents the region of DCSR space allocated to
357the Core Service Bridge Proxies.
358There is one Core Service Bridge Proxy device for each CPU in the system.
359This functionlity provides access to the debug operations of the CPU.
360
361PROPERTIES
362
363 - compatible
364 Usage: required
365 Value type: <string>
366 Definition: Must include both an identifier specific to the cpu
367 of the form "fsl,dcsr-<cpu>-sb-proxy" in addition to the
368 generic compatible string "fsl,dcsr-cpu-sb-proxy".
369
370 - cpu-handle
371 Usage: required
372 Definition: A phandle to associate this debug node with its cpu.
373
374 - reg
375 Usage: required
376 Value type: <prop-encoded-array>
377 Definition: A standard property. Specifies the physical address
378 offset and length of the DCSR space registers of the device
379 configuration block.
380
381EXAMPLE
382 dcsr-cpu-sb-proxy@40000 {
383 compatible = "fsl,dcsr-e500mc-sb-proxy",
384 "fsl,dcsr-cpu-sb-proxy";
385 cpu-handle = <&cpu0>;
386 reg = <0x40000 0x1000>;
387 };
388 dcsr-cpu-sb-proxy@41000 {
389 compatible = "fsl,dcsr-e500mc-sb-proxy",
390 "fsl,dcsr-cpu-sb-proxy";
391 cpu-handle = <&cpu1>;
392 reg = <0x41000 0x1000>;
393 };
394
395=======================================================================
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
index 70558c3f3682..5d586e1ccaf5 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
@@ -25,6 +25,16 @@ Required properties:
25 are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed 25 are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed
26 to MPIC. 26 to MPIC.
27 27
28Optional properties:
29- msi-address-64: 64-bit PCI address of the MSIIR register. The MSIIR register
30 is used for MSI messaging. The address of MSIIR in PCI address space is
31 the MSI message address.
32
33 This property may be used in virtualized environments where the hypervisor
34 has created an alternate mapping for the MSIR block. See below for an
35 explanation.
36
37
28Example: 38Example:
29 msi@41600 { 39 msi@41600 {
30 compatible = "fsl,mpc8610-msi", "fsl,mpic-msi"; 40 compatible = "fsl,mpc8610-msi", "fsl,mpic-msi";
@@ -41,3 +51,35 @@ Example:
41 0xe7 0>; 51 0xe7 0>;
42 interrupt-parent = <&mpic>; 52 interrupt-parent = <&mpic>;
43 }; 53 };
54
55The Freescale hypervisor and msi-address-64
56-------------------------------------------
57Normally, PCI devices have access to all of CCSR via an ATMU mapping. The
58Freescale MSI driver calculates the address of MSIIR (in the MSI register
59block) and sets that address as the MSI message address.
60
61In a virtualized environment, the hypervisor may need to create an IOMMU
62mapping for MSIIR. The Freescale ePAPR hypervisor has this requirement
63because of hardware limitations of the Peripheral Access Management Unit
64(PAMU), which is currently the only IOMMU that the hypervisor supports.
65The ATMU is programmed with the guest physical address, and the PAMU
66intercepts transactions and reroutes them to the true physical address.
67
68In the PAMU, each PCI controller is given only one primary window. The
69PAMU restricts DMA operations so that they can only occur within a window.
70Because PCI devices must be able to DMA to memory, the primary window must
71be used to cover all of the guest's memory space.
72
73PAMU primary windows can be divided into 256 subwindows, and each
74subwindow can have its own address mapping ("guest physical" to "true
75physical"). However, each subwindow has to have the same alignment, which
76means they cannot be located at just any address. Because of these
77restrictions, it is usually impossible to create a 4KB subwindow that
78covers MSIIR where it's normally located.
79
80Therefore, the hypervisor has to create a subwindow inside the same
81primary window used for memory, but mapped to the MSIR block (where MSIIR
82lives). The first subwindow after the end of guest memory is used for
83this. The address specified in the msi-address-64 property is the PCI
84address of MSIIR. The hypervisor configures the PAMU to map that address to
85the true physical address of MSIIR.
diff --git a/Documentation/filesystems/hfs.txt b/Documentation/filesystems/hfs.txt
index bd0fa7704035..d096df6db07a 100644
--- a/Documentation/filesystems/hfs.txt
+++ b/Documentation/filesystems/hfs.txt
@@ -1,3 +1,4 @@
1Note: This filesystem doesn't have a maintainer.
1 2
2Macintosh HFS Filesystem for Linux 3Macintosh HFS Filesystem for Linux
3================================== 4==================================
@@ -76,8 +77,6 @@ hformat that can be used to create HFS filesystem. See
76Credits 77Credits
77======= 78=======
78 79
79The HFS drivers was written by Paul H. Hargrovea (hargrove@sccm.Stanford.EDU) 80The HFS drivers was written by Paul H. Hargrovea (hargrove@sccm.Stanford.EDU).
80and is now maintained by Roman Zippel (roman@ardistech.com) at Ardis 81Roman Zippel (roman@ardistech.com) rewrote large parts of the code and brought
81Technologies. 82in btree routines derived from Brad Boyer's hfsplus driver.
82Roman rewrote large parts of the code and brought in btree routines derived
83from Brad Boyer's hfsplus driver (also maintained by Roman now).
diff --git a/Documentation/filesystems/inotify.txt b/Documentation/filesystems/inotify.txt
index 59a919f16144..cfd02712b83e 100644
--- a/Documentation/filesystems/inotify.txt
+++ b/Documentation/filesystems/inotify.txt
@@ -194,7 +194,8 @@ associated with the inotify_handle, and on which events are queued.
194Each watch is associated with an inotify_watch structure. Watches are chained 194Each watch is associated with an inotify_watch structure. Watches are chained
195off of each associated inotify_handle and each associated inode. 195off of each associated inotify_handle and each associated inode.
196 196
197See fs/inotify.c and fs/inotify_user.c for the locking and lifetime rules. 197See fs/notify/inotify/inotify_fsnotify.c and fs/notify/inotify/inotify_user.c
198for the locking and lifetime rules.
198 199
199 200
200(vi) Rationale 201(vi) Rationale
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index 76ffef94ed75..3f44dbdfda70 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -14,6 +14,10 @@ Supported chips:
14 Prefix: 'w83627dhg' 14 Prefix: 'w83627dhg'
15 Addresses scanned: ISA address retrieved from Super I/O registers 15 Addresses scanned: ISA address retrieved from Super I/O registers
16 Datasheet: not available 16 Datasheet: not available
17 * Winbond W83627UHG
18 Prefix: 'w83627uhg'
19 Addresses scanned: ISA address retrieved from Super I/O registers
20 Datasheet: available from www.nuvoton.com
17 * Winbond W83667HG 21 * Winbond W83667HG
18 Prefix: 'w83667hg' 22 Prefix: 'w83667hg'
19 Addresses scanned: ISA address retrieved from Super I/O registers 23 Addresses scanned: ISA address retrieved from Super I/O registers
@@ -42,14 +46,13 @@ Description
42----------- 46-----------
43 47
44This driver implements support for the Winbond W83627EHF, W83627EHG, 48This driver implements support for the Winbond W83627EHF, W83627EHG,
45W83627DHG, W83627DHG-P, W83667HG, W83667HG-B, W83667HG-I (NCT6775F), 49W83627DHG, W83627DHG-P, W83627UHG, W83667HG, W83667HG-B, W83667HG-I
46and NCT6776F super I/O chips. We will refer to them collectively as 50(NCT6775F), and NCT6776F super I/O chips. We will refer to them collectively
47Winbond chips. 51as Winbond chips.
48 52
49The chips implement three temperature sensors (up to four for 667HG-B, and nine 53The chips implement 2 to 4 temperature sensors (9 for NCT6775F and NCT6776F),
50for NCT6775F and NCT6776F), five fan rotation speed sensors, ten analog voltage 542 to 5 fan rotation speed sensors, 8 to 10 analog voltage sensors, one VID
51sensors (only nine for the 627DHG), one VID (6 pins for the 627EHF/EHG, 8 pins 55(except for 627UHG), alarms with beep warnings (control unimplemented),
52for the 627DHG and 667HG), alarms with beep warnings (control unimplemented),
53and some automatic fan regulation strategies (plus manual fan control mode). 56and some automatic fan regulation strategies (plus manual fan control mode).
54 57
55The temperature sensor sources on W82677HG-B, NCT6775F, and NCT6776F are 58The temperature sensor sources on W82677HG-B, NCT6775F, and NCT6776F are
@@ -86,17 +89,16 @@ follows:
86 89
87temp1 -> pwm1 90temp1 -> pwm1
88temp2 -> pwm2 91temp2 -> pwm2
89temp3 -> pwm3 92temp3 -> pwm3 (not on 627UHG)
90prog -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not 93prog -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not
91 supported by the driver) 94 supported by the driver)
92 95
93/sys files 96/sys files
94---------- 97----------
95 98
96name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG, 99name - this is a standard hwmon device entry, it contains the name of
97 it is set to "w83627ehf", for the W83627DHG it is set to "w83627dhg", 100 the device (see the prefix in the list of supported devices at
98 for the W83667HG and W83667HG-B it is set to "w83667hg", for NCT6775F it 101 the top of this file)
99 is set to "nct6775", and for NCT6776F it is set to "nct6776".
100 102
101pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: 103pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
102 0 (stop) to 255 (full) 104 0 (stop) to 255 (full)
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 3ff0dad62d36..9d666828915a 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -411,9 +411,9 @@ event code Key Notes
411 411
4120x1004 0x03 FN+F4 Sleep button (ACPI sleep button 4120x1004 0x03 FN+F4 Sleep button (ACPI sleep button
413 semantics, i.e. sleep-to-RAM). 413 semantics, i.e. sleep-to-RAM).
414 It is always generate some kind 414 It always generates some kind
415 of event, either the hot key 415 of event, either the hot key
416 event or a ACPI sleep button 416 event or an ACPI sleep button
417 event. The firmware may 417 event. The firmware may
418 refuse to generate further FN+F4 418 refuse to generate further FN+F4
419 key presses until a S3 or S4 ACPI 419 key presses until a S3 or S4 ACPI
diff --git a/Documentation/leds/leds-class.txt b/Documentation/leds/leds-class.txt
index 4996586e27e8..79699c200766 100644
--- a/Documentation/leds/leds-class.txt
+++ b/Documentation/leds/leds-class.txt
@@ -61,8 +61,8 @@ Hardware accelerated blink of LEDs
61Some LEDs can be programmed to blink without any CPU interaction. To 61Some LEDs can be programmed to blink without any CPU interaction. To
62support this feature, a LED driver can optionally implement the 62support this feature, a LED driver can optionally implement the
63blink_set() function (see <linux/leds.h>). To set an LED to blinking, 63blink_set() function (see <linux/leds.h>). To set an LED to blinking,
64however, it is better to use use the API function led_blink_set(), 64however, it is better to use the API function led_blink_set(), as it
65as it will check and implement software fallback if necessary. 65will check and implement software fallback if necessary.
66 66
67To turn off blinking again, use the API function led_brightness_set() 67To turn off blinking again, use the API function led_brightness_set()
68as that will not just set the LED brightness but also stop any software 68as that will not just set the LED brightness but also stop any software
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 38b57248fd61..316c2ba187f4 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -22,12 +22,12 @@ try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
22either wakes them up, if they are kernel threads, or sends fake signals to them, 22either wakes them up, if they are kernel threads, or sends fake signals to them,
23if they are user space processes. A task that has TIF_FREEZE set, should react 23if they are user space processes. A task that has TIF_FREEZE set, should react
24to it by calling the function called refrigerator() (defined in 24to it by calling the function called refrigerator() (defined in
25kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state 25kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state
26to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. 26to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
27Then, we say that the task is 'frozen' and therefore the set of functions 27Then, we say that the task is 'frozen' and therefore the set of functions
28handling this mechanism is referred to as 'the freezer' (these functions are 28handling this mechanism is referred to as 'the freezer' (these functions are
29defined in kernel/power/process.c and include/linux/freezer.h). User space 29defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h).
30processes are generally frozen before kernel threads. 30User space processes are generally frozen before kernel threads.
31 31
32It is not recommended to call refrigerator() directly. Instead, it is 32It is not recommended to call refrigerator() directly. Instead, it is
33recommended to use the try_to_freeze() function (defined in 33recommended to use the try_to_freeze() function (defined in
@@ -95,7 +95,7 @@ after the memory for the image has been freed, we don't want tasks to allocate
95additional memory and we prevent them from doing that by freezing them earlier. 95additional memory and we prevent them from doing that by freezing them earlier.
96[Of course, this also means that device drivers should not allocate substantial 96[Of course, this also means that device drivers should not allocate substantial
97amounts of memory from their .suspend() callbacks before hibernation, but this 97amounts of memory from their .suspend() callbacks before hibernation, but this
98is e separate issue.] 98is a separate issue.]
99 99
1003. The third reason is to prevent user space processes and some kernel threads 1003. The third reason is to prevent user space processes and some kernel threads
101from interfering with the suspending and resuming of devices. A user space 101from interfering with the suspending and resuming of devices. A user space
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 0e856088db7c..5336149f831b 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -789,6 +789,16 @@ will behave normally, not taking the autosuspend delay into account.
789Similarly, if the power.use_autosuspend field isn't set then the autosuspend 789Similarly, if the power.use_autosuspend field isn't set then the autosuspend
790helper functions will behave just like the non-autosuspend counterparts. 790helper functions will behave just like the non-autosuspend counterparts.
791 791
792Under some circumstances a driver or subsystem may want to prevent a device
793from autosuspending immediately, even though the usage counter is zero and the
794autosuspend delay time has expired. If the ->runtime_suspend() callback
795returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
796in the future (as it normally would be if the callback invoked
797pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
798autosuspend. The ->runtime_suspend() callback can't do this rescheduling
799itself because no suspend requests of any kind are accepted while the device is
800suspending (i.e., while the callback is running).
801
792The implementation is well suited for asynchronous use in interrupt contexts. 802The implementation is well suited for asynchronous use in interrupt contexts.
793However such use inevitably involves races, because the PM core can't 803However such use inevitably involves races, because the PM core can't
794synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. 804synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
diff --git a/Documentation/serial/computone.txt b/Documentation/serial/computone.txt
index 60a6f657c37d..39ddcdbeeb85 100644
--- a/Documentation/serial/computone.txt
+++ b/Documentation/serial/computone.txt
@@ -20,8 +20,6 @@ Version: 1.2.14
20Date: 11/01/2001 20Date: 11/01/2001
21Historical Author: Andrew Manison <amanison@america.net> 21Historical Author: Andrew Manison <amanison@america.net>
22Primary Author: Doug McNash 22Primary Author: Doug McNash
23Support: support@computone.com
24Fixes and Updates: Mike Warfield <mhw@wittsend.com>
25 23
26This file assumes that you are using the Computone drivers which are 24This file assumes that you are using the Computone drivers which are
27integrated into the kernel sources. For updating the drivers or installing 25integrated into the kernel sources. For updating the drivers or installing
diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
new file mode 100644
index 000000000000..ae1e90036d06
--- /dev/null
+++ b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
@@ -0,0 +1,195 @@
1Converting old watchdog drivers to the watchdog framework
2by Wolfram Sang <w.sang@pengutronix.de>
3=========================================================
4
5Before the watchdog framework came into the kernel, every driver had to
6implement the API on its own. Now, as the framework factored out the common
7components, those drivers can be lightened making it a user of the framework.
8This document shall guide you for this task. The necessary steps are described
9as well as things to look out for.
10
11
12Remove the file_operations struct
13---------------------------------
14
15Old drivers define their own file_operations for actions like open(), write(),
16etc... These are now handled by the framework and just call the driver when
17needed. So, in general, the 'file_operations' struct and assorted functions can
18go. Only very few driver-specific details have to be moved to other functions.
19Here is a overview of the functions and probably needed actions:
20
21- open: Everything dealing with resource management (file-open checks, magic
22 close preparations) can simply go. Device specific stuff needs to go to the
23 driver specific start-function. Note that for some drivers, the start-function
24 also serves as the ping-function. If that is the case and you need start/stop
25 to be balanced (clocks!), you are better off refactoring a separate start-function.
26
27- close: Same hints as for open apply.
28
29- write: Can simply go, all defined behaviour is taken care of by the framework,
30 i.e. ping on write and magic char ('V') handling.
31
32- ioctl: While the driver is allowed to have extensions to the IOCTL interface,
33 the most common ones are handled by the framework, supported by some assistance
34 from the driver:
35
36 WDIOC_GETSUPPORT:
37 Returns the mandatory watchdog_info struct from the driver
38
39 WDIOC_GETSTATUS:
40 Needs the status-callback defined, otherwise returns 0
41
42 WDIOC_GETBOOTSTATUS:
43 Needs the bootstatus member properly set. Make sure it is 0 if you
44 don't have further support!
45
46 WDIOC_SETOPTIONS:
47 No preparations needed
48
49 WDIOC_KEEPALIVE:
50 If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING
51 set
52
53 WDIOC_SETTIMEOUT:
54 Options in watchdog_info need to have WDIOF_SETTIMEOUT set
55 and a set_timeout-callback has to be defined. The core will also
56 do limit-checking, if min_timeout and max_timeout in the watchdog
57 device are set. All is optional.
58
59 WDIOC_GETTIMEOUT:
60 No preparations needed
61
62 Other IOCTLs can be served using the ioctl-callback. Note that this is mainly
63 intended for porting old drivers; new drivers should not invent private IOCTLs.
64 Private IOCTLs are processed first. When the callback returns with
65 -ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other error
66 is directly given to the user.
67
68Example conversion:
69
70-static const struct file_operations s3c2410wdt_fops = {
71- .owner = THIS_MODULE,
72- .llseek = no_llseek,
73- .write = s3c2410wdt_write,
74- .unlocked_ioctl = s3c2410wdt_ioctl,
75- .open = s3c2410wdt_open,
76- .release = s3c2410wdt_release,
77-};
78
79Check the functions for device-specific stuff and keep it for later
80refactoring. The rest can go.
81
82
83Remove the miscdevice
84---------------------
85
86Since the file_operations are gone now, you can also remove the 'struct
87miscdevice'. The framework will create it on watchdog_dev_register() called by
88watchdog_register_device().
89
90-static struct miscdevice s3c2410wdt_miscdev = {
91- .minor = WATCHDOG_MINOR,
92- .name = "watchdog",
93- .fops = &s3c2410wdt_fops,
94-};
95
96
97Remove obsolete includes and defines
98------------------------------------
99
100Because of the simplifications, a few defines are probably unused now. Remove
101them. Includes can be removed, too. For example:
102
103- #include <linux/fs.h>
104- #include <linux/miscdevice.h> (if MODULE_ALIAS_MISCDEV is not used)
105- #include <linux/uaccess.h> (if no custom IOCTLs are used)
106
107
108Add the watchdog operations
109---------------------------
110
111All possible callbacks are defined in 'struct watchdog_ops'. You can find it
112explained in 'watchdog-kernel-api.txt' in this directory. start(), stop() and
113owner must be set, the rest are optional. You will easily find corresponding
114functions in the old driver. Note that you will now get a pointer to the
115watchdog_device as a parameter to these functions, so you probably have to
116change the function header. Other changes are most likely not needed, because
117here simply happens the direct hardware access. If you have device-specific
118code left from the above steps, it should be refactored into these callbacks.
119
120Here is a simple example:
121
122+static struct watchdog_ops s3c2410wdt_ops = {
123+ .owner = THIS_MODULE,
124+ .start = s3c2410wdt_start,
125+ .stop = s3c2410wdt_stop,
126+ .ping = s3c2410wdt_keepalive,
127+ .set_timeout = s3c2410wdt_set_heartbeat,
128+};
129
130A typical function-header change looks like:
131
132-static void s3c2410wdt_keepalive(void)
133+static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
134 {
135...
136+
137+ return 0;
138 }
139
140...
141
142- s3c2410wdt_keepalive();
143+ s3c2410wdt_keepalive(&s3c2410_wdd);
144
145
146Add the watchdog device
147-----------------------
148
149Now we need to create a 'struct watchdog_device' and populate it with the
150necessary information for the framework. The struct is also explained in detail
151in 'watchdog-kernel-api.txt' in this directory. We pass it the mandatory
152watchdog_info struct and the newly created watchdog_ops. Often, old drivers
153have their own record-keeping for things like bootstatus and timeout using
154static variables. Those have to be converted to use the members in
155watchdog_device. Note that the timeout values are unsigned int. Some drivers
156use signed int, so this has to be converted, too.
157
158Here is a simple example for a watchdog device:
159
160+static struct watchdog_device s3c2410_wdd = {
161+ .info = &s3c2410_wdt_ident,
162+ .ops = &s3c2410wdt_ops,
163+};
164
165
166Register the watchdog device
167----------------------------
168
169Replace misc_register(&miscdev) with watchdog_register_device(&watchdog_dev).
170Make sure the return value gets checked and the error message, if present,
171still fits. Also convert the unregister case.
172
173- ret = misc_register(&s3c2410wdt_miscdev);
174+ ret = watchdog_register_device(&s3c2410_wdd);
175
176...
177
178- misc_deregister(&s3c2410wdt_miscdev);
179+ watchdog_unregister_device(&s3c2410_wdd);
180
181
182Update the Kconfig-entry
183------------------------
184
185The entry for the driver now needs to select WATCHDOG_CORE:
186
187+ select WATCHDOG_CORE
188
189
190Create a patch and send it to upstream
191--------------------------------------
192
193Make sure you understood Documentation/SubmittingPatches and send your patch to
194linux-watchdog@vger.kernel.org. We are looking forward to it :)
195
diff --git a/MAINTAINERS b/MAINTAINERS
index a6afe342f0fc..6388a96dc1c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2387,7 +2387,7 @@ F: include/linux/netfilter_bridge/ebt_*.h
2387F: net/bridge/netfilter/ebt*.c 2387F: net/bridge/netfilter/ebt*.c
2388 2388
2389ECRYPT FILE SYSTEM 2389ECRYPT FILE SYSTEM
2390M: Tyler Hicks <tyhicks@linux.vnet.ibm.com> 2390M: Tyler Hicks <tyhicks@canonical.com>
2391M: Dustin Kirkland <kirkland@canonical.com> 2391M: Dustin Kirkland <kirkland@canonical.com>
2392L: ecryptfs@vger.kernel.org 2392L: ecryptfs@vger.kernel.org
2393W: https://launchpad.net/ecryptfs 2393W: https://launchpad.net/ecryptfs
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fe6b0526b3a6..44789eff983f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -595,6 +595,7 @@ config ARCH_MMP
595 select TICK_ONESHOT 595 select TICK_ONESHOT
596 select PLAT_PXA 596 select PLAT_PXA
597 select SPARSE_IRQ 597 select SPARSE_IRQ
598 select GENERIC_ALLOCATOR
598 help 599 help
599 Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line. 600 Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
600 601
@@ -769,6 +770,7 @@ config ARCH_S3C64XX
769 select CPU_V6 770 select CPU_V6
770 select ARM_VIC 771 select ARM_VIC
771 select HAVE_CLK 772 select HAVE_CLK
773 select HAVE_TCM
772 select CLKDEV_LOOKUP 774 select CLKDEV_LOOKUP
773 select NO_IOPORT 775 select NO_IOPORT
774 select ARCH_USES_GETTIMEOFFSET 776 select ARCH_USES_GETTIMEOFFSET
@@ -777,9 +779,6 @@ config ARCH_S3C64XX
777 select SAMSUNG_CLKSRC 779 select SAMSUNG_CLKSRC
778 select SAMSUNG_IRQ_VIC_TIMER 780 select SAMSUNG_IRQ_VIC_TIMER
779 select S3C_GPIO_TRACK 781 select S3C_GPIO_TRACK
780 select S3C_GPIO_PULL_UPDOWN
781 select S3C_GPIO_CFG_S3C24XX
782 select S3C_GPIO_CFG_S3C64XX
783 select S3C_DEV_NAND 782 select S3C_DEV_NAND
784 select USB_ARCH_HAS_OHCI 783 select USB_ARCH_HAS_OHCI
785 select SAMSUNG_GPIOLIB_4BIT 784 select SAMSUNG_GPIOLIB_4BIT
@@ -838,8 +837,8 @@ config ARCH_S5PV210
838 help 837 help
839 Samsung S5PV210/S5PC110 series based systems 838 Samsung S5PV210/S5PC110 series based systems
840 839
841config ARCH_EXYNOS4 840config ARCH_EXYNOS
842 bool "Samsung EXYNOS4" 841 bool "SAMSUNG EXYNOS"
843 select CPU_V7 842 select CPU_V7
844 select ARCH_SPARSEMEM_ENABLE 843 select ARCH_SPARSEMEM_ENABLE
845 select ARCH_HAS_HOLES_MEMORYMODEL 844 select ARCH_HAS_HOLES_MEMORYMODEL
@@ -853,7 +852,7 @@ config ARCH_EXYNOS4
853 select HAVE_S3C2410_WATCHDOG if WATCHDOG 852 select HAVE_S3C2410_WATCHDOG if WATCHDOG
854 select NEED_MACH_MEMORY_H 853 select NEED_MACH_MEMORY_H
855 help 854 help
856 Samsung EXYNOS4 series based systems 855 Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
857 856
858config ARCH_SHARK 857config ARCH_SHARK
859 bool "Shark" 858 bool "Shark"
@@ -1080,7 +1079,7 @@ source "arch/arm/mach-s5pc100/Kconfig"
1080 1079
1081source "arch/arm/mach-s5pv210/Kconfig" 1080source "arch/arm/mach-s5pv210/Kconfig"
1082 1081
1083source "arch/arm/mach-exynos4/Kconfig" 1082source "arch/arm/mach-exynos/Kconfig"
1084 1083
1085source "arch/arm/mach-shmobile/Kconfig" 1084source "arch/arm/mach-shmobile/Kconfig"
1086 1085
@@ -2212,7 +2211,7 @@ menu "Power management options"
2212source "kernel/power/Kconfig" 2211source "kernel/power/Kconfig"
2213 2212
2214config ARCH_SUSPEND_POSSIBLE 2213config ARCH_SUSPEND_POSSIBLE
2215 depends on !ARCH_S5P64X0 && !ARCH_S5PC100 2214 depends on !ARCH_S5PC100
2216 depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \ 2215 depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
2217 CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE 2216 CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
2218 def_bool y 2217 def_bool y
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index b7c2d377a6c2..dfcf3b033e10 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -180,7 +180,7 @@ machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
180machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 180machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
181machine-$(CONFIG_ARCH_S5PC100) := s5pc100 181machine-$(CONFIG_ARCH_S5PC100) := s5pc100
182machine-$(CONFIG_ARCH_S5PV210) := s5pv210 182machine-$(CONFIG_ARCH_S5PV210) := s5pv210
183machine-$(CONFIG_ARCH_EXYNOS4) := exynos4 183machine-$(CONFIG_ARCH_EXYNOS4) := exynos
184machine-$(CONFIG_ARCH_SA1100) := sa1100 184machine-$(CONFIG_ARCH_SA1100) := sa1100
185machine-$(CONFIG_ARCH_SHARK) := shark 185machine-$(CONFIG_ARCH_SHARK) := shark
186machine-$(CONFIG_ARCH_SHMOBILE) := shmobile 186machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig
index cd40bb56e568..bffe68e190a3 100644
--- a/arch/arm/configs/exynos4_defconfig
+++ b/arch/arm/configs/exynos4_defconfig
@@ -4,19 +4,18 @@ CONFIG_KALLSYMS_ALL=y
4CONFIG_MODULES=y 4CONFIG_MODULES=y
5CONFIG_MODULE_UNLOAD=y 5CONFIG_MODULE_UNLOAD=y
6# CONFIG_BLK_DEV_BSG is not set 6# CONFIG_BLK_DEV_BSG is not set
7CONFIG_ARCH_EXYNOS4=y 7CONFIG_ARCH_EXYNOS=y
8CONFIG_S3C_LOWLEVEL_UART_PORT=1 8CONFIG_S3C_LOWLEVEL_UART_PORT=1
9CONFIG_MACH_SMDKC210=y 9CONFIG_MACH_SMDKC210=y
10CONFIG_MACH_SMDKV310=y
11CONFIG_MACH_ARMLEX4210=y 10CONFIG_MACH_ARMLEX4210=y
12CONFIG_MACH_UNIVERSAL_C210=y 11CONFIG_MACH_UNIVERSAL_C210=y
13CONFIG_MACH_NURI=y 12CONFIG_MACH_NURI=y
14CONFIG_MACH_ORIGEN=y 13CONFIG_MACH_ORIGEN=y
14CONFIG_MACH_SMDK4412=y
15CONFIG_NO_HZ=y 15CONFIG_NO_HZ=y
16CONFIG_HIGH_RES_TIMERS=y 16CONFIG_HIGH_RES_TIMERS=y
17CONFIG_SMP=y 17CONFIG_SMP=y
18CONFIG_NR_CPUS=2 18CONFIG_NR_CPUS=2
19CONFIG_HOTPLUG_CPU=y
20CONFIG_PREEMPT=y 19CONFIG_PREEMPT=y
21CONFIG_AEABI=y 20CONFIG_AEABI=y
22CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" 21CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
@@ -61,13 +60,9 @@ CONFIG_DETECT_HUNG_TASK=y
61CONFIG_DEBUG_RT_MUTEXES=y 60CONFIG_DEBUG_RT_MUTEXES=y
62CONFIG_DEBUG_SPINLOCK=y 61CONFIG_DEBUG_SPINLOCK=y
63CONFIG_DEBUG_MUTEXES=y 62CONFIG_DEBUG_MUTEXES=y
64CONFIG_DEBUG_SPINLOCK_SLEEP=y
65CONFIG_DEBUG_INFO=y 63CONFIG_DEBUG_INFO=y
66# CONFIG_RCU_CPU_STALL_DETECTOR is not set
67CONFIG_SYSCTL_SYSCALL_CHECK=y 64CONFIG_SYSCTL_SYSCALL_CHECK=y
68CONFIG_DEBUG_USER=y 65CONFIG_DEBUG_USER=y
69CONFIG_DEBUG_ERRORS=y
70CONFIG_DEBUG_LL=y 66CONFIG_DEBUG_LL=y
71CONFIG_EARLY_PRINTK=y 67CONFIG_EARLY_PRINTK=y
72CONFIG_DEBUG_S3C_UART=1
73CONFIG_CRC_CCITT=y 68CONFIG_CRC_CCITT=y
diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h
index e4a04e4e5627..33c78d7af2e1 100644
--- a/arch/arm/include/asm/hardware/pl080.h
+++ b/arch/arm/include/asm/hardware/pl080.h
@@ -21,6 +21,9 @@
21 * OneNAND features. 21 * OneNAND features.
22*/ 22*/
23 23
24#ifndef ASM_PL080_H
25#define ASM_PL080_H
26
24#define PL080_INT_STATUS (0x00) 27#define PL080_INT_STATUS (0x00)
25#define PL080_TC_STATUS (0x04) 28#define PL080_TC_STATUS (0x04)
26#define PL080_TC_CLEAR (0x08) 29#define PL080_TC_CLEAR (0x08)
@@ -138,3 +141,4 @@ struct pl080s_lli {
138 u32 control1; 141 u32 control1;
139}; 142};
140 143
144#endif /* ASM_PL080_H */
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index fbaae4772b91..960e9de47e1e 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -15,6 +15,8 @@
15 15
16#include <asm-generic/gpio.h> 16#include <asm-generic/gpio.h>
17 17
18#define __ARM_GPIOLIB_COMPLEX
19
18/* The inline versions use the static inlines in the driver header */ 20/* The inline versions use the static inlines in the driver header */
19#include "gpio-davinci.h" 21#include "gpio-davinci.h"
20 22
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos/Kconfig
index a65273598036..724ec0f3560d 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -1,4 +1,4 @@
1# arch/arm/mach-exynos4/Kconfig 1# arch/arm/mach-exynos/Kconfig
2# 2#
3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/ 4# http://www.samsung.com/
@@ -7,22 +7,47 @@
7 7
8# Configuration options for the EXYNOS4 8# Configuration options for the EXYNOS4
9 9
10if ARCH_EXYNOS4 10if ARCH_EXYNOS
11
12menu "SAMSUNG EXYNOS SoCs Support"
13
14choice
15 prompt "EXYNOS System Type"
16 default ARCH_EXYNOS4
17
18config ARCH_EXYNOS4
19 bool "SAMSUNG EXYNOS4"
20 help
21 Samsung EXYNOS4 SoCs based systems
22
23endchoice
24
25comment "EXYNOS SoCs"
11 26
12config CPU_EXYNOS4210 27config CPU_EXYNOS4210
13 bool 28 bool "SAMSUNG EXYNOS4210"
14 select S3C_PL330_DMA 29 default y
30 depends on ARCH_EXYNOS4
31 select SAMSUNG_DMADEV
15 select ARM_CPU_SUSPEND if PM 32 select ARM_CPU_SUSPEND if PM
33 select S5P_PM if PM
34 select S5P_SLEEP if PM
16 help 35 help
17 Enable EXYNOS4210 CPU support 36 Enable EXYNOS4210 CPU support
18 37
19config SOC_EXYNOS4212 38config SOC_EXYNOS4212
20 bool 39 bool "SAMSUNG EXYNOS4212"
40 default y
41 depends on ARCH_EXYNOS4
42 select S5P_PM if PM
43 select S5P_SLEEP if PM
21 help 44 help
22 Enable EXYNOS4212 SoC support 45 Enable EXYNOS4212 SoC support
23 46
24config SOC_EXYNOS4412 47config SOC_EXYNOS4412
25 bool 48 bool "SAMSUNG EXYNOS4412"
49 default y
50 depends on ARCH_EXYNOS4
26 help 51 help
27 Enable EXYNOS4412 SoC support 52 Enable EXYNOS4412 SoC support
28 53
@@ -120,7 +145,7 @@ config EXYNOS4_SETUP_USB_PHY
120 145
121# machine support 146# machine support
122 147
123menu "EXYNOS4 Machines" 148if ARCH_EXYNOS4
124 149
125comment "EXYNOS4210 Boards" 150comment "EXYNOS4210 Boards"
126 151
@@ -137,6 +162,14 @@ config MACH_SMDKV310
137 select S3C_DEV_RTC 162 select S3C_DEV_RTC
138 select S3C_DEV_WDT 163 select S3C_DEV_WDT
139 select S3C_DEV_I2C1 164 select S3C_DEV_I2C1
165 select S5P_DEV_FIMC0
166 select S5P_DEV_FIMC1
167 select S5P_DEV_FIMC2
168 select S5P_DEV_FIMC3
169 select S5P_DEV_I2C_HDMIPHY
170 select S5P_DEV_MFC
171 select S5P_DEV_TV
172 select S5P_DEV_USB_EHCI
140 select S3C_DEV_HSMMC 173 select S3C_DEV_HSMMC
141 select S3C_DEV_HSMMC1 174 select S3C_DEV_HSMMC1
142 select S3C_DEV_HSMMC2 175 select S3C_DEV_HSMMC2
@@ -151,6 +184,7 @@ config MACH_SMDKV310
151 select EXYNOS4_SETUP_I2C1 184 select EXYNOS4_SETUP_I2C1
152 select EXYNOS4_SETUP_KEYPAD 185 select EXYNOS4_SETUP_KEYPAD
153 select EXYNOS4_SETUP_SDHCI 186 select EXYNOS4_SETUP_SDHCI
187 select EXYNOS4_SETUP_USB_PHY
154 help 188 help
155 Machine support for Samsung SMDKV310 189 Machine support for Samsung SMDKV310
156 190
@@ -176,19 +210,26 @@ config MACH_UNIVERSAL_C210
176 select S5P_DEV_FIMC1 210 select S5P_DEV_FIMC1
177 select S5P_DEV_FIMC2 211 select S5P_DEV_FIMC2
178 select S5P_DEV_FIMC3 212 select S5P_DEV_FIMC3
213 select S5P_DEV_CSIS0
214 select S5P_DEV_FIMD0
179 select S3C_DEV_HSMMC 215 select S3C_DEV_HSMMC
180 select S3C_DEV_HSMMC2 216 select S3C_DEV_HSMMC2
181 select S3C_DEV_HSMMC3 217 select S3C_DEV_HSMMC3
182 select S3C_DEV_I2C1 218 select S3C_DEV_I2C1
183 select S3C_DEV_I2C3 219 select S3C_DEV_I2C3
184 select S3C_DEV_I2C5 220 select S3C_DEV_I2C5
221 select S5P_DEV_I2C_HDMIPHY
185 select S5P_DEV_MFC 222 select S5P_DEV_MFC
186 select S5P_DEV_ONENAND 223 select S5P_DEV_ONENAND
224 select S5P_DEV_TV
187 select EXYNOS4_DEV_PD 225 select EXYNOS4_DEV_PD
226 select EXYNOS4_SETUP_FIMD0
188 select EXYNOS4_SETUP_I2C1 227 select EXYNOS4_SETUP_I2C1
189 select EXYNOS4_SETUP_I2C3 228 select EXYNOS4_SETUP_I2C3
190 select EXYNOS4_SETUP_I2C5 229 select EXYNOS4_SETUP_I2C5
191 select EXYNOS4_SETUP_SDHCI 230 select EXYNOS4_SETUP_SDHCI
231 select EXYNOS4_SETUP_FIMC
232 select S5P_SETUP_MIPIPHY
192 help 233 help
193 Machine support for Samsung Mobile Universal S5PC210 Reference 234 Machine support for Samsung Mobile Universal S5PC210 Reference
194 Board. 235 Board.
@@ -196,21 +237,33 @@ config MACH_UNIVERSAL_C210
196config MACH_NURI 237config MACH_NURI
197 bool "Mobile NURI Board" 238 bool "Mobile NURI Board"
198 select CPU_EXYNOS4210 239 select CPU_EXYNOS4210
240 select S5P_GPIO_INT
199 select S3C_DEV_WDT 241 select S3C_DEV_WDT
242 select S3C_DEV_RTC
243 select S5P_DEV_FIMD0
200 select S3C_DEV_HSMMC 244 select S3C_DEV_HSMMC
201 select S3C_DEV_HSMMC2 245 select S3C_DEV_HSMMC2
202 select S3C_DEV_HSMMC3 246 select S3C_DEV_HSMMC3
203 select S3C_DEV_I2C1 247 select S3C_DEV_I2C1
204 select S3C_DEV_I2C3 248 select S3C_DEV_I2C3
205 select S3C_DEV_I2C5 249 select S3C_DEV_I2C5
250 select S5P_DEV_CSIS0
251 select S5P_DEV_FIMC0
252 select S5P_DEV_FIMC1
253 select S5P_DEV_FIMC2
254 select S5P_DEV_FIMC3
206 select S5P_DEV_MFC 255 select S5P_DEV_MFC
207 select S5P_DEV_USB_EHCI 256 select S5P_DEV_USB_EHCI
257 select S5P_SETUP_MIPIPHY
208 select EXYNOS4_DEV_PD 258 select EXYNOS4_DEV_PD
259 select EXYNOS4_SETUP_FIMC
260 select EXYNOS4_SETUP_FIMD0
209 select EXYNOS4_SETUP_I2C1 261 select EXYNOS4_SETUP_I2C1
210 select EXYNOS4_SETUP_I2C3 262 select EXYNOS4_SETUP_I2C3
211 select EXYNOS4_SETUP_I2C5 263 select EXYNOS4_SETUP_I2C5
212 select EXYNOS4_SETUP_SDHCI 264 select EXYNOS4_SETUP_SDHCI
213 select EXYNOS4_SETUP_USB_PHY 265 select EXYNOS4_SETUP_USB_PHY
266 select S5P_SETUP_MIPIPHY
214 select SAMSUNG_DEV_PWM 267 select SAMSUNG_DEV_PWM
215 select SAMSUNG_DEV_ADC 268 select SAMSUNG_DEV_ADC
216 help 269 help
@@ -221,8 +274,23 @@ config MACH_ORIGEN
221 select CPU_EXYNOS4210 274 select CPU_EXYNOS4210
222 select S3C_DEV_RTC 275 select S3C_DEV_RTC
223 select S3C_DEV_WDT 276 select S3C_DEV_WDT
277 select S3C_DEV_HSMMC
224 select S3C_DEV_HSMMC2 278 select S3C_DEV_HSMMC2
279 select S5P_DEV_FIMC0
280 select S5P_DEV_FIMC1
281 select S5P_DEV_FIMC2
282 select S5P_DEV_FIMC3
283 select S5P_DEV_FIMD0
284 select S5P_DEV_I2C_HDMIPHY
285 select S5P_DEV_MFC
286 select S5P_DEV_TV
287 select S5P_DEV_USB_EHCI
288 select SAMSUNG_DEV_BACKLIGHT
289 select SAMSUNG_DEV_PWM
290 select EXYNOS4_DEV_PD
291 select EXYNOS4_SETUP_FIMD0
225 select EXYNOS4_SETUP_SDHCI 292 select EXYNOS4_SETUP_SDHCI
293 select EXYNOS4_SETUP_USB_PHY
226 help 294 help
227 Machine support for ORIGEN based on Samsung EXYNOS4210 295 Machine support for ORIGEN based on Samsung EXYNOS4210
228 296
@@ -257,12 +325,11 @@ config MACH_SMDK4412
257 select MACH_SMDK4212 325 select MACH_SMDK4212
258 help 326 help
259 Machine support for Samsung SMDK4412 327 Machine support for Samsung SMDK4412
328endif
260 329
261endmenu 330if ARCH_EXYNOS4
262
263comment "Configuration for HSMMC bus width"
264 331
265menu "Use 8-bit bus width" 332comment "Configuration for HSMMC 8-bit bus width"
266 333
267config EXYNOS4_SDHCI_CH0_8BIT 334config EXYNOS4_SDHCI_CH0_8BIT
268 bool "Channel 0 with 8-bit bus" 335 bool "Channel 0 with 8-bit bus"
@@ -275,6 +342,7 @@ config EXYNOS4_SDHCI_CH2_8BIT
275 help 342 help
276 Support HSMMC Channel 2 8-bit bus. 343 Support HSMMC Channel 2 8-bit bus.
277 If selected, Channel 3 is disabled. 344 If selected, Channel 3 is disabled.
345endif
278 346
279endmenu 347endmenu
280 348
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos/Makefile
index c9b2e1f97e44..59069a35e40b 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -1,4 +1,4 @@
1# arch/arm/mach-exynos4/Makefile 1# arch/arm/mach-exynos/Makefile
2# 2#
3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/ 4# http://www.samsung.com/
@@ -12,11 +12,11 @@ obj- :=
12 12
13# Core support for EXYNOS4 system 13# Core support for EXYNOS4 system
14 14
15obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o 15obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o
16obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o irq-eint.o dma.o pmu.o 16obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o dma.o pmu.o
17obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o 17obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
18obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o 18obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
19obj-$(CONFIG_PM) += pm.o sleep.o 19obj-$(CONFIG_PM) += pm.o
20obj-$(CONFIG_CPU_IDLE) += cpuidle.o 20obj-$(CONFIG_CPU_IDLE) += cpuidle.o
21 21
22obj-$(CONFIG_SMP) += platsmp.o headsmp.o 22obj-$(CONFIG_SMP) += platsmp.o headsmp.o
@@ -39,11 +39,11 @@ obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o
39 39
40# device support 40# device support
41 41
42obj-y += dev-audio.o 42obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
43obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o 43obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
44obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o 44obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
45obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o 45obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
46obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o 46obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
47 47
48obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o 48obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
49obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o 49obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
@@ -57,5 +57,4 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
57obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o 57obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
58obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o 58obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
59obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 59obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
60
61obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o 60obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
index b9862e22bf10..b9862e22bf10 100644
--- a/arch/arm/mach-exynos4/Makefile.boot
+++ b/arch/arm/mach-exynos/Makefile.boot
diff --git a/arch/arm/mach-exynos4/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index b9d5ef670eb4..b9d5ef670eb4 100644
--- a/arch/arm/mach-exynos4/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
diff --git a/arch/arm/mach-exynos4/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index 77d5decb34fd..77d5decb34fd 100644
--- a/arch/arm/mach-exynos4/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos/clock.c
index 0d59be3fa1fe..2894f0adef5c 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -111,6 +111,11 @@ struct clk clk_sclk_usbphy1 = {
111 .name = "sclk_usbphy1", 111 .name = "sclk_usbphy1",
112}; 112};
113 113
114static struct clk dummy_apb_pclk = {
115 .name = "apb_pclk",
116 .id = -1,
117};
118
114static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable) 119static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
115{ 120{
116 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable); 121 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
@@ -146,6 +151,11 @@ static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
146 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable); 151 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
147} 152}
148 153
154static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
155{
156 return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable);
157}
158
149static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable) 159static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
150{ 160{
151 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable); 161 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
@@ -186,6 +196,16 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
186 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable); 196 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
187} 197}
188 198
199static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
200{
201 return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
202}
203
204static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
205{
206 return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
207}
208
189/* Core list of CMU_CPU side */ 209/* Core list of CMU_CPU side */
190 210
191static struct clksrc_clk clk_mout_apll = { 211static struct clksrc_clk clk_mout_apll = {
@@ -503,13 +523,43 @@ static struct clk init_clocks_off[] = {
503 .enable = exynos4_clk_ip_fsys_ctrl, 523 .enable = exynos4_clk_ip_fsys_ctrl,
504 .ctrlbit = (1 << 9), 524 .ctrlbit = (1 << 9),
505 }, { 525 }, {
506 .name = "pdma", 526 .name = "dac",
507 .devname = "s3c-pl330.0", 527 .devname = "s5p-sdo",
528 .enable = exynos4_clk_ip_tv_ctrl,
529 .ctrlbit = (1 << 2),
530 }, {
531 .name = "mixer",
532 .devname = "s5p-mixer",
533 .enable = exynos4_clk_ip_tv_ctrl,
534 .ctrlbit = (1 << 1),
535 }, {
536 .name = "vp",
537 .devname = "s5p-mixer",
538 .enable = exynos4_clk_ip_tv_ctrl,
539 .ctrlbit = (1 << 0),
540 }, {
541 .name = "hdmi",
542 .devname = "exynos4-hdmi",
543 .enable = exynos4_clk_ip_tv_ctrl,
544 .ctrlbit = (1 << 3),
545 }, {
546 .name = "hdmiphy",
547 .devname = "exynos4-hdmi",
548 .enable = exynos4_clk_hdmiphy_ctrl,
549 .ctrlbit = (1 << 0),
550 }, {
551 .name = "dacphy",
552 .devname = "s5p-sdo",
553 .enable = exynos4_clk_dac_ctrl,
554 .ctrlbit = (1 << 0),
555 }, {
556 .name = "dma",
557 .devname = "dma-pl330.0",
508 .enable = exynos4_clk_ip_fsys_ctrl, 558 .enable = exynos4_clk_ip_fsys_ctrl,
509 .ctrlbit = (1 << 0), 559 .ctrlbit = (1 << 0),
510 }, { 560 }, {
511 .name = "pdma", 561 .name = "dma",
512 .devname = "s3c-pl330.1", 562 .devname = "dma-pl330.1",
513 .enable = exynos4_clk_ip_fsys_ctrl, 563 .enable = exynos4_clk_ip_fsys_ctrl,
514 .ctrlbit = (1 << 1), 564 .ctrlbit = (1 << 1),
515 }, { 565 }, {
@@ -630,6 +680,12 @@ static struct clk init_clocks_off[] = {
630 .enable = exynos4_clk_ip_peril_ctrl, 680 .enable = exynos4_clk_ip_peril_ctrl,
631 .ctrlbit = (1 << 13), 681 .ctrlbit = (1 << 13),
632 }, { 682 }, {
683 .name = "i2c",
684 .devname = "s3c2440-hdmiphy-i2c",
685 .parent = &clk_aclk_100.clk,
686 .enable = exynos4_clk_ip_peril_ctrl,
687 .ctrlbit = (1 << 14),
688 }, {
633 .name = "SYSMMU_MDMA", 689 .name = "SYSMMU_MDMA",
634 .enable = exynos4_clk_ip_image_ctrl, 690 .enable = exynos4_clk_ip_image_ctrl,
635 .ctrlbit = (1 << 5), 691 .ctrlbit = (1 << 5),
@@ -831,6 +887,81 @@ static struct clksrc_sources clkset_mout_mfc = {
831 .nr_sources = ARRAY_SIZE(clkset_mout_mfc_list), 887 .nr_sources = ARRAY_SIZE(clkset_mout_mfc_list),
832}; 888};
833 889
890static struct clk *clkset_sclk_dac_list[] = {
891 [0] = &clk_sclk_vpll.clk,
892 [1] = &clk_sclk_hdmiphy,
893};
894
895static struct clksrc_sources clkset_sclk_dac = {
896 .sources = clkset_sclk_dac_list,
897 .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list),
898};
899
900static struct clksrc_clk clk_sclk_dac = {
901 .clk = {
902 .name = "sclk_dac",
903 .enable = exynos4_clksrc_mask_tv_ctrl,
904 .ctrlbit = (1 << 8),
905 },
906 .sources = &clkset_sclk_dac,
907 .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 },
908};
909
910static struct clksrc_clk clk_sclk_pixel = {
911 .clk = {
912 .name = "sclk_pixel",
913 .parent = &clk_sclk_vpll.clk,
914 },
915 .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 },
916};
917
918static struct clk *clkset_sclk_hdmi_list[] = {
919 [0] = &clk_sclk_pixel.clk,
920 [1] = &clk_sclk_hdmiphy,
921};
922
923static struct clksrc_sources clkset_sclk_hdmi = {
924 .sources = clkset_sclk_hdmi_list,
925 .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list),
926};
927
928static struct clksrc_clk clk_sclk_hdmi = {
929 .clk = {
930 .name = "sclk_hdmi",
931 .enable = exynos4_clksrc_mask_tv_ctrl,
932 .ctrlbit = (1 << 0),
933 },
934 .sources = &clkset_sclk_hdmi,
935 .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 },
936};
937
938static struct clk *clkset_sclk_mixer_list[] = {
939 [0] = &clk_sclk_dac.clk,
940 [1] = &clk_sclk_hdmi.clk,
941};
942
943static struct clksrc_sources clkset_sclk_mixer = {
944 .sources = clkset_sclk_mixer_list,
945 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
946};
947
948static struct clksrc_clk clk_sclk_mixer = {
949 .clk = {
950 .name = "sclk_mixer",
951 .enable = exynos4_clksrc_mask_tv_ctrl,
952 .ctrlbit = (1 << 4),
953 },
954 .sources = &clkset_sclk_mixer,
955 .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 },
956};
957
958static struct clksrc_clk *sclk_tv[] = {
959 &clk_sclk_dac,
960 &clk_sclk_pixel,
961 &clk_sclk_hdmi,
962 &clk_sclk_mixer,
963};
964
834static struct clksrc_clk clk_dout_mmc0 = { 965static struct clksrc_clk clk_dout_mmc0 = {
835 .clk = { 966 .clk = {
836 .name = "dout_mmc0", 967 .name = "dout_mmc0",
@@ -1157,6 +1288,71 @@ static struct clk_ops exynos4_fout_apll_ops = {
1157 .get_rate = exynos4_fout_apll_get_rate, 1288 .get_rate = exynos4_fout_apll_get_rate,
1158}; 1289};
1159 1290
1291static u32 vpll_div[][8] = {
1292 { 54000000, 3, 53, 3, 1024, 0, 17, 0 },
1293 { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
1294};
1295
1296static unsigned long exynos4_vpll_get_rate(struct clk *clk)
1297{
1298 return clk->rate;
1299}
1300
1301static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
1302{
1303 unsigned int vpll_con0, vpll_con1 = 0;
1304 unsigned int i;
1305
1306 /* Return if nothing changed */
1307 if (clk->rate == rate)
1308 return 0;
1309
1310 vpll_con0 = __raw_readl(S5P_VPLL_CON0);
1311 vpll_con0 &= ~(0x1 << 27 | \
1312 PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1313 PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1314 PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1315
1316 vpll_con1 = __raw_readl(S5P_VPLL_CON1);
1317 vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \
1318 PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
1319 PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
1320
1321 for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1322 if (vpll_div[i][0] == rate) {
1323 vpll_con0 |= vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
1324 vpll_con0 |= vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
1325 vpll_con0 |= vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
1326 vpll_con1 |= vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
1327 vpll_con1 |= vpll_div[i][5] << PLL46XX_MFR_SHIFT;
1328 vpll_con1 |= vpll_div[i][6] << PLL46XX_MRR_SHIFT;
1329 vpll_con0 |= vpll_div[i][7] << 27;
1330 break;
1331 }
1332 }
1333
1334 if (i == ARRAY_SIZE(vpll_div)) {
1335 printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1336 __func__);
1337 return -EINVAL;
1338 }
1339
1340 __raw_writel(vpll_con0, S5P_VPLL_CON0);
1341 __raw_writel(vpll_con1, S5P_VPLL_CON1);
1342
1343 /* Wait for VPLL lock */
1344 while (!(__raw_readl(S5P_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
1345 continue;
1346
1347 clk->rate = rate;
1348 return 0;
1349}
1350
1351static struct clk_ops exynos4_vpll_ops = {
1352 .get_rate = exynos4_vpll_get_rate,
1353 .set_rate = exynos4_vpll_set_rate,
1354};
1355
1160void __init_or_cpufreq exynos4_setup_clocks(void) 1356void __init_or_cpufreq exynos4_setup_clocks(void)
1161{ 1357{
1162 struct clk *xtal_clk; 1358 struct clk *xtal_clk;
@@ -1214,6 +1410,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
1214 clk_fout_apll.ops = &exynos4_fout_apll_ops; 1410 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1215 clk_fout_mpll.rate = mpll; 1411 clk_fout_mpll.rate = mpll;
1216 clk_fout_epll.rate = epll; 1412 clk_fout_epll.rate = epll;
1413 clk_fout_vpll.ops = &exynos4_vpll_ops;
1217 clk_fout_vpll.rate = vpll; 1414 clk_fout_vpll.rate = vpll;
1218 1415
1219 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", 1416 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
@@ -1241,7 +1438,10 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
1241} 1438}
1242 1439
1243static struct clk *clks[] __initdata = { 1440static struct clk *clks[] __initdata = {
1244 /* Nothing here yet */ 1441 &clk_sclk_hdmi27m,
1442 &clk_sclk_hdmiphy,
1443 &clk_sclk_usbphy0,
1444 &clk_sclk_usbphy1,
1245}; 1445};
1246 1446
1247#ifdef CONFIG_PM_SLEEP 1447#ifdef CONFIG_PM_SLEEP
@@ -1275,6 +1475,9 @@ void __init exynos4_register_clocks(void)
1275 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 1475 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1276 s3c_register_clksrc(sysclks[ptr], 1); 1476 s3c_register_clksrc(sysclks[ptr], 1);
1277 1477
1478 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1479 s3c_register_clksrc(sclk_tv[ptr], 1);
1480
1278 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1481 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1279 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1482 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1280 1483
@@ -1282,5 +1485,7 @@ void __init exynos4_register_clocks(void)
1282 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1485 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1283 1486
1284 register_syscore_ops(&exynos4_clock_syscore_ops); 1487 register_syscore_ops(&exynos4_clock_syscore_ops);
1488 s3c24xx_register_clock(&dummy_apb_pclk);
1489
1285 s3c_pwmclk_init(); 1490 s3c_pwmclk_init();
1286} 1491}
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos/cpu.c
index a348434f17b5..90ec247f3b37 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos/cpu.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-exynos4/cpu.c 1/* linux/arch/arm/mach-exynos/cpu.c
2 * 2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -28,6 +28,7 @@
28#include <plat/fimc-core.h> 28#include <plat/fimc-core.h>
29#include <plat/iic-core.h> 29#include <plat/iic-core.h>
30#include <plat/reset.h> 30#include <plat/reset.h>
31#include <plat/tv-core.h>
31 32
32#include <mach/regs-irq.h> 33#include <mach/regs-irq.h>
33#include <mach/regs-pmu.h> 34#include <mach/regs-pmu.h>
@@ -39,28 +40,47 @@ extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
39extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); 40extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
40 41
41/* Initial IO mappings */ 42/* Initial IO mappings */
42static struct map_desc exynos4_iodesc[] __initdata = { 43static struct map_desc exynos_iodesc[] __initdata = {
43 { 44 {
44 .virtual = (unsigned long)S5P_VA_SYSTIMER, 45 .virtual = (unsigned long)S5P_VA_SYSTIMER,
45 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), 46 .pfn = __phys_to_pfn(EXYNOS_PA_SYSTIMER),
46 .length = SZ_4K, 47 .length = SZ_4K,
47 .type = MT_DEVICE,
48 }, {
49 .virtual = (unsigned long)S5P_VA_CMU,
50 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
51 .length = SZ_128K,
52 .type = MT_DEVICE, 48 .type = MT_DEVICE,
53 }, { 49 }, {
54 .virtual = (unsigned long)S5P_VA_PMU, 50 .virtual = (unsigned long)S5P_VA_PMU,
55 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU), 51 .pfn = __phys_to_pfn(EXYNOS_PA_PMU),
56 .length = SZ_64K, 52 .length = SZ_64K,
57 .type = MT_DEVICE, 53 .type = MT_DEVICE,
58 }, { 54 }, {
59 .virtual = (unsigned long)S5P_VA_COMBINER_BASE, 55 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
60 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER), 56 .pfn = __phys_to_pfn(EXYNOS_PA_COMBINER),
61 .length = SZ_4K, 57 .length = SZ_4K,
62 .type = MT_DEVICE, 58 .type = MT_DEVICE,
63 }, { 59 }, {
60 .virtual = (unsigned long)S5P_VA_GIC_CPU,
61 .pfn = __phys_to_pfn(EXYNOS_PA_GIC_CPU),
62 .length = SZ_64K,
63 .type = MT_DEVICE,
64 }, {
65 .virtual = (unsigned long)S5P_VA_GIC_DIST,
66 .pfn = __phys_to_pfn(EXYNOS_PA_GIC_DIST),
67 .length = SZ_64K,
68 .type = MT_DEVICE,
69 }, {
70 .virtual = (unsigned long)S3C_VA_UART,
71 .pfn = __phys_to_pfn(S3C_PA_UART),
72 .length = SZ_512K,
73 .type = MT_DEVICE,
74 },
75};
76
77static struct map_desc exynos4_iodesc[] __initdata = {
78 {
79 .virtual = (unsigned long)S5P_VA_CMU,
80 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
81 .length = SZ_128K,
82 .type = MT_DEVICE,
83 }, {
64 .virtual = (unsigned long)S5P_VA_COREPERI_BASE, 84 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
65 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI), 85 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
66 .length = SZ_8K, 86 .length = SZ_8K,
@@ -91,11 +111,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
91 .length = SZ_4K, 111 .length = SZ_4K,
92 .type = MT_DEVICE, 112 .type = MT_DEVICE,
93 }, { 113 }, {
94 .virtual = (unsigned long)S3C_VA_UART,
95 .pfn = __phys_to_pfn(S3C_PA_UART),
96 .length = SZ_512K,
97 .type = MT_DEVICE,
98 }, {
99 .virtual = (unsigned long)S5P_VA_SROMC, 114 .virtual = (unsigned long)S5P_VA_SROMC,
100 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), 115 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
101 .length = SZ_4K, 116 .length = SZ_4K,
@@ -105,16 +120,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
105 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), 120 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
106 .length = SZ_4K, 121 .length = SZ_4K,
107 .type = MT_DEVICE, 122 .type = MT_DEVICE,
108 }, {
109 .virtual = (unsigned long)S5P_VA_GIC_CPU,
110 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
111 .length = SZ_64K,
112 .type = MT_DEVICE,
113 }, {
114 .virtual = (unsigned long)S5P_VA_GIC_DIST,
115 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
116 .length = SZ_64K,
117 .type = MT_DEVICE,
118 }, 123 },
119}; 124};
120 125
@@ -136,7 +141,7 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
136 }, 141 },
137}; 142};
138 143
139static void exynos4_idle(void) 144static void exynos_idle(void)
140{ 145{
141 if (!need_resched()) 146 if (!need_resched())
142 cpu_do_idle(); 147 cpu_do_idle();
@@ -150,12 +155,13 @@ static void exynos4_sw_reset(void)
150} 155}
151 156
152/* 157/*
153 * exynos4_map_io 158 * exynos_map_io
154 * 159 *
155 * register the standard cpu IO areas 160 * register the standard cpu IO areas
156 */ 161 */
157void __init exynos4_map_io(void) 162void __init exynos4_map_io(void)
158{ 163{
164 iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
159 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); 165 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
160 166
161 if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0) 167 if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
@@ -182,6 +188,7 @@ void __init exynos4_map_io(void)
182 s3c_i2c2_setname("s3c2440-i2c"); 188 s3c_i2c2_setname("s3c2440-i2c");
183 189
184 s5p_fb_setname(0, "exynos4-fb"); 190 s5p_fb_setname(0, "exynos4-fb");
191 s5p_hdmi_setname("exynos4-hdmi");
185} 192}
186 193
187void __init exynos4_init_clocks(int xtal) 194void __init exynos4_init_clocks(int xtal)
@@ -248,7 +255,6 @@ static int __init exynos4_core_init(void)
248{ 255{
249 return sysdev_class_register(&exynos4_sysclass); 256 return sysdev_class_register(&exynos4_sysclass);
250} 257}
251
252core_initcall(exynos4_core_init); 258core_initcall(exynos4_core_init);
253 259
254#ifdef CONFIG_CACHE_L2X0 260#ifdef CONFIG_CACHE_L2X0
@@ -277,15 +283,16 @@ static int __init exynos4_l2x0_cache_init(void)
277early_initcall(exynos4_l2x0_cache_init); 283early_initcall(exynos4_l2x0_cache_init);
278#endif 284#endif
279 285
280int __init exynos4_init(void) 286int __init exynos_init(void)
281{ 287{
282 printk(KERN_INFO "EXYNOS4: Initializing architecture\n"); 288 printk(KERN_INFO "EXYNOS: Initializing architecture\n");
283 289
284 /* set idle function */ 290 /* set idle function */
285 pm_idle = exynos4_idle; 291 pm_idle = exynos_idle;
286 292
287 /* set sw_reset function */ 293 /* set sw_reset function */
288 s5p_reset_hook = exynos4_sw_reset; 294 if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
295 s5p_reset_hook = exynos4_sw_reset;
289 296
290 return sysdev_register(&exynos4_sysdev); 297 return sysdev_register(&exynos4_sysdev);
291} 298}
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index bf7e96f2793a..bf7e96f2793a 100644
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
diff --git a/arch/arm/mach-exynos4/dev-ahci.c b/arch/arm/mach-exynos/dev-ahci.c
index f57a3de8e1d2..f57a3de8e1d2 100644
--- a/arch/arm/mach-exynos4/dev-ahci.c
+++ b/arch/arm/mach-exynos/dev-ahci.c
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos/dev-audio.c
index 5a9f9c2e53bf..5a9f9c2e53bf 100644
--- a/arch/arm/mach-exynos4/dev-audio.c
+++ b/arch/arm/mach-exynos/dev-audio.c
diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-exynos/dev-dwmci.c
index b025db4bf602..b025db4bf602 100644
--- a/arch/arm/mach-exynos4/dev-dwmci.c
+++ b/arch/arm/mach-exynos/dev-dwmci.c
diff --git a/arch/arm/mach-exynos4/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c
index 3273f25d6a75..3273f25d6a75 100644
--- a/arch/arm/mach-exynos4/dev-pd.c
+++ b/arch/arm/mach-exynos/dev-pd.c
diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 3b7cae0fe23e..3b7cae0fe23e 100644
--- a/arch/arm/mach-exynos4/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
new file mode 100644
index 000000000000..9667c61e64fb
--- /dev/null
+++ b/arch/arm/mach-exynos/dma.c
@@ -0,0 +1,250 @@
1/* linux/arch/arm/mach-exynos4/dma.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
7 * Jaswinder Singh <jassi.brar@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h>
27
28#include <asm/irq.h>
29#include <plat/devs.h>
30#include <plat/irqs.h>
31
32#include <mach/map.h>
33#include <mach/irqs.h>
34#include <mach/dma.h>
35
36static u64 dma_dmamask = DMA_BIT_MASK(32);
37
38struct dma_pl330_peri pdma0_peri[28] = {
39 {
40 .peri_id = (u8)DMACH_PCM0_RX,
41 .rqtype = DEVTOMEM,
42 }, {
43 .peri_id = (u8)DMACH_PCM0_TX,
44 .rqtype = MEMTODEV,
45 }, {
46 .peri_id = (u8)DMACH_PCM2_RX,
47 .rqtype = DEVTOMEM,
48 }, {
49 .peri_id = (u8)DMACH_PCM2_TX,
50 .rqtype = MEMTODEV,
51 }, {
52 .peri_id = (u8)DMACH_MSM_REQ0,
53 }, {
54 .peri_id = (u8)DMACH_MSM_REQ2,
55 }, {
56 .peri_id = (u8)DMACH_SPI0_RX,
57 .rqtype = DEVTOMEM,
58 }, {
59 .peri_id = (u8)DMACH_SPI0_TX,
60 .rqtype = MEMTODEV,
61 }, {
62 .peri_id = (u8)DMACH_SPI2_RX,
63 .rqtype = DEVTOMEM,
64 }, {
65 .peri_id = (u8)DMACH_SPI2_TX,
66 .rqtype = MEMTODEV,
67 }, {
68 .peri_id = (u8)DMACH_I2S0S_TX,
69 .rqtype = MEMTODEV,
70 }, {
71 .peri_id = (u8)DMACH_I2S0_RX,
72 .rqtype = DEVTOMEM,
73 }, {
74 .peri_id = (u8)DMACH_I2S0_TX,
75 .rqtype = MEMTODEV,
76 }, {
77 .peri_id = (u8)DMACH_UART0_RX,
78 .rqtype = DEVTOMEM,
79 }, {
80 .peri_id = (u8)DMACH_UART0_TX,
81 .rqtype = MEMTODEV,
82 }, {
83 .peri_id = (u8)DMACH_UART2_RX,
84 .rqtype = DEVTOMEM,
85 }, {
86 .peri_id = (u8)DMACH_UART2_TX,
87 .rqtype = MEMTODEV,
88 }, {
89 .peri_id = (u8)DMACH_UART4_RX,
90 .rqtype = DEVTOMEM,
91 }, {
92 .peri_id = (u8)DMACH_UART4_TX,
93 .rqtype = MEMTODEV,
94 }, {
95 .peri_id = (u8)DMACH_SLIMBUS0_RX,
96 .rqtype = DEVTOMEM,
97 }, {
98 .peri_id = (u8)DMACH_SLIMBUS0_TX,
99 .rqtype = MEMTODEV,
100 }, {
101 .peri_id = (u8)DMACH_SLIMBUS2_RX,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_SLIMBUS2_TX,
105 .rqtype = MEMTODEV,
106 }, {
107 .peri_id = (u8)DMACH_SLIMBUS4_RX,
108 .rqtype = DEVTOMEM,
109 }, {
110 .peri_id = (u8)DMACH_SLIMBUS4_TX,
111 .rqtype = MEMTODEV,
112 }, {
113 .peri_id = (u8)DMACH_AC97_MICIN,
114 .rqtype = DEVTOMEM,
115 }, {
116 .peri_id = (u8)DMACH_AC97_PCMIN,
117 .rqtype = DEVTOMEM,
118 }, {
119 .peri_id = (u8)DMACH_AC97_PCMOUT,
120 .rqtype = MEMTODEV,
121 },
122};
123
124struct dma_pl330_platdata exynos4_pdma0_pdata = {
125 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
126 .peri = pdma0_peri,
127};
128
129struct amba_device exynos4_device_pdma0 = {
130 .dev = {
131 .init_name = "dma-pl330.0",
132 .dma_mask = &dma_dmamask,
133 .coherent_dma_mask = DMA_BIT_MASK(32),
134 .platform_data = &exynos4_pdma0_pdata,
135 },
136 .res = {
137 .start = EXYNOS4_PA_PDMA0,
138 .end = EXYNOS4_PA_PDMA0 + SZ_4K,
139 .flags = IORESOURCE_MEM,
140 },
141 .irq = {IRQ_PDMA0, NO_IRQ},
142 .periphid = 0x00041330,
143};
144
145struct dma_pl330_peri pdma1_peri[25] = {
146 {
147 .peri_id = (u8)DMACH_PCM0_RX,
148 .rqtype = DEVTOMEM,
149 }, {
150 .peri_id = (u8)DMACH_PCM0_TX,
151 .rqtype = MEMTODEV,
152 }, {
153 .peri_id = (u8)DMACH_PCM1_RX,
154 .rqtype = DEVTOMEM,
155 }, {
156 .peri_id = (u8)DMACH_PCM1_TX,
157 .rqtype = MEMTODEV,
158 }, {
159 .peri_id = (u8)DMACH_MSM_REQ1,
160 }, {
161 .peri_id = (u8)DMACH_MSM_REQ3,
162 }, {
163 .peri_id = (u8)DMACH_SPI1_RX,
164 .rqtype = DEVTOMEM,
165 }, {
166 .peri_id = (u8)DMACH_SPI1_TX,
167 .rqtype = MEMTODEV,
168 }, {
169 .peri_id = (u8)DMACH_I2S0S_TX,
170 .rqtype = MEMTODEV,
171 }, {
172 .peri_id = (u8)DMACH_I2S0_RX,
173 .rqtype = DEVTOMEM,
174 }, {
175 .peri_id = (u8)DMACH_I2S0_TX,
176 .rqtype = MEMTODEV,
177 }, {
178 .peri_id = (u8)DMACH_I2S1_RX,
179 .rqtype = DEVTOMEM,
180 }, {
181 .peri_id = (u8)DMACH_I2S1_TX,
182 .rqtype = MEMTODEV,
183 }, {
184 .peri_id = (u8)DMACH_UART0_RX,
185 .rqtype = DEVTOMEM,
186 }, {
187 .peri_id = (u8)DMACH_UART0_TX,
188 .rqtype = MEMTODEV,
189 }, {
190 .peri_id = (u8)DMACH_UART1_RX,
191 .rqtype = DEVTOMEM,
192 }, {
193 .peri_id = (u8)DMACH_UART1_TX,
194 .rqtype = MEMTODEV,
195 }, {
196 .peri_id = (u8)DMACH_UART3_RX,
197 .rqtype = DEVTOMEM,
198 }, {
199 .peri_id = (u8)DMACH_UART3_TX,
200 .rqtype = MEMTODEV,
201 }, {
202 .peri_id = (u8)DMACH_SLIMBUS1_RX,
203 .rqtype = DEVTOMEM,
204 }, {
205 .peri_id = (u8)DMACH_SLIMBUS1_TX,
206 .rqtype = MEMTODEV,
207 }, {
208 .peri_id = (u8)DMACH_SLIMBUS3_RX,
209 .rqtype = DEVTOMEM,
210 }, {
211 .peri_id = (u8)DMACH_SLIMBUS3_TX,
212 .rqtype = MEMTODEV,
213 }, {
214 .peri_id = (u8)DMACH_SLIMBUS5_RX,
215 .rqtype = DEVTOMEM,
216 }, {
217 .peri_id = (u8)DMACH_SLIMBUS5_TX,
218 .rqtype = MEMTODEV,
219 },
220};
221
222struct dma_pl330_platdata exynos4_pdma1_pdata = {
223 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
224 .peri = pdma1_peri,
225};
226
227struct amba_device exynos4_device_pdma1 = {
228 .dev = {
229 .init_name = "dma-pl330.1",
230 .dma_mask = &dma_dmamask,
231 .coherent_dma_mask = DMA_BIT_MASK(32),
232 .platform_data = &exynos4_pdma1_pdata,
233 },
234 .res = {
235 .start = EXYNOS4_PA_PDMA1,
236 .end = EXYNOS4_PA_PDMA1 + SZ_4K,
237 .flags = IORESOURCE_MEM,
238 },
239 .irq = {IRQ_PDMA1, NO_IRQ},
240 .periphid = 0x00041330,
241};
242
243static int __init exynos4_dma_init(void)
244{
245 amba_device_register(&exynos4_device_pdma0, &iomem_resource);
246 amba_device_register(&exynos4_device_pdma1, &iomem_resource);
247
248 return 0;
249}
250arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos4/headsmp.S b/arch/arm/mach-exynos/headsmp.S
index 3cdeb3647542..3cdeb3647542 100644
--- a/arch/arm/mach-exynos4/headsmp.S
+++ b/arch/arm/mach-exynos/headsmp.S
diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index da70e7e39937..da70e7e39937 100644
--- a/arch/arm/mach-exynos4/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos/include/mach/debug-macro.S
index 6cacf16a67a6..6cacf16a67a6 100644
--- a/arch/arm/mach-exynos4/include/mach/debug-macro.S
+++ b/arch/arm/mach-exynos/include/mach/debug-macro.S
diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos/include/mach/dma.h
index 81209eb1409b..201842a3769e 100644
--- a/arch/arm/mach-exynos4/include/mach/dma.h
+++ b/arch/arm/mach-exynos/include/mach/dma.h
@@ -20,7 +20,7 @@
20#ifndef __MACH_DMA_H 20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H 21#define __MACH_DMA_H
22 22
23/* This platform uses the common S3C DMA API driver for PL330 */ 23/* This platform uses the common DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h> 24#include <plat/dma-pl330.h>
25 25
26#endif /* __MACH_DMA_H */ 26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos4/include/mach/dwmci.h b/arch/arm/mach-exynos/include/mach/dwmci.h
index 7ce657459cc0..7ce657459cc0 100644
--- a/arch/arm/mach-exynos4/include/mach/dwmci.h
+++ b/arch/arm/mach-exynos/include/mach/dwmci.h
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S
index f5e9fd8e37b4..f5e9fd8e37b4 100644
--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos/include/mach/entry-macro.S
diff --git a/arch/arm/mach-exynos4/include/mach/exynos4-clock.h b/arch/arm/mach-exynos/include/mach/exynos4-clock.h
index a07fcbf55251..a07fcbf55251 100644
--- a/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
+++ b/arch/arm/mach-exynos/include/mach/exynos4-clock.h
diff --git a/arch/arm/mach-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
index 80523ca9bb49..80523ca9bb49 100644
--- a/arch/arm/mach-exynos4/include/mach/gpio.h
+++ b/arch/arm/mach-exynos/include/mach/gpio.h
diff --git a/arch/arm/mach-exynos4/include/mach/hardware.h b/arch/arm/mach-exynos/include/mach/hardware.h
index 5109eb232f23..5109eb232f23 100644
--- a/arch/arm/mach-exynos4/include/mach/hardware.h
+++ b/arch/arm/mach-exynos/include/mach/hardware.h
diff --git a/arch/arm/mach-exynos4/include/mach/io.h b/arch/arm/mach-exynos/include/mach/io.h
index d5478d247535..d5478d247535 100644
--- a/arch/arm/mach-exynos4/include/mach/io.h
+++ b/arch/arm/mach-exynos/include/mach/io.h
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index 2d3f6bcd9bc0..dfd4b7eecb90 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -95,7 +95,11 @@
95#define IRQ_2D IRQ_SPI(89) 95#define IRQ_2D IRQ_SPI(89)
96#define IRQ_PCIE IRQ_SPI(90) 96#define IRQ_PCIE IRQ_SPI(90)
97 97
98#define IRQ_MIXER IRQ_SPI(91)
99#define IRQ_HDMI IRQ_SPI(92)
100#define IRQ_IIC_HDMIPHY IRQ_SPI(93)
98#define IRQ_MFC IRQ_SPI(94) 101#define IRQ_MFC IRQ_SPI(94)
102#define IRQ_SDO IRQ_SPI(95)
99 103
100#define IRQ_AUDIO_SS IRQ_SPI(96) 104#define IRQ_AUDIO_SS IRQ_SPI(96)
101#define IRQ_I2S0 IRQ_SPI(97) 105#define IRQ_I2S0 IRQ_SPI(97)
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 9f97eb8499ee..058541d45af0 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-exynos4/include/mach/map.h 1/* linux/arch/arm/mach-exynos/include/mach/map.h
2 * 2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
@@ -112,6 +112,12 @@
112 112
113#define EXYNOS4_PA_UART 0x13800000 113#define EXYNOS4_PA_UART 0x13800000
114 114
115#define EXYNOS4_PA_VP 0x12C00000
116#define EXYNOS4_PA_MIXER 0x12C10000
117#define EXYNOS4_PA_SDO 0x12C20000
118#define EXYNOS4_PA_HDMI 0x12D00000
119#define EXYNOS4_PA_IIC_HDMIPHY 0x138E0000
120
115#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) 121#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
116 122
117#define EXYNOS4_PA_ADC 0x13910000 123#define EXYNOS4_PA_ADC 0x13910000
@@ -139,33 +145,45 @@
139#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5) 145#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5)
140#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6) 146#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6)
141#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7) 147#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7)
142#define SAMSUNG_PA_ADC EXYNOS4_PA_ADC
143#define SAMSUNG_PA_ADC1 EXYNOS4_PA_ADC1
144#define S3C_PA_RTC EXYNOS4_PA_RTC 148#define S3C_PA_RTC EXYNOS4_PA_RTC
145#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG 149#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
150#define S3C_PA_UART EXYNOS4_PA_UART
146 151
147#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID 152#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID
153#define S5P_PA_EHCI EXYNOS4_PA_EHCI
148#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 154#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
149#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 155#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
150#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 156#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
151#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 157#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
158#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
159#define S5P_PA_HDMI EXYNOS4_PA_HDMI
160#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY
161#define S5P_PA_MFC EXYNOS4_PA_MFC
152#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0 162#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
153#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1 163#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
154#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 164#define S5P_PA_MIXER EXYNOS4_PA_MIXER
155#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND 165#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
156#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA 166#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
167#define S5P_PA_SDO EXYNOS4_PA_SDO
157#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM 168#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
158#define S5P_PA_SROMC EXYNOS4_PA_SROMC 169#define S5P_PA_SROMC EXYNOS4_PA_SROMC
159#define S5P_PA_MFC EXYNOS4_PA_MFC
160#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON 170#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
161#define S5P_PA_TIMER EXYNOS4_PA_TIMER 171#define S5P_PA_TIMER EXYNOS4_PA_TIMER
162#define S5P_PA_EHCI EXYNOS4_PA_EHCI 172#define S5P_PA_VP EXYNOS4_PA_VP
163 173
174#define SAMSUNG_PA_ADC EXYNOS4_PA_ADC
175#define SAMSUNG_PA_ADC1 EXYNOS4_PA_ADC1
164#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD 176#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD
165 177
166/* UART */ 178#define EXYNOS_PA_COMBINER EXYNOS4_PA_COMBINER
179#define EXYNOS_PA_GIC_CPU EXYNOS4_PA_GIC_CPU
180#define EXYNOS_PA_GIC_DIST EXYNOS4_PA_GIC_DIST
181#define EXYNOS_PA_PMU EXYNOS4_PA_PMU
182#define EXYNOS_PA_SYSTIMER EXYNOS4_PA_SYSTIMER
167 183
168#define S3C_PA_UART EXYNOS4_PA_UART 184/* Compatibility UART */
185
186#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
169 187
170#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET)) 188#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
171#define S5P_PA_UART0 S5P_PA_UART(0) 189#define S5P_PA_UART0 S5P_PA_UART(0)
diff --git a/arch/arm/mach-exynos4/include/mach/memory.h b/arch/arm/mach-exynos/include/mach/memory.h
index 374ef2cf7152..374ef2cf7152 100644
--- a/arch/arm/mach-exynos4/include/mach/memory.h
+++ b/arch/arm/mach-exynos/include/mach/memory.h
diff --git a/arch/arm/mach-exynos4/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h
index 1df3b81f96e8..9d8da51e35ca 100644
--- a/arch/arm/mach-exynos4/include/mach/pm-core.h
+++ b/arch/arm/mach-exynos/include/mach/pm-core.h
@@ -14,6 +14,10 @@
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16*/ 16*/
17
18#ifndef __ASM_ARCH_PM_CORE_H
19#define __ASM_ARCH_PM_CORE_H __FILE__
20
17#include <mach/regs-pmu.h> 21#include <mach/regs-pmu.h>
18 22
19static inline void s3c_pm_debug_init_uart(void) 23static inline void s3c_pm_debug_init_uart(void)
@@ -53,7 +57,9 @@ static inline void s3c_pm_restored_gpios(void)
53 /* nothing here yet */ 57 /* nothing here yet */
54} 58}
55 59
56static inline void s3c_pm_saved_gpios(void) 60static inline void samsung_pm_saved_gpios(void)
57{ 61{
58 /* nothing here yet */ 62 /* nothing here yet */
59} 63}
64
65#endif /* __ASM_ARCH_PM_CORE_H */
diff --git a/arch/arm/mach-exynos4/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h
index a952904b010e..632dd5630138 100644
--- a/arch/arm/mach-exynos4/include/mach/pmu.h
+++ b/arch/arm/mach-exynos/include/mach/pmu.h
@@ -13,6 +13,8 @@
13#ifndef __ASM_ARCH_PMU_H 13#ifndef __ASM_ARCH_PMU_H
14#define __ASM_ARCH_PMU_H __FILE__ 14#define __ASM_ARCH_PMU_H __FILE__
15 15
16#define PMU_TABLE_END NULL
17
16enum sys_powerdown { 18enum sys_powerdown {
17 SYS_AFTR, 19 SYS_AFTR,
18 SYS_LPA, 20 SYS_LPA,
@@ -20,6 +22,11 @@ enum sys_powerdown {
20 NUM_SYS_POWERDOWN, 22 NUM_SYS_POWERDOWN,
21}; 23};
22 24
25struct exynos4_pmu_conf {
26 void __iomem *reg;
27 unsigned int val[NUM_SYS_POWERDOWN];
28};
29
23extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); 30extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
24 31
25#endif /* __ASM_ARCH_PMU_H */ 32#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-audss.h b/arch/arm/mach-exynos/include/mach/regs-audss.h
index ca5a8b64218a..ca5a8b64218a 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-audss.h
+++ b/arch/arm/mach-exynos/include/mach/regs-audss.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
index 6c37ebe94829..6c37ebe94829 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h
index 1401b21663a5..1401b21663a5 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-gpio.h
+++ b/arch/arm/mach-exynos/include/mach/regs-gpio.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-irq.h b/arch/arm/mach-exynos/include/mach/regs-irq.h
index 9c7b4bfd546f..9c7b4bfd546f 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-irq.h
+++ b/arch/arm/mach-exynos/include/mach/regs-irq.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos/include/mach/regs-mct.h
index 80dd02ad6d61..80dd02ad6d61 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-mct.h
+++ b/arch/arm/mach-exynos/include/mach/regs-mct.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mem.h b/arch/arm/mach-exynos/include/mach/regs-mem.h
index 0368b5a27252..0368b5a27252 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-mem.h
+++ b/arch/arm/mach-exynos/include/mach/regs-mem.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index cdf9b47c303c..4fff8e938fec 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -25,9 +25,10 @@
25 25
26#define S5P_USE_STANDBY_WFI0 (1 << 16) 26#define S5P_USE_STANDBY_WFI0 (1 << 16)
27#define S5P_USE_STANDBY_WFI1 (1 << 17) 27#define S5P_USE_STANDBY_WFI1 (1 << 17)
28#define S5P_USE_STANDBYWFI_ISP_ARM (1 << 18)
28#define S5P_USE_STANDBY_WFE0 (1 << 24) 29#define S5P_USE_STANDBY_WFE0 (1 << 24)
29#define S5P_USE_STANDBY_WFE1 (1 << 25) 30#define S5P_USE_STANDBY_WFE1 (1 << 25)
30#define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24)) 31#define S5P_USE_STANDBYWFE_ISP_ARM (1 << 26)
31 32
32#define S5P_SWRESET S5P_PMUREG(0x0400) 33#define S5P_SWRESET S5P_PMUREG(0x0400)
33 34
@@ -35,15 +36,17 @@
35#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) 36#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
36#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) 37#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
37 38
38#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) 39#define S5P_HDMI_PHY_CONTROL S5P_PMUREG(0x0700)
39#define S5P_USBHOST_PHY_ENABLE (1 << 0) 40#define S5P_HDMI_PHY_ENABLE (1 << 0)
41
42#define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C)
43#define S5P_DAC_PHY_ENABLE (1 << 0)
40 44
41#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4) 45#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
42#define S5P_MIPI_DPHY_ENABLE (1 << 0) 46#define S5P_MIPI_DPHY_ENABLE (1 << 0)
43#define S5P_MIPI_DPHY_SRESETN (1 << 1) 47#define S5P_MIPI_DPHY_SRESETN (1 << 1)
44#define S5P_MIPI_DPHY_MRESETN (1 << 2) 48#define S5P_MIPI_DPHY_MRESETN (1 << 2)
45 49
46#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720)
47#define S5P_INFORM0 S5P_PMUREG(0x0800) 50#define S5P_INFORM0 S5P_PMUREG(0x0800)
48#define S5P_INFORM1 S5P_PMUREG(0x0804) 51#define S5P_INFORM1 S5P_PMUREG(0x0804)
49#define S5P_INFORM2 S5P_PMUREG(0x0808) 52#define S5P_INFORM2 S5P_PMUREG(0x0808)
@@ -76,7 +79,6 @@
76#define S5P_CMU_CLKSTOP_MFC_LOWPWR S5P_PMUREG(0x1148) 79#define S5P_CMU_CLKSTOP_MFC_LOWPWR S5P_PMUREG(0x1148)
77#define S5P_CMU_CLKSTOP_G3D_LOWPWR S5P_PMUREG(0x114C) 80#define S5P_CMU_CLKSTOP_G3D_LOWPWR S5P_PMUREG(0x114C)
78#define S5P_CMU_CLKSTOP_LCD0_LOWPWR S5P_PMUREG(0x1150) 81#define S5P_CMU_CLKSTOP_LCD0_LOWPWR S5P_PMUREG(0x1150)
79#define S5P_CMU_CLKSTOP_LCD1_LOWPWR S5P_PMUREG(0x1154)
80#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR S5P_PMUREG(0x1158) 82#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR S5P_PMUREG(0x1158)
81#define S5P_CMU_CLKSTOP_GPS_LOWPWR S5P_PMUREG(0x115C) 83#define S5P_CMU_CLKSTOP_GPS_LOWPWR S5P_PMUREG(0x115C)
82#define S5P_CMU_RESET_CAM_LOWPWR S5P_PMUREG(0x1160) 84#define S5P_CMU_RESET_CAM_LOWPWR S5P_PMUREG(0x1160)
@@ -84,7 +86,6 @@
84#define S5P_CMU_RESET_MFC_LOWPWR S5P_PMUREG(0x1168) 86#define S5P_CMU_RESET_MFC_LOWPWR S5P_PMUREG(0x1168)
85#define S5P_CMU_RESET_G3D_LOWPWR S5P_PMUREG(0x116C) 87#define S5P_CMU_RESET_G3D_LOWPWR S5P_PMUREG(0x116C)
86#define S5P_CMU_RESET_LCD0_LOWPWR S5P_PMUREG(0x1170) 88#define S5P_CMU_RESET_LCD0_LOWPWR S5P_PMUREG(0x1170)
87#define S5P_CMU_RESET_LCD1_LOWPWR S5P_PMUREG(0x1174)
88#define S5P_CMU_RESET_MAUDIO_LOWPWR S5P_PMUREG(0x1178) 89#define S5P_CMU_RESET_MAUDIO_LOWPWR S5P_PMUREG(0x1178)
89#define S5P_CMU_RESET_GPS_LOWPWR S5P_PMUREG(0x117C) 90#define S5P_CMU_RESET_GPS_LOWPWR S5P_PMUREG(0x117C)
90#define S5P_TOP_BUS_LOWPWR S5P_PMUREG(0x1180) 91#define S5P_TOP_BUS_LOWPWR S5P_PMUREG(0x1180)
@@ -92,14 +93,11 @@
92#define S5P_TOP_PWR_LOWPWR S5P_PMUREG(0x1188) 93#define S5P_TOP_PWR_LOWPWR S5P_PMUREG(0x1188)
93#define S5P_LOGIC_RESET_LOWPWR S5P_PMUREG(0x11A0) 94#define S5P_LOGIC_RESET_LOWPWR S5P_PMUREG(0x11A0)
94#define S5P_ONENAND_MEM_LOWPWR S5P_PMUREG(0x11C0) 95#define S5P_ONENAND_MEM_LOWPWR S5P_PMUREG(0x11C0)
95#define S5P_MODIMIF_MEM_LOWPWR S5P_PMUREG(0x11C4)
96#define S5P_G2D_ACP_MEM_LOWPWR S5P_PMUREG(0x11C8) 96#define S5P_G2D_ACP_MEM_LOWPWR S5P_PMUREG(0x11C8)
97#define S5P_USBOTG_MEM_LOWPWR S5P_PMUREG(0x11CC) 97#define S5P_USBOTG_MEM_LOWPWR S5P_PMUREG(0x11CC)
98#define S5P_HSMMC_MEM_LOWPWR S5P_PMUREG(0x11D0) 98#define S5P_HSMMC_MEM_LOWPWR S5P_PMUREG(0x11D0)
99#define S5P_CSSYS_MEM_LOWPWR S5P_PMUREG(0x11D4) 99#define S5P_CSSYS_MEM_LOWPWR S5P_PMUREG(0x11D4)
100#define S5P_SECSS_MEM_LOWPWR S5P_PMUREG(0x11D8) 100#define S5P_SECSS_MEM_LOWPWR S5P_PMUREG(0x11D8)
101#define S5P_PCIE_MEM_LOWPWR S5P_PMUREG(0x11E0)
102#define S5P_SATA_MEM_LOWPWR S5P_PMUREG(0x11E4)
103#define S5P_PAD_RETENTION_DRAM_LOWPWR S5P_PMUREG(0x1200) 101#define S5P_PAD_RETENTION_DRAM_LOWPWR S5P_PMUREG(0x1200)
104#define S5P_PAD_RETENTION_MAUDIO_LOWPWR S5P_PMUREG(0x1204) 102#define S5P_PAD_RETENTION_MAUDIO_LOWPWR S5P_PMUREG(0x1204)
105#define S5P_PAD_RETENTION_GPIO_LOWPWR S5P_PMUREG(0x1220) 103#define S5P_PAD_RETENTION_GPIO_LOWPWR S5P_PMUREG(0x1220)
@@ -120,7 +118,6 @@
120#define S5P_MFC_LOWPWR S5P_PMUREG(0x1388) 118#define S5P_MFC_LOWPWR S5P_PMUREG(0x1388)
121#define S5P_G3D_LOWPWR S5P_PMUREG(0x138C) 119#define S5P_G3D_LOWPWR S5P_PMUREG(0x138C)
122#define S5P_LCD0_LOWPWR S5P_PMUREG(0x1390) 120#define S5P_LCD0_LOWPWR S5P_PMUREG(0x1390)
123#define S5P_LCD1_LOWPWR S5P_PMUREG(0x1394)
124#define S5P_MAUDIO_LOWPWR S5P_PMUREG(0x1398) 121#define S5P_MAUDIO_LOWPWR S5P_PMUREG(0x1398)
125#define S5P_GPS_LOWPWR S5P_PMUREG(0x139C) 122#define S5P_GPS_LOWPWR S5P_PMUREG(0x139C)
126#define S5P_GPS_ALIVE_LOWPWR S5P_PMUREG(0x13A0) 123#define S5P_GPS_ALIVE_LOWPWR S5P_PMUREG(0x13A0)
@@ -156,7 +153,6 @@
156#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40) 153#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
157#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60) 154#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
158#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80) 155#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
159#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
160#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0) 156#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
161 157
162#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 158#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1
@@ -165,4 +161,60 @@
165 161
166#define S5P_CHECK_SLEEP 0x00000BAD 162#define S5P_CHECK_SLEEP 0x00000BAD
167 163
164/* Only for EXYNOS4210 */
165#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708)
166#define S5P_USBHOST_PHY_ENABLE (1 << 0)
167
168#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720)
169
170#define S5P_CMU_CLKSTOP_LCD1_LOWPWR S5P_PMUREG(0x1154)
171#define S5P_CMU_RESET_LCD1_LOWPWR S5P_PMUREG(0x1174)
172#define S5P_MODIMIF_MEM_LOWPWR S5P_PMUREG(0x11C4)
173#define S5P_PCIE_MEM_LOWPWR S5P_PMUREG(0x11E0)
174#define S5P_SATA_MEM_LOWPWR S5P_PMUREG(0x11E4)
175#define S5P_LCD1_LOWPWR S5P_PMUREG(0x1394)
176
177#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
178
179/* Only for EXYNOS4212 */
180#define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050)
181#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054)
182#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR S5P_PMUREG(0x1058)
183#define S5P_CMU_ACLKSTOP_COREBLK_LOWPWR S5P_PMUREG(0x1110)
184#define S5P_CMU_SCLKSTOP_COREBLK_LOWPWR S5P_PMUREG(0x1114)
185#define S5P_CMU_RESET_COREBLK_LOWPWR S5P_PMUREG(0x111C)
186#define S5P_MPLLUSER_SYSCLK_LOWPWR S5P_PMUREG(0x1130)
187#define S5P_CMU_CLKSTOP_ISP_LOWPWR S5P_PMUREG(0x1154)
188#define S5P_CMU_RESET_ISP_LOWPWR S5P_PMUREG(0x1174)
189#define S5P_TOP_BUS_COREBLK_LOWPWR S5P_PMUREG(0x1190)
190#define S5P_TOP_RETENTION_COREBLK_LOWPWR S5P_PMUREG(0x1194)
191#define S5P_TOP_PWR_COREBLK_LOWPWR S5P_PMUREG(0x1198)
192#define S5P_OSCCLK_GATE_LOWPWR S5P_PMUREG(0x11A4)
193#define S5P_LOGIC_RESET_COREBLK_LOWPWR S5P_PMUREG(0x11B0)
194#define S5P_OSCCLK_GATE_COREBLK_LOWPWR S5P_PMUREG(0x11B4)
195#define S5P_HSI_MEM_LOWPWR S5P_PMUREG(0x11C4)
196#define S5P_ROTATOR_MEM_LOWPWR S5P_PMUREG(0x11DC)
197#define S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR S5P_PMUREG(0x123C)
198#define S5P_PAD_ISOLATION_COREBLK_LOWPWR S5P_PMUREG(0x1250)
199#define S5P_GPIO_MODE_COREBLK_LOWPWR S5P_PMUREG(0x1320)
200#define S5P_TOP_ASB_RESET_LOWPWR S5P_PMUREG(0x1344)
201#define S5P_TOP_ASB_ISOLATION_LOWPWR S5P_PMUREG(0x1348)
202#define S5P_ISP_LOWPWR S5P_PMUREG(0x1394)
203#define S5P_DRAM_FREQ_DOWN_LOWPWR S5P_PMUREG(0x13B0)
204#define S5P_DDRPHY_DLLOFF_LOWPWR S5P_PMUREG(0x13B4)
205#define S5P_CMU_SYSCLK_ISP_LOWPWR S5P_PMUREG(0x13B8)
206#define S5P_CMU_SYSCLK_GPS_LOWPWR S5P_PMUREG(0x13BC)
207#define S5P_LPDDR_PHY_DLL_LOCK_LOWPWR S5P_PMUREG(0x13C0)
208
209#define S5P_ARM_L2_0_OPTION S5P_PMUREG(0x2608)
210#define S5P_ARM_L2_1_OPTION S5P_PMUREG(0x2628)
211#define S5P_ONENAND_MEM_OPTION S5P_PMUREG(0x2E08)
212#define S5P_HSI_MEM_OPTION S5P_PMUREG(0x2E28)
213#define S5P_G2D_ACP_MEM_OPTION S5P_PMUREG(0x2E48)
214#define S5P_USBOTG_MEM_OPTION S5P_PMUREG(0x2E68)
215#define S5P_HSMMC_MEM_OPTION S5P_PMUREG(0x2E88)
216#define S5P_CSSYS_MEM_OPTION S5P_PMUREG(0x2EA8)
217#define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8)
218#define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48)
219
168#endif /* __ASM_ARCH_REGS_PMU_H */ 220#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
index 68ff6ad08a2b..68ff6ad08a2b 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
diff --git a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
index c337cf3a71bf..c337cf3a71bf 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
+++ b/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
diff --git a/arch/arm/mach-exynos4/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
index 6a5fbb534e82..6a5fbb534e82 100644
--- a/arch/arm/mach-exynos4/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
diff --git a/arch/arm/mach-exynos4/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h
index 5e3220c18fc7..5e3220c18fc7 100644
--- a/arch/arm/mach-exynos4/include/mach/system.h
+++ b/arch/arm/mach-exynos/include/mach/system.h
diff --git a/arch/arm/mach-exynos4/include/mach/timex.h b/arch/arm/mach-exynos/include/mach/timex.h
index 6d138750a708..6d138750a708 100644
--- a/arch/arm/mach-exynos4/include/mach/timex.h
+++ b/arch/arm/mach-exynos/include/mach/timex.h
diff --git a/arch/arm/mach-exynos4/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h
index 21d97bcd9acb..21d97bcd9acb 100644
--- a/arch/arm/mach-exynos4/include/mach/uncompress.h
+++ b/arch/arm/mach-exynos/include/mach/uncompress.h
diff --git a/arch/arm/mach-exynos4/include/mach/vmalloc.h b/arch/arm/mach-exynos/include/mach/vmalloc.h
index 284330e571d2..284330e571d2 100644
--- a/arch/arm/mach-exynos4/include/mach/vmalloc.h
+++ b/arch/arm/mach-exynos/include/mach/vmalloc.h
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos/init.c
index a8a83e3881a4..a8a83e3881a4 100644
--- a/arch/arm/mach-exynos4/init.c
+++ b/arch/arm/mach-exynos/init.c
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos/irq-combiner.c
index 5a2758ab055e..5a2758ab055e 100644
--- a/arch/arm/mach-exynos4/irq-combiner.c
+++ b/arch/arm/mach-exynos/irq-combiner.c
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos/irq-eint.c
index badb8c66fc9b..badb8c66fc9b 100644
--- a/arch/arm/mach-exynos4/irq-eint.c
+++ b/arch/arm/mach-exynos/irq-eint.c
diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index f0ca6c157d29..f0ca6c157d29 100644
--- a/arch/arm/mach-exynos4/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 6e0536818bf5..236bbe187163 100644
--- a/arch/arm/mach-exynos4/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -27,15 +27,20 @@
27#include <linux/pwm_backlight.h> 27#include <linux/pwm_backlight.h>
28 28
29#include <video/platform_lcd.h> 29#include <video/platform_lcd.h>
30#include <media/m5mols.h>
31#include <media/s5p_fimc.h>
32#include <media/v4l2-mediabus.h>
30 33
31#include <asm/mach/arch.h> 34#include <asm/mach/arch.h>
32#include <asm/mach-types.h> 35#include <asm/mach-types.h>
33 36
34#include <plat/adc.h> 37#include <plat/adc.h>
38#include <plat/regs-fb-v4.h>
35#include <plat/regs-serial.h> 39#include <plat/regs-serial.h>
36#include <plat/exynos4.h> 40#include <plat/exynos4.h>
37#include <plat/cpu.h> 41#include <plat/cpu.h>
38#include <plat/devs.h> 42#include <plat/devs.h>
43#include <plat/fb.h>
39#include <plat/sdhci.h> 44#include <plat/sdhci.h>
40#include <plat/ehci.h> 45#include <plat/ehci.h>
41#include <plat/clock.h> 46#include <plat/clock.h>
@@ -43,6 +48,9 @@
43#include <plat/iic.h> 48#include <plat/iic.h>
44#include <plat/mfc.h> 49#include <plat/mfc.h>
45#include <plat/pd.h> 50#include <plat/pd.h>
51#include <plat/fimc-core.h>
52#include <plat/camport.h>
53#include <plat/mipi_csis.h>
46 54
47#include <mach/map.h> 55#include <mach/map.h>
48 56
@@ -63,6 +71,8 @@
63enum fixed_regulator_id { 71enum fixed_regulator_id {
64 FIXED_REG_ID_MMC = 0, 72 FIXED_REG_ID_MMC = 0,
65 FIXED_REG_ID_MAX8903, 73 FIXED_REG_ID_MAX8903,
74 FIXED_REG_ID_CAM_A28V,
75 FIXED_REG_ID_CAM_12V,
66}; 76};
67 77
68static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = { 78static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
@@ -199,6 +209,33 @@ static struct platform_device nuri_gpio_keys = {
199 }, 209 },
200}; 210};
201 211
212/* Frame Buffer */
213static struct s3c_fb_pd_win nuri_fb_win0 = {
214 .win_mode = {
215 .left_margin = 64,
216 .right_margin = 16,
217 .upper_margin = 64,
218 .lower_margin = 1,
219 .hsync_len = 48,
220 .vsync_len = 3,
221 .xres = 1280,
222 .yres = 800,
223 .refresh = 60,
224 },
225 .max_bpp = 24,
226 .default_bpp = 16,
227 .virtual_x = 1280,
228 .virtual_y = 800,
229};
230
231static struct s3c_fb_platdata nuri_fb_pdata __initdata = {
232 .win[0] = &nuri_fb_win0,
233 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
234 VIDCON0_CLKSEL_LCD,
235 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
236 .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
237};
238
202static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power) 239static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
203{ 240{
204 int gpio = EXYNOS4_GPE1(5); 241 int gpio = EXYNOS4_GPE1(5);
@@ -1037,13 +1074,6 @@ static struct platform_device nuri_max8903_device = {
1037 }, 1074 },
1038}; 1075};
1039 1076
1040static struct device *nuri_cm_devices[] = {
1041 &s3c_device_i2c5.dev,
1042 &s3c_device_adc.dev,
1043 NULL, /* Reserved for UART */
1044 NULL,
1045};
1046
1047static void __init nuri_power_init(void) 1077static void __init nuri_power_init(void)
1048{ 1078{
1049 int gpio; 1079 int gpio;
@@ -1088,10 +1118,141 @@ static void __init nuri_ehci_init(void)
1088 s5p_ehci_set_platdata(pdata); 1118 s5p_ehci_set_platdata(pdata);
1089} 1119}
1090 1120
1121/* CAMERA */
1122static struct regulator_consumer_supply cam_vdda_supply[] = {
1123 REGULATOR_SUPPLY("a_sensor", "0-001f"),
1124};
1125
1126static struct regulator_init_data cam_vdda_reg_init_data = {
1127 .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
1128 .num_consumer_supplies = ARRAY_SIZE(cam_vdda_supply),
1129 .consumer_supplies = cam_vdda_supply,
1130};
1131
1132static struct fixed_voltage_config cam_vdda_fixed_voltage_cfg = {
1133 .supply_name = "CAM_IO_EN",
1134 .microvolts = 2800000,
1135 .gpio = EXYNOS4_GPE2(1), /* CAM_IO_EN */
1136 .enable_high = 1,
1137 .init_data = &cam_vdda_reg_init_data,
1138};
1139
1140static struct platform_device cam_vdda_fixed_rdev = {
1141 .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_A28V,
1142 .dev = { .platform_data = &cam_vdda_fixed_voltage_cfg },
1143};
1144
1145static struct regulator_consumer_supply camera_8m_12v_supply =
1146 REGULATOR_SUPPLY("dig_12", "0-001f");
1147
1148static struct regulator_init_data cam_8m_12v_reg_init_data = {
1149 .num_consumer_supplies = 1,
1150 .consumer_supplies = &camera_8m_12v_supply,
1151 .constraints = {
1152 .valid_ops_mask = REGULATOR_CHANGE_STATUS
1153 },
1154};
1155
1156static struct fixed_voltage_config cam_8m_12v_fixed_voltage_cfg = {
1157 .supply_name = "8M_1.2V",
1158 .microvolts = 1200000,
1159 .gpio = EXYNOS4_GPE2(5), /* 8M_1.2V_EN */
1160 .enable_high = 1,
1161 .init_data = &cam_8m_12v_reg_init_data,
1162};
1163
1164static struct platform_device cam_8m_12v_fixed_rdev = {
1165 .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_12V,
1166 .dev = { .platform_data = &cam_8m_12v_fixed_voltage_cfg },
1167};
1168
1169static struct s5p_platform_mipi_csis mipi_csis_platdata = {
1170 .clk_rate = 166000000UL,
1171 .lanes = 2,
1172 .alignment = 32,
1173 .hs_settle = 12,
1174 .phy_enable = s5p_csis_phy_enable,
1175};
1176
1177#define GPIO_CAM_MEGA_RST EXYNOS4_GPY3(7) /* ISP_RESET */
1178#define GPIO_CAM_8M_ISP_INT EXYNOS4_GPL2(5)
1179
1180static struct m5mols_platform_data m5mols_platdata = {
1181 .gpio_reset = GPIO_CAM_MEGA_RST,
1182};
1183
1184static struct i2c_board_info m5mols_board_info = {
1185 I2C_BOARD_INFO("M5MOLS", 0x1F),
1186 .platform_data = &m5mols_platdata,
1187};
1188
1189static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
1190 {
1191 .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
1192 V4L2_MBUS_VSYNC_ACTIVE_LOW,
1193 .bus_type = FIMC_MIPI_CSI2,
1194 .board_info = &m5mols_board_info,
1195 .clk_frequency = 24000000UL,
1196 .csi_data_align = 32,
1197 },
1198};
1199
1200static struct s5p_platform_fimc fimc_md_platdata = {
1201 .isp_info = nuri_camera_sensors,
1202 .num_clients = ARRAY_SIZE(nuri_camera_sensors),
1203};
1204
1205static struct gpio nuri_camera_gpios[] = {
1206 { GPIO_CAM_8M_ISP_INT, GPIOF_IN, "8M_ISP_INT" },
1207 { GPIO_CAM_MEGA_RST, GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
1208};
1209
1210static void nuri_camera_init(void)
1211{
1212 s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
1213 &s5p_device_mipi_csis0);
1214 s3c_set_platdata(&fimc_md_platdata, sizeof(fimc_md_platdata),
1215 &s5p_device_fimc_md);
1216
1217 if (gpio_request_array(nuri_camera_gpios,
1218 ARRAY_SIZE(nuri_camera_gpios))) {
1219 pr_err("%s: GPIO request failed\n", __func__);
1220 return;
1221 }
1222
1223 m5mols_board_info.irq = s5p_register_gpio_interrupt(GPIO_CAM_8M_ISP_INT);
1224 if (!IS_ERR_VALUE(m5mols_board_info.irq))
1225 s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xF));
1226 else
1227 pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
1228
1229 /* Free GPIOs controlled directly by the sensor drivers. */
1230 gpio_free(GPIO_CAM_MEGA_RST);
1231
1232 if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
1233 pr_err("%s: Camera port A setup failed\n", __func__);
1234 return;
1235 }
1236 /* Increase drive strength of the sensor clock output */
1237 s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
1238}
1239
1240static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
1241 .frequency = 400000U,
1242 .sda_delay = 200,
1243};
1244
1091static struct platform_device *nuri_devices[] __initdata = { 1245static struct platform_device *nuri_devices[] __initdata = {
1092 /* Samsung Platform Devices */ 1246 /* Samsung Platform Devices */
1093 &s3c_device_i2c5, /* PMIC should initialize first */ 1247 &s3c_device_i2c5, /* PMIC should initialize first */
1248 &s3c_device_i2c0,
1094 &emmc_fixed_voltage, 1249 &emmc_fixed_voltage,
1250 &s5p_device_mipi_csis0,
1251 &s5p_device_fimc0,
1252 &s5p_device_fimc1,
1253 &s5p_device_fimc2,
1254 &s5p_device_fimc3,
1255 &s5p_device_fimd0,
1095 &s3c_device_hsmmc0, 1256 &s3c_device_hsmmc0,
1096 &s3c_device_hsmmc2, 1257 &s3c_device_hsmmc2,
1097 &s3c_device_hsmmc3, 1258 &s3c_device_hsmmc3,
@@ -1106,6 +1267,9 @@ static struct platform_device *nuri_devices[] __initdata = {
1106 &s5p_device_mfc_l, 1267 &s5p_device_mfc_l,
1107 &s5p_device_mfc_r, 1268 &s5p_device_mfc_r,
1108 &exynos4_device_pd[PD_MFC], 1269 &exynos4_device_pd[PD_MFC],
1270 &exynos4_device_pd[PD_LCD0],
1271 &exynos4_device_pd[PD_CAM],
1272 &s5p_device_fimc_md,
1109 1273
1110 /* NURI Devices */ 1274 /* NURI Devices */
1111 &nuri_gpio_keys, 1275 &nuri_gpio_keys,
@@ -1113,6 +1277,8 @@ static struct platform_device *nuri_devices[] __initdata = {
1113 &nuri_backlight_device, 1277 &nuri_backlight_device,
1114 &max8903_fixed_reg_dev, 1278 &max8903_fixed_reg_dev,
1115 &nuri_max8903_device, 1279 &nuri_max8903_device,
1280 &cam_vdda_fixed_rdev,
1281 &cam_8m_12v_fixed_rdev,
1116}; 1282};
1117 1283
1118static void __init nuri_map_io(void) 1284static void __init nuri_map_io(void)
@@ -1133,6 +1299,7 @@ static void __init nuri_machine_init(void)
1133 nuri_tsp_init(); 1299 nuri_tsp_init();
1134 nuri_power_init(); 1300 nuri_power_init();
1135 1301
1302 s3c_i2c0_set_platdata(&nuri_i2c0_platdata);
1136 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 1303 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
1137 s3c_i2c3_set_platdata(&i2c3_data); 1304 s3c_i2c3_set_platdata(&i2c3_data);
1138 i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs)); 1305 i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
@@ -1142,12 +1309,23 @@ static void __init nuri_machine_init(void)
1142 i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3)); 1309 i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
1143 i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs)); 1310 i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
1144 1311
1312 s5p_fimd0_set_platdata(&nuri_fb_pdata);
1313
1314 nuri_camera_init();
1315
1145 nuri_ehci_init(); 1316 nuri_ehci_init();
1146 clk_xusbxti.rate = 24000000; 1317 clk_xusbxti.rate = 24000000;
1147 1318
1148 /* Last */ 1319 /* Last */
1149 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); 1320 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
1150 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev; 1321 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
1322 s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
1323
1324 s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1325 s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1326 s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1327 s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1328 s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1151} 1329}
1152 1330
1153MACHINE_START(NURI, "NURI") 1331MACHINE_START(NURI, "NURI")
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
new file mode 100644
index 000000000000..f80b563f2be7
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -0,0 +1,700 @@
1/* linux/arch/arm/mach-exynos4/mach-origen.c
2 *
3 * Copyright (c) 2011 Insignal Co., Ltd.
4 * http://www.insignal.co.kr/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/serial_core.h>
12#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/input.h>
17#include <linux/pwm_backlight.h>
18#include <linux/gpio_keys.h>
19#include <linux/i2c.h>
20#include <linux/regulator/machine.h>
21#include <linux/mfd/max8997.h>
22#include <linux/lcd.h>
23
24#include <asm/mach/arch.h>
25#include <asm/mach-types.h>
26
27#include <video/platform_lcd.h>
28
29#include <plat/regs-serial.h>
30#include <plat/regs-fb-v4.h>
31#include <plat/exynos4.h>
32#include <plat/cpu.h>
33#include <plat/devs.h>
34#include <plat/sdhci.h>
35#include <plat/iic.h>
36#include <plat/ehci.h>
37#include <plat/clock.h>
38#include <plat/gpio-cfg.h>
39#include <plat/backlight.h>
40#include <plat/pd.h>
41#include <plat/fb.h>
42#include <plat/mfc.h>
43
44#include <mach/map.h>
45
46/* Following are default values for UCON, ULCON and UFCON UART registers */
47#define ORIGEN_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
48 S3C2410_UCON_RXILEVEL | \
49 S3C2410_UCON_TXIRQMODE | \
50 S3C2410_UCON_RXIRQMODE | \
51 S3C2410_UCON_RXFIFO_TOI | \
52 S3C2443_UCON_RXERR_IRQEN)
53
54#define ORIGEN_ULCON_DEFAULT S3C2410_LCON_CS8
55
56#define ORIGEN_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
57 S5PV210_UFCON_TXTRIG4 | \
58 S5PV210_UFCON_RXTRIG4)
59
60static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
61 [0] = {
62 .hwport = 0,
63 .flags = 0,
64 .ucon = ORIGEN_UCON_DEFAULT,
65 .ulcon = ORIGEN_ULCON_DEFAULT,
66 .ufcon = ORIGEN_UFCON_DEFAULT,
67 },
68 [1] = {
69 .hwport = 1,
70 .flags = 0,
71 .ucon = ORIGEN_UCON_DEFAULT,
72 .ulcon = ORIGEN_ULCON_DEFAULT,
73 .ufcon = ORIGEN_UFCON_DEFAULT,
74 },
75 [2] = {
76 .hwport = 2,
77 .flags = 0,
78 .ucon = ORIGEN_UCON_DEFAULT,
79 .ulcon = ORIGEN_ULCON_DEFAULT,
80 .ufcon = ORIGEN_UFCON_DEFAULT,
81 },
82 [3] = {
83 .hwport = 3,
84 .flags = 0,
85 .ucon = ORIGEN_UCON_DEFAULT,
86 .ulcon = ORIGEN_ULCON_DEFAULT,
87 .ufcon = ORIGEN_UFCON_DEFAULT,
88 },
89};
90
91static struct regulator_consumer_supply __initdata ldo3_consumer[] = {
92 REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
93 REGULATOR_SUPPLY("vdd", "exynos4-hdmi"), /* HDMI */
94 REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"), /* HDMI */
95};
96static struct regulator_consumer_supply __initdata ldo6_consumer[] = {
97 REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
98};
99static struct regulator_consumer_supply __initdata ldo7_consumer[] = {
100 REGULATOR_SUPPLY("avdd", "alc5625"), /* Realtek ALC5625 */
101};
102static struct regulator_consumer_supply __initdata ldo8_consumer[] = {
103 REGULATOR_SUPPLY("vdd", "s5p-adc"), /* ADC */
104 REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"), /* HDMI */
105};
106static struct regulator_consumer_supply __initdata ldo9_consumer[] = {
107 REGULATOR_SUPPLY("dvdd", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
108};
109static struct regulator_consumer_supply __initdata ldo11_consumer[] = {
110 REGULATOR_SUPPLY("dvdd", "alc5625"), /* Realtek ALC5625 */
111};
112static struct regulator_consumer_supply __initdata ldo14_consumer[] = {
113 REGULATOR_SUPPLY("avdd18", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
114};
115static struct regulator_consumer_supply __initdata ldo17_consumer[] = {
116 REGULATOR_SUPPLY("vdd33", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
117};
118static struct regulator_consumer_supply __initdata buck1_consumer[] = {
119 REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
120};
121static struct regulator_consumer_supply __initdata buck2_consumer[] = {
122 REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
123};
124static struct regulator_consumer_supply __initdata buck3_consumer[] = {
125 REGULATOR_SUPPLY("vdd_g3d", "mali_drm"), /* G3D */
126};
127static struct regulator_consumer_supply __initdata buck7_consumer[] = {
128 REGULATOR_SUPPLY("vcc", "platform-lcd"), /* LCD */
129};
130
131static struct regulator_init_data __initdata max8997_ldo1_data = {
132 .constraints = {
133 .name = "VDD_ABB_3.3V",
134 .min_uV = 3300000,
135 .max_uV = 3300000,
136 .apply_uV = 1,
137 .state_mem = {
138 .disabled = 1,
139 },
140 },
141};
142
143static struct regulator_init_data __initdata max8997_ldo2_data = {
144 .constraints = {
145 .name = "VDD_ALIVE_1.1V",
146 .min_uV = 1100000,
147 .max_uV = 1100000,
148 .apply_uV = 1,
149 .always_on = 1,
150 .state_mem = {
151 .enabled = 1,
152 },
153 },
154};
155
156static struct regulator_init_data __initdata max8997_ldo3_data = {
157 .constraints = {
158 .name = "VMIPI_1.1V",
159 .min_uV = 1100000,
160 .max_uV = 1100000,
161 .apply_uV = 1,
162 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
163 .state_mem = {
164 .disabled = 1,
165 },
166 },
167 .num_consumer_supplies = ARRAY_SIZE(ldo3_consumer),
168 .consumer_supplies = ldo3_consumer,
169};
170
171static struct regulator_init_data __initdata max8997_ldo4_data = {
172 .constraints = {
173 .name = "VDD_RTC_1.8V",
174 .min_uV = 1800000,
175 .max_uV = 1800000,
176 .apply_uV = 1,
177 .always_on = 1,
178 .state_mem = {
179 .disabled = 1,
180 },
181 },
182};
183
184static struct regulator_init_data __initdata max8997_ldo6_data = {
185 .constraints = {
186 .name = "VMIPI_1.8V",
187 .min_uV = 1800000,
188 .max_uV = 1800000,
189 .apply_uV = 1,
190 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
191 .state_mem = {
192 .disabled = 1,
193 },
194 },
195 .num_consumer_supplies = ARRAY_SIZE(ldo6_consumer),
196 .consumer_supplies = ldo6_consumer,
197};
198
199static struct regulator_init_data __initdata max8997_ldo7_data = {
200 .constraints = {
201 .name = "VDD_AUD_1.8V",
202 .min_uV = 1800000,
203 .max_uV = 1800000,
204 .apply_uV = 1,
205 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
206 .state_mem = {
207 .disabled = 1,
208 },
209 },
210 .num_consumer_supplies = ARRAY_SIZE(ldo7_consumer),
211 .consumer_supplies = ldo7_consumer,
212};
213
214static struct regulator_init_data __initdata max8997_ldo8_data = {
215 .constraints = {
216 .name = "VADC_3.3V",
217 .min_uV = 3300000,
218 .max_uV = 3300000,
219 .apply_uV = 1,
220 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
221 .state_mem = {
222 .disabled = 1,
223 },
224 },
225 .num_consumer_supplies = ARRAY_SIZE(ldo8_consumer),
226 .consumer_supplies = ldo8_consumer,
227};
228
229static struct regulator_init_data __initdata max8997_ldo9_data = {
230 .constraints = {
231 .name = "DVDD_SWB_2.8V",
232 .min_uV = 2800000,
233 .max_uV = 2800000,
234 .apply_uV = 1,
235 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
236 .state_mem = {
237 .disabled = 1,
238 },
239 },
240 .num_consumer_supplies = ARRAY_SIZE(ldo9_consumer),
241 .consumer_supplies = ldo9_consumer,
242};
243
244static struct regulator_init_data __initdata max8997_ldo10_data = {
245 .constraints = {
246 .name = "VDD_PLL_1.1V",
247 .min_uV = 1100000,
248 .max_uV = 1100000,
249 .apply_uV = 1,
250 .always_on = 1,
251 .state_mem = {
252 .disabled = 1,
253 },
254 },
255};
256
257static struct regulator_init_data __initdata max8997_ldo11_data = {
258 .constraints = {
259 .name = "VDD_AUD_3V",
260 .min_uV = 3000000,
261 .max_uV = 3000000,
262 .apply_uV = 1,
263 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
264 .state_mem = {
265 .disabled = 1,
266 },
267 },
268 .num_consumer_supplies = ARRAY_SIZE(ldo11_consumer),
269 .consumer_supplies = ldo11_consumer,
270};
271
272static struct regulator_init_data __initdata max8997_ldo14_data = {
273 .constraints = {
274 .name = "AVDD18_SWB_1.8V",
275 .min_uV = 1800000,
276 .max_uV = 1800000,
277 .apply_uV = 1,
278 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
279 .state_mem = {
280 .disabled = 1,
281 },
282 },
283 .num_consumer_supplies = ARRAY_SIZE(ldo14_consumer),
284 .consumer_supplies = ldo14_consumer,
285};
286
287static struct regulator_init_data __initdata max8997_ldo17_data = {
288 .constraints = {
289 .name = "VDD_SWB_3.3V",
290 .min_uV = 3300000,
291 .max_uV = 3300000,
292 .apply_uV = 1,
293 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
294 .state_mem = {
295 .disabled = 1,
296 },
297 },
298 .num_consumer_supplies = ARRAY_SIZE(ldo17_consumer),
299 .consumer_supplies = ldo17_consumer,
300};
301
302static struct regulator_init_data __initdata max8997_ldo21_data = {
303 .constraints = {
304 .name = "VDD_MIF_1.2V",
305 .min_uV = 1200000,
306 .max_uV = 1200000,
307 .apply_uV = 1,
308 .always_on = 1,
309 .state_mem = {
310 .disabled = 1,
311 },
312 },
313};
314
315static struct regulator_init_data __initdata max8997_buck1_data = {
316 .constraints = {
317 .name = "VDD_ARM_1.2V",
318 .min_uV = 950000,
319 .max_uV = 1350000,
320 .always_on = 1,
321 .boot_on = 1,
322 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
323 .state_mem = {
324 .disabled = 1,
325 },
326 },
327 .num_consumer_supplies = ARRAY_SIZE(buck1_consumer),
328 .consumer_supplies = buck1_consumer,
329};
330
331static struct regulator_init_data __initdata max8997_buck2_data = {
332 .constraints = {
333 .name = "VDD_INT_1.1V",
334 .min_uV = 900000,
335 .max_uV = 1100000,
336 .always_on = 1,
337 .boot_on = 1,
338 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
339 .state_mem = {
340 .disabled = 1,
341 },
342 },
343 .num_consumer_supplies = ARRAY_SIZE(buck2_consumer),
344 .consumer_supplies = buck2_consumer,
345};
346
347static struct regulator_init_data __initdata max8997_buck3_data = {
348 .constraints = {
349 .name = "VDD_G3D_1.1V",
350 .min_uV = 900000,
351 .max_uV = 1100000,
352 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
353 REGULATOR_CHANGE_STATUS,
354 .state_mem = {
355 .disabled = 1,
356 },
357 },
358 .num_consumer_supplies = ARRAY_SIZE(buck3_consumer),
359 .consumer_supplies = buck3_consumer,
360};
361
362static struct regulator_init_data __initdata max8997_buck5_data = {
363 .constraints = {
364 .name = "VDDQ_M1M2_1.2V",
365 .min_uV = 1200000,
366 .max_uV = 1200000,
367 .apply_uV = 1,
368 .always_on = 1,
369 .state_mem = {
370 .disabled = 1,
371 },
372 },
373};
374
375static struct regulator_init_data __initdata max8997_buck7_data = {
376 .constraints = {
377 .name = "VDD_LCD_3.3V",
378 .min_uV = 3300000,
379 .max_uV = 3300000,
380 .boot_on = 1,
381 .apply_uV = 1,
382 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
383 .state_mem = {
384 .disabled = 1
385 },
386 },
387 .num_consumer_supplies = ARRAY_SIZE(buck7_consumer),
388 .consumer_supplies = buck7_consumer,
389};
390
391static struct max8997_regulator_data __initdata origen_max8997_regulators[] = {
392 { MAX8997_LDO1, &max8997_ldo1_data },
393 { MAX8997_LDO2, &max8997_ldo2_data },
394 { MAX8997_LDO3, &max8997_ldo3_data },
395 { MAX8997_LDO4, &max8997_ldo4_data },
396 { MAX8997_LDO6, &max8997_ldo6_data },
397 { MAX8997_LDO7, &max8997_ldo7_data },
398 { MAX8997_LDO8, &max8997_ldo8_data },
399 { MAX8997_LDO9, &max8997_ldo9_data },
400 { MAX8997_LDO10, &max8997_ldo10_data },
401 { MAX8997_LDO11, &max8997_ldo11_data },
402 { MAX8997_LDO14, &max8997_ldo14_data },
403 { MAX8997_LDO17, &max8997_ldo17_data },
404 { MAX8997_LDO21, &max8997_ldo21_data },
405 { MAX8997_BUCK1, &max8997_buck1_data },
406 { MAX8997_BUCK2, &max8997_buck2_data },
407 { MAX8997_BUCK3, &max8997_buck3_data },
408 { MAX8997_BUCK5, &max8997_buck5_data },
409 { MAX8997_BUCK7, &max8997_buck7_data },
410};
411
412struct max8997_platform_data __initdata origen_max8997_pdata = {
413 .num_regulators = ARRAY_SIZE(origen_max8997_regulators),
414 .regulators = origen_max8997_regulators,
415
416 .wakeup = true,
417 .buck1_gpiodvs = false,
418 .buck2_gpiodvs = false,
419 .buck5_gpiodvs = false,
420 .irq_base = IRQ_GPIO_END + 1,
421
422 .ignore_gpiodvs_side_effect = true,
423 .buck125_default_idx = 0x0,
424
425 .buck125_gpios[0] = EXYNOS4_GPX0(0),
426 .buck125_gpios[1] = EXYNOS4_GPX0(1),
427 .buck125_gpios[2] = EXYNOS4_GPX0(2),
428
429 .buck1_voltage[0] = 1350000,
430 .buck1_voltage[1] = 1300000,
431 .buck1_voltage[2] = 1250000,
432 .buck1_voltage[3] = 1200000,
433 .buck1_voltage[4] = 1150000,
434 .buck1_voltage[5] = 1100000,
435 .buck1_voltage[6] = 1000000,
436 .buck1_voltage[7] = 950000,
437
438 .buck2_voltage[0] = 1100000,
439 .buck2_voltage[1] = 1100000,
440 .buck2_voltage[2] = 1100000,
441 .buck2_voltage[3] = 1100000,
442 .buck2_voltage[4] = 1000000,
443 .buck2_voltage[5] = 1000000,
444 .buck2_voltage[6] = 1000000,
445 .buck2_voltage[7] = 1000000,
446
447 .buck5_voltage[0] = 1200000,
448 .buck5_voltage[1] = 1200000,
449 .buck5_voltage[2] = 1200000,
450 .buck5_voltage[3] = 1200000,
451 .buck5_voltage[4] = 1200000,
452 .buck5_voltage[5] = 1200000,
453 .buck5_voltage[6] = 1200000,
454 .buck5_voltage[7] = 1200000,
455};
456
457/* I2C0 */
458static struct i2c_board_info i2c0_devs[] __initdata = {
459 {
460 I2C_BOARD_INFO("max8997", (0xCC >> 1)),
461 .platform_data = &origen_max8997_pdata,
462 .irq = IRQ_EINT(4),
463 },
464};
465
466static struct s3c_sdhci_platdata origen_hsmmc0_pdata __initdata = {
467 .cd_type = S3C_SDHCI_CD_INTERNAL,
468 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
469};
470
471static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
472 .cd_type = S3C_SDHCI_CD_INTERNAL,
473 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
474};
475
476/* USB EHCI */
477static struct s5p_ehci_platdata origen_ehci_pdata;
478
479static void __init origen_ehci_init(void)
480{
481 struct s5p_ehci_platdata *pdata = &origen_ehci_pdata;
482
483 s5p_ehci_set_platdata(pdata);
484}
485
486static struct gpio_keys_button origen_gpio_keys_table[] = {
487 {
488 .code = KEY_MENU,
489 .gpio = EXYNOS4_GPX1(5),
490 .desc = "gpio-keys: KEY_MENU",
491 .type = EV_KEY,
492 .active_low = 1,
493 .wakeup = 1,
494 .debounce_interval = 1,
495 }, {
496 .code = KEY_HOME,
497 .gpio = EXYNOS4_GPX1(6),
498 .desc = "gpio-keys: KEY_HOME",
499 .type = EV_KEY,
500 .active_low = 1,
501 .wakeup = 1,
502 .debounce_interval = 1,
503 }, {
504 .code = KEY_BACK,
505 .gpio = EXYNOS4_GPX1(7),
506 .desc = "gpio-keys: KEY_BACK",
507 .type = EV_KEY,
508 .active_low = 1,
509 .wakeup = 1,
510 .debounce_interval = 1,
511 }, {
512 .code = KEY_UP,
513 .gpio = EXYNOS4_GPX2(0),
514 .desc = "gpio-keys: KEY_UP",
515 .type = EV_KEY,
516 .active_low = 1,
517 .wakeup = 1,
518 .debounce_interval = 1,
519 }, {
520 .code = KEY_DOWN,
521 .gpio = EXYNOS4_GPX2(1),
522 .desc = "gpio-keys: KEY_DOWN",
523 .type = EV_KEY,
524 .active_low = 1,
525 .wakeup = 1,
526 .debounce_interval = 1,
527 },
528};
529
530static struct gpio_keys_platform_data origen_gpio_keys_data = {
531 .buttons = origen_gpio_keys_table,
532 .nbuttons = ARRAY_SIZE(origen_gpio_keys_table),
533};
534
535static struct platform_device origen_device_gpiokeys = {
536 .name = "gpio-keys",
537 .dev = {
538 .platform_data = &origen_gpio_keys_data,
539 },
540};
541
542static void lcd_hv070wsa_set_power(struct plat_lcd_data *pd, unsigned int power)
543{
544 int ret;
545
546 if (power)
547 ret = gpio_request_one(EXYNOS4_GPE3(4),
548 GPIOF_OUT_INIT_HIGH, "GPE3_4");
549 else
550 ret = gpio_request_one(EXYNOS4_GPE3(4),
551 GPIOF_OUT_INIT_LOW, "GPE3_4");
552
553 gpio_free(EXYNOS4_GPE3(4));
554
555 if (ret)
556 pr_err("failed to request gpio for LCD power: %d\n", ret);
557}
558
559static struct plat_lcd_data origen_lcd_hv070wsa_data = {
560 .set_power = lcd_hv070wsa_set_power,
561};
562
563static struct platform_device origen_lcd_hv070wsa = {
564 .name = "platform-lcd",
565 .dev.parent = &s5p_device_fimd0.dev,
566 .dev.platform_data = &origen_lcd_hv070wsa_data,
567};
568
569static struct s3c_fb_pd_win origen_fb_win0 = {
570 .win_mode = {
571 .left_margin = 64,
572 .right_margin = 16,
573 .upper_margin = 64,
574 .lower_margin = 16,
575 .hsync_len = 48,
576 .vsync_len = 3,
577 .xres = 1024,
578 .yres = 600,
579 },
580 .max_bpp = 32,
581 .default_bpp = 24,
582};
583
584static struct s3c_fb_platdata origen_lcd_pdata __initdata = {
585 .win[0] = &origen_fb_win0,
586 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
587 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
588 .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
589};
590
591static struct platform_device *origen_devices[] __initdata = {
592 &s3c_device_hsmmc2,
593 &s3c_device_hsmmc0,
594 &s3c_device_i2c0,
595 &s3c_device_rtc,
596 &s3c_device_wdt,
597 &s5p_device_ehci,
598 &s5p_device_fimc0,
599 &s5p_device_fimc1,
600 &s5p_device_fimc2,
601 &s5p_device_fimc3,
602 &s5p_device_fimd0,
603 &s5p_device_hdmi,
604 &s5p_device_i2c_hdmiphy,
605 &s5p_device_mfc,
606 &s5p_device_mfc_l,
607 &s5p_device_mfc_r,
608 &s5p_device_mixer,
609 &exynos4_device_pd[PD_LCD0],
610 &exynos4_device_pd[PD_TV],
611 &exynos4_device_pd[PD_G3D],
612 &exynos4_device_pd[PD_LCD1],
613 &exynos4_device_pd[PD_CAM],
614 &exynos4_device_pd[PD_GPS],
615 &exynos4_device_pd[PD_MFC],
616 &origen_device_gpiokeys,
617 &origen_lcd_hv070wsa,
618};
619
620/* LCD Backlight data */
621static struct samsung_bl_gpio_info origen_bl_gpio_info = {
622 .no = EXYNOS4_GPD0(0),
623 .func = S3C_GPIO_SFN(2),
624};
625
626static struct platform_pwm_backlight_data origen_bl_data = {
627 .pwm_id = 0,
628 .pwm_period_ns = 1000,
629};
630
631static void s5p_tv_setup(void)
632{
633 /* Direct HPD to HDMI chip */
634 gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
635 s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
636 s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
637}
638
639static void __init origen_map_io(void)
640{
641 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
642 s3c24xx_init_clocks(24000000);
643 s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
644}
645
646static void __init origen_power_init(void)
647{
648 gpio_request(EXYNOS4_GPX0(4), "PMIC_IRQ");
649 s3c_gpio_cfgpin(EXYNOS4_GPX0(4), S3C_GPIO_SFN(0xf));
650 s3c_gpio_setpull(EXYNOS4_GPX0(4), S3C_GPIO_PULL_NONE);
651}
652
653static void __init origen_reserve(void)
654{
655 s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
656}
657
658static void __init origen_machine_init(void)
659{
660 origen_power_init();
661
662 s3c_i2c0_set_platdata(NULL);
663 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
664
665 /*
666 * Since sdhci instance 2 can contain a bootable media,
667 * sdhci instance 0 is registered after instance 2.
668 */
669 s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
670 s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);
671
672 origen_ehci_init();
673 clk_xusbxti.rate = 24000000;
674
675 s5p_tv_setup();
676 s5p_i2c_hdmiphy_set_platdata(NULL);
677
678 s5p_fimd0_set_platdata(&origen_lcd_pdata);
679
680 platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
681
682 s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
683
684 s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
685 s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
686
687 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
688
689 samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
690}
691
692MACHINE_START(ORIGEN, "ORIGEN")
693 /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
694 .atag_offset = 0x100,
695 .init_irq = exynos4_init_irq,
696 .map_io = origen_map_io,
697 .init_machine = origen_machine_init,
698 .timer = &exynos4_timer,
699 .reserve = &origen_reserve,
700MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index fcf2e0e23d53..fcf2e0e23d53 100644
--- a/arch/arm/mach-exynos4/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 2c1a076c6a73..cec2afabe7b4 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -37,6 +37,9 @@
37#include <plat/pd.h> 37#include <plat/pd.h>
38#include <plat/gpio-cfg.h> 38#include <plat/gpio-cfg.h>
39#include <plat/backlight.h> 39#include <plat/backlight.h>
40#include <plat/mfc.h>
41#include <plat/ehci.h>
42#include <plat/clock.h>
40 43
41#include <mach/map.h> 44#include <mach/map.h>
42 45
@@ -232,17 +235,36 @@ static struct i2c_board_info i2c_devs1[] __initdata = {
232 {I2C_BOARD_INFO("wm8994", 0x1a),}, 235 {I2C_BOARD_INFO("wm8994", 0x1a),},
233}; 236};
234 237
238/* USB EHCI */
239static struct s5p_ehci_platdata smdkv310_ehci_pdata;
240
241static void __init smdkv310_ehci_init(void)
242{
243 struct s5p_ehci_platdata *pdata = &smdkv310_ehci_pdata;
244
245 s5p_ehci_set_platdata(pdata);
246}
247
235static struct platform_device *smdkv310_devices[] __initdata = { 248static struct platform_device *smdkv310_devices[] __initdata = {
236 &s3c_device_hsmmc0, 249 &s3c_device_hsmmc0,
237 &s3c_device_hsmmc1, 250 &s3c_device_hsmmc1,
238 &s3c_device_hsmmc2, 251 &s3c_device_hsmmc2,
239 &s3c_device_hsmmc3, 252 &s3c_device_hsmmc3,
240 &s3c_device_i2c1, 253 &s3c_device_i2c1,
254 &s5p_device_i2c_hdmiphy,
241 &s3c_device_rtc, 255 &s3c_device_rtc,
242 &s3c_device_wdt, 256 &s3c_device_wdt,
257 &s5p_device_ehci,
258 &s5p_device_fimc0,
259 &s5p_device_fimc1,
260 &s5p_device_fimc2,
261 &s5p_device_fimc3,
243 &exynos4_device_ac97, 262 &exynos4_device_ac97,
244 &exynos4_device_i2s0, 263 &exynos4_device_i2s0,
245 &samsung_device_keypad, 264 &samsung_device_keypad,
265 &s5p_device_mfc,
266 &s5p_device_mfc_l,
267 &s5p_device_mfc_r,
246 &exynos4_device_pd[PD_MFC], 268 &exynos4_device_pd[PD_MFC],
247 &exynos4_device_pd[PD_G3D], 269 &exynos4_device_pd[PD_G3D],
248 &exynos4_device_pd[PD_LCD0], 270 &exynos4_device_pd[PD_LCD0],
@@ -258,6 +280,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
258 &smdkv310_lcd_lte480wv, 280 &smdkv310_lcd_lte480wv,
259 &smdkv310_smsc911x, 281 &smdkv310_smsc911x,
260 &exynos4_device_ahci, 282 &exynos4_device_ahci,
283 &s5p_device_hdmi,
284 &s5p_device_mixer,
261}; 285};
262 286
263static void __init smdkv310_smsc911x_init(void) 287static void __init smdkv310_smsc911x_init(void)
@@ -294,6 +318,18 @@ static struct platform_pwm_backlight_data smdkv310_bl_data = {
294 .pwm_period_ns = 1000, 318 .pwm_period_ns = 1000,
295}; 319};
296 320
321static void s5p_tv_setup(void)
322{
323 /* direct HPD to HDMI chip */
324 WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
325 s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
326 s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
327
328 /* setup dependencies between TV devices */
329 s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
330 s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
331}
332
297static void __init smdkv310_map_io(void) 333static void __init smdkv310_map_io(void)
298{ 334{
299 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 335 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -301,6 +337,11 @@ static void __init smdkv310_map_io(void)
301 s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs)); 337 s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
302} 338}
303 339
340static void __init smdkv310_reserve(void)
341{
342 s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
343}
344
304static void __init smdkv310_machine_init(void) 345static void __init smdkv310_machine_init(void)
305{ 346{
306 s3c_i2c1_set_platdata(NULL); 347 s3c_i2c1_set_platdata(NULL);
@@ -313,12 +354,19 @@ static void __init smdkv310_machine_init(void)
313 s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata); 354 s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
314 s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata); 355 s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
315 356
357 s5p_tv_setup();
358 s5p_i2c_hdmiphy_set_platdata(NULL);
359
316 samsung_keypad_set_platdata(&smdkv310_keypad_data); 360 samsung_keypad_set_platdata(&smdkv310_keypad_data);
317 361
318 samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data); 362 samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
319 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata); 363 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
320 364
365 smdkv310_ehci_init();
366 clk_xusbxti.rate = 24000000;
367
321 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); 368 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
369 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
322} 370}
323 371
324MACHINE_START(SMDKV310, "SMDKV310") 372MACHINE_START(SMDKV310, "SMDKV310")
@@ -329,6 +377,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
329 .map_io = smdkv310_map_io, 377 .map_io = smdkv310_map_io,
330 .init_machine = smdkv310_machine_init, 378 .init_machine = smdkv310_machine_init,
331 .timer = &exynos4_timer, 379 .timer = &exynos4_timer,
380 .reserve = &smdkv310_reserve,
332MACHINE_END 381MACHINE_END
333 382
334MACHINE_START(SMDKC210, "SMDKC210") 383MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 2aac6f755c8e..a2a177ff4b44 100644
--- a/arch/arm/mach-exynos4/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -13,6 +13,7 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/gpio_keys.h> 14#include <linux/gpio_keys.h>
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/fb.h>
16#include <linux/mfd/max8998.h> 17#include <linux/mfd/max8998.h>
17#include <linux/regulator/machine.h> 18#include <linux/regulator/machine.h>
18#include <linux/regulator/fixed.h> 19#include <linux/regulator/fixed.h>
@@ -31,12 +32,21 @@
31#include <plat/devs.h> 32#include <plat/devs.h>
32#include <plat/iic.h> 33#include <plat/iic.h>
33#include <plat/gpio-cfg.h> 34#include <plat/gpio-cfg.h>
35#include <plat/fb.h>
34#include <plat/mfc.h> 36#include <plat/mfc.h>
35#include <plat/sdhci.h> 37#include <plat/sdhci.h>
36#include <plat/pd.h> 38#include <plat/pd.h>
39#include <plat/regs-fb-v4.h>
40#include <plat/fimc-core.h>
41#include <plat/camport.h>
42#include <plat/mipi_csis.h>
37 43
38#include <mach/map.h> 44#include <mach/map.h>
39 45
46#include <media/v4l2-mediabus.h>
47#include <media/s5p_fimc.h>
48#include <media/m5mols.h>
49
40/* Following are default values for UCON, ULCON and UFCON UART registers */ 50/* Following are default values for UCON, ULCON and UFCON UART registers */
41#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 51#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
42 S3C2410_UCON_RXILEVEL | \ 52 S3C2410_UCON_RXILEVEL | \
@@ -110,6 +120,9 @@ static struct regulator_consumer_supply lp3974_buck1_consumer =
110static struct regulator_consumer_supply lp3974_buck2_consumer = 120static struct regulator_consumer_supply lp3974_buck2_consumer =
111 REGULATOR_SUPPLY("vddg3d", NULL); 121 REGULATOR_SUPPLY("vddg3d", NULL);
112 122
123static struct regulator_consumer_supply lp3974_buck3_consumer =
124 REGULATOR_SUPPLY("vdet", "s5p-sdo");
125
113static struct regulator_init_data lp3974_buck1_data = { 126static struct regulator_init_data lp3974_buck1_data = {
114 .constraints = { 127 .constraints = {
115 .name = "VINT_1.1V", 128 .name = "VINT_1.1V",
@@ -153,6 +166,8 @@ static struct regulator_init_data lp3974_buck3_data = {
153 .enabled = 1, 166 .enabled = 1,
154 }, 167 },
155 }, 168 },
169 .num_consumer_supplies = 1,
170 .consumer_supplies = &lp3974_buck3_consumer,
156}; 171};
157 172
158static struct regulator_init_data lp3974_buck4_data = { 173static struct regulator_init_data lp3974_buck4_data = {
@@ -181,6 +196,12 @@ static struct regulator_init_data lp3974_ldo2_data = {
181 }, 196 },
182}; 197};
183 198
199static struct regulator_consumer_supply lp3974_ldo3_consumer[] = {
200 REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
201 REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
202 REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"),
203};
204
184static struct regulator_init_data lp3974_ldo3_data = { 205static struct regulator_init_data lp3974_ldo3_data = {
185 .constraints = { 206 .constraints = {
186 .name = "VUSB+MIPI_1.1V", 207 .name = "VUSB+MIPI_1.1V",
@@ -192,6 +213,12 @@ static struct regulator_init_data lp3974_ldo3_data = {
192 .disabled = 1, 213 .disabled = 1,
193 }, 214 },
194 }, 215 },
216 .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo3_consumer),
217 .consumer_supplies = lp3974_ldo3_consumer,
218};
219
220static struct regulator_consumer_supply lp3974_ldo4_consumer[] = {
221 REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
195}; 222};
196 223
197static struct regulator_init_data lp3974_ldo4_data = { 224static struct regulator_init_data lp3974_ldo4_data = {
@@ -205,6 +232,8 @@ static struct regulator_init_data lp3974_ldo4_data = {
205 .disabled = 1, 232 .disabled = 1,
206 }, 233 },
207 }, 234 },
235 .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo4_consumer),
236 .consumer_supplies = lp3974_ldo4_consumer,
208}; 237};
209 238
210static struct regulator_init_data lp3974_ldo5_data = { 239static struct regulator_init_data lp3974_ldo5_data = {
@@ -233,6 +262,10 @@ static struct regulator_init_data lp3974_ldo6_data = {
233 }, 262 },
234}; 263};
235 264
265static struct regulator_consumer_supply lp3974_ldo7_consumer[] = {
266 REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"),
267};
268
236static struct regulator_init_data lp3974_ldo7_data = { 269static struct regulator_init_data lp3974_ldo7_data = {
237 .constraints = { 270 .constraints = {
238 .name = "VLCD+VMIPI_1.8V", 271 .name = "VLCD+VMIPI_1.8V",
@@ -244,6 +277,12 @@ static struct regulator_init_data lp3974_ldo7_data = {
244 .disabled = 1, 277 .disabled = 1,
245 }, 278 },
246 }, 279 },
280 .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo7_consumer),
281 .consumer_supplies = lp3974_ldo7_consumer,
282};
283
284static struct regulator_consumer_supply lp3974_ldo8_consumer[] = {
285 REGULATOR_SUPPLY("vdd33a_dac", "s5p-sdo"),
247}; 286};
248 287
249static struct regulator_init_data lp3974_ldo8_data = { 288static struct regulator_init_data lp3974_ldo8_data = {
@@ -257,6 +296,8 @@ static struct regulator_init_data lp3974_ldo8_data = {
257 .disabled = 1, 296 .disabled = 1,
258 }, 297 },
259 }, 298 },
299 .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo8_consumer),
300 .consumer_supplies = lp3974_ldo8_consumer,
260}; 301};
261 302
262static struct regulator_init_data lp3974_ldo9_data = { 303static struct regulator_init_data lp3974_ldo9_data = {
@@ -286,6 +327,9 @@ static struct regulator_init_data lp3974_ldo10_data = {
286 }, 327 },
287}; 328};
288 329
330static struct regulator_consumer_supply lp3974_ldo11_consumer =
331 REGULATOR_SUPPLY("dig_28", "0-001f");
332
289static struct regulator_init_data lp3974_ldo11_data = { 333static struct regulator_init_data lp3974_ldo11_data = {
290 .constraints = { 334 .constraints = {
291 .name = "CAM_AF_3.3V", 335 .name = "CAM_AF_3.3V",
@@ -297,6 +341,8 @@ static struct regulator_init_data lp3974_ldo11_data = {
297 .disabled = 1, 341 .disabled = 1,
298 }, 342 },
299 }, 343 },
344 .num_consumer_supplies = 1,
345 .consumer_supplies = &lp3974_ldo11_consumer,
300}; 346};
301 347
302static struct regulator_init_data lp3974_ldo12_data = { 348static struct regulator_init_data lp3974_ldo12_data = {
@@ -325,6 +371,9 @@ static struct regulator_init_data lp3974_ldo13_data = {
325 }, 371 },
326}; 372};
327 373
374static struct regulator_consumer_supply lp3974_ldo14_consumer =
375 REGULATOR_SUPPLY("dig_18", "0-001f");
376
328static struct regulator_init_data lp3974_ldo14_data = { 377static struct regulator_init_data lp3974_ldo14_data = {
329 .constraints = { 378 .constraints = {
330 .name = "CAM_I_HOST_1.8V", 379 .name = "CAM_I_HOST_1.8V",
@@ -336,8 +385,14 @@ static struct regulator_init_data lp3974_ldo14_data = {
336 .disabled = 1, 385 .disabled = 1,
337 }, 386 },
338 }, 387 },
388 .num_consumer_supplies = 1,
389 .consumer_supplies = &lp3974_ldo14_consumer,
339}; 390};
340 391
392
393static struct regulator_consumer_supply lp3974_ldo15_consumer =
394 REGULATOR_SUPPLY("dig_12", "0-001f");
395
341static struct regulator_init_data lp3974_ldo15_data = { 396static struct regulator_init_data lp3974_ldo15_data = {
342 .constraints = { 397 .constraints = {
343 .name = "CAM_S_DIG+FM33_CORE_1.2V", 398 .name = "CAM_S_DIG+FM33_CORE_1.2V",
@@ -349,6 +404,12 @@ static struct regulator_init_data lp3974_ldo15_data = {
349 .disabled = 1, 404 .disabled = 1,
350 }, 405 },
351 }, 406 },
407 .num_consumer_supplies = 1,
408 .consumer_supplies = &lp3974_ldo15_consumer,
409};
410
411static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
412 REGULATOR_SUPPLY("a_sensor", "0-001f"),
352}; 413};
353 414
354static struct regulator_init_data lp3974_ldo16_data = { 415static struct regulator_init_data lp3974_ldo16_data = {
@@ -362,6 +423,8 @@ static struct regulator_init_data lp3974_ldo16_data = {
362 .disabled = 1, 423 .disabled = 1,
363 }, 424 },
364 }, 425 },
426 .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo16_consumer),
427 .consumer_supplies = lp3974_ldo16_consumer,
365}; 428};
366 429
367static struct regulator_init_data lp3974_ldo17_data = { 430static struct regulator_init_data lp3974_ldo17_data = {
@@ -472,6 +535,43 @@ static struct max8998_platform_data universal_lp3974_pdata = {
472 .wakeup = true, 535 .wakeup = true,
473}; 536};
474 537
538
539enum fixed_regulator_id {
540 FIXED_REG_ID_MMC0,
541 FIXED_REG_ID_HDMI_5V,
542 FIXED_REG_ID_CAM_S_IF,
543 FIXED_REG_ID_CAM_I_CORE,
544 FIXED_REG_ID_CAM_VT_DIO,
545};
546
547static struct regulator_consumer_supply hdmi_fixed_consumer =
548 REGULATOR_SUPPLY("hdmi-en", "exynos4-hdmi");
549
550static struct regulator_init_data hdmi_fixed_voltage_init_data = {
551 .constraints = {
552 .name = "HDMI_5V",
553 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
554 },
555 .num_consumer_supplies = 1,
556 .consumer_supplies = &hdmi_fixed_consumer,
557};
558
559static struct fixed_voltage_config hdmi_fixed_voltage_config = {
560 .supply_name = "HDMI_EN1",
561 .microvolts = 5000000,
562 .gpio = EXYNOS4_GPE0(1),
563 .enable_high = true,
564 .init_data = &hdmi_fixed_voltage_init_data,
565};
566
567static struct platform_device hdmi_fixed_voltage = {
568 .name = "reg-fixed-voltage",
569 .id = FIXED_REG_ID_HDMI_5V,
570 .dev = {
571 .platform_data = &hdmi_fixed_voltage_config,
572 },
573};
574
475/* GPIO I2C 5 (PMIC) */ 575/* GPIO I2C 5 (PMIC) */
476static struct i2c_board_info i2c5_devs[] __initdata = { 576static struct i2c_board_info i2c5_devs[] __initdata = {
477 { 577 {
@@ -573,6 +673,11 @@ static void __init universal_touchkey_init(void)
573 gpio_direction_output(gpio, 1); 673 gpio_direction_output(gpio, 1);
574} 674}
575 675
676static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = {
677 .frequency = 300 * 1000,
678 .sda_delay = 200,
679};
680
576/* GPIO KEYS */ 681/* GPIO KEYS */
577static struct gpio_keys_button universal_gpio_keys_tables[] = { 682static struct gpio_keys_button universal_gpio_keys_tables[] = {
578 { 683 {
@@ -658,7 +763,7 @@ static struct fixed_voltage_config mmc0_fixed_voltage_config = {
658 763
659static struct platform_device mmc0_fixed_voltage = { 764static struct platform_device mmc0_fixed_voltage = {
660 .name = "reg-fixed-voltage", 765 .name = "reg-fixed-voltage",
661 .id = 0, 766 .id = FIXED_REG_ID_MMC0,
662 .dev = { 767 .dev = {
663 .platform_data = &mmc0_fixed_voltage_config, 768 .platform_data = &mmc0_fixed_voltage_config,
664 }, 769 },
@@ -692,18 +797,165 @@ static void __init universal_sdhci_init(void)
692 s3c_sdhci3_set_platdata(&universal_hsmmc3_data); 797 s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
693} 798}
694 799
695/* I2C0 */
696static struct i2c_board_info i2c0_devs[] __initdata = {
697 /* Camera, To be updated */
698};
699
700/* I2C1 */ 800/* I2C1 */
701static struct i2c_board_info i2c1_devs[] __initdata = { 801static struct i2c_board_info i2c1_devs[] __initdata = {
702 /* Gyro, To be updated */ 802 /* Gyro, To be updated */
703}; 803};
704 804
805/* Frame Buffer */
806static struct s3c_fb_pd_win universal_fb_win0 = {
807 .win_mode = {
808 .left_margin = 16,
809 .right_margin = 16,
810 .upper_margin = 2,
811 .lower_margin = 28,
812 .hsync_len = 2,
813 .vsync_len = 1,
814 .xres = 480,
815 .yres = 800,
816 .refresh = 55,
817 },
818 .max_bpp = 32,
819 .default_bpp = 16,
820};
821
822static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
823 .win[0] = &universal_fb_win0,
824 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
825 VIDCON0_CLKSEL_LCD,
826 .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
827 | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
828 .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
829};
830
831static struct regulator_consumer_supply cam_i_core_supply =
832 REGULATOR_SUPPLY("core", "0-001f");
833
834static struct regulator_init_data cam_i_core_reg_init_data = {
835 .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
836 .num_consumer_supplies = 1,
837 .consumer_supplies = &cam_i_core_supply,
838};
839
840static struct fixed_voltage_config cam_i_core_fixed_voltage_cfg = {
841 .supply_name = "CAM_I_CORE_1.2V",
842 .microvolts = 1200000,
843 .gpio = EXYNOS4_GPE2(2), /* CAM_8M_CORE_EN */
844 .enable_high = 1,
845 .init_data = &cam_i_core_reg_init_data,
846};
847
848static struct platform_device cam_i_core_fixed_reg_dev = {
849 .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_I_CORE,
850 .dev = { .platform_data = &cam_i_core_fixed_voltage_cfg },
851};
852
853static struct regulator_consumer_supply cam_s_if_supply =
854 REGULATOR_SUPPLY("d_sensor", "0-001f");
855
856static struct regulator_init_data cam_s_if_reg_init_data = {
857 .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
858 .num_consumer_supplies = 1,
859 .consumer_supplies = &cam_s_if_supply,
860};
861
862static struct fixed_voltage_config cam_s_if_fixed_voltage_cfg = {
863 .supply_name = "CAM_S_IF_1.8V",
864 .microvolts = 1800000,
865 .gpio = EXYNOS4_GPE3(0), /* CAM_PWR_EN1 */
866 .enable_high = 1,
867 .init_data = &cam_s_if_reg_init_data,
868};
869
870static struct platform_device cam_s_if_fixed_reg_dev = {
871 .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_S_IF,
872 .dev = { .platform_data = &cam_s_if_fixed_voltage_cfg },
873};
874
875static struct s5p_platform_mipi_csis mipi_csis_platdata = {
876 .clk_rate = 166000000UL,
877 .lanes = 2,
878 .alignment = 32,
879 .hs_settle = 12,
880 .phy_enable = s5p_csis_phy_enable,
881};
882
883#define GPIO_CAM_LEVEL_EN(n) EXYNOS4_GPE4(n + 3)
884#define GPIO_CAM_8M_ISP_INT EXYNOS4_GPX1(5) /* XEINT_13 */
885#define GPIO_CAM_MEGA_nRST EXYNOS4_GPE2(5)
886
887static int m5mols_set_power(struct device *dev, int on)
888{
889 gpio_set_value(GPIO_CAM_LEVEL_EN(1), !on);
890 gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
891 return 0;
892}
893
894static struct m5mols_platform_data m5mols_platdata = {
895 .gpio_reset = GPIO_CAM_MEGA_nRST,
896 .reset_polarity = 0,
897 .set_power = m5mols_set_power,
898};
899
900static struct i2c_board_info m5mols_board_info = {
901 I2C_BOARD_INFO("M5MOLS", 0x1F),
902 .platform_data = &m5mols_platdata,
903};
904
905static struct s5p_fimc_isp_info universal_camera_sensors[] = {
906 {
907 .mux_id = 0,
908 .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
909 V4L2_MBUS_VSYNC_ACTIVE_LOW,
910 .bus_type = FIMC_MIPI_CSI2,
911 .board_info = &m5mols_board_info,
912 .i2c_bus_num = 0,
913 .clk_frequency = 21600000UL,
914 .csi_data_align = 32,
915 },
916};
917
918static struct s5p_platform_fimc fimc_md_platdata = {
919 .isp_info = universal_camera_sensors,
920 .num_clients = ARRAY_SIZE(universal_camera_sensors),
921};
922
923static struct gpio universal_camera_gpios[] = {
924 { GPIO_CAM_LEVEL_EN(1), GPIOF_OUT_INIT_HIGH, "CAM_LVL_EN1" },
925 { GPIO_CAM_LEVEL_EN(2), GPIOF_OUT_INIT_LOW, "CAM_LVL_EN2" },
926 { GPIO_CAM_8M_ISP_INT, GPIOF_IN, "8M_ISP_INT" },
927 { GPIO_CAM_MEGA_nRST, GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
928};
929
930static void universal_camera_init(void)
931{
932 s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
933 &s5p_device_mipi_csis0);
934 s3c_set_platdata(&fimc_md_platdata, sizeof(fimc_md_platdata),
935 &s5p_device_fimc_md);
936
937 if (gpio_request_array(universal_camera_gpios,
938 ARRAY_SIZE(universal_camera_gpios))) {
939 pr_err("%s: GPIO request failed\n", __func__);
940 return;
941 }
942
943 if (!s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xf)))
944 m5mols_board_info.irq = gpio_to_irq(GPIO_CAM_8M_ISP_INT);
945 else
946 pr_err("Failed to configure 8M_ISP_INT GPIO\n");
947
948 /* Free GPIOs controlled directly by the sensor drivers. */
949 gpio_free(GPIO_CAM_MEGA_nRST);
950 gpio_free(GPIO_CAM_8M_ISP_INT);
951
952 if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
953 pr_err("Camera port A setup failed\n");
954}
955
705static struct platform_device *universal_devices[] __initdata = { 956static struct platform_device *universal_devices[] __initdata = {
706 /* Samsung Platform Devices */ 957 /* Samsung Platform Devices */
958 &s5p_device_mipi_csis0,
707 &s5p_device_fimc0, 959 &s5p_device_fimc0,
708 &s5p_device_fimc1, 960 &s5p_device_fimc1,
709 &s5p_device_fimc2, 961 &s5p_device_fimc2,
@@ -712,17 +964,30 @@ static struct platform_device *universal_devices[] __initdata = {
712 &s3c_device_hsmmc0, 964 &s3c_device_hsmmc0,
713 &s3c_device_hsmmc2, 965 &s3c_device_hsmmc2,
714 &s3c_device_hsmmc3, 966 &s3c_device_hsmmc3,
967 &s3c_device_i2c0,
715 &s3c_device_i2c3, 968 &s3c_device_i2c3,
716 &s3c_device_i2c5, 969 &s3c_device_i2c5,
970 &s5p_device_i2c_hdmiphy,
971 &hdmi_fixed_voltage,
972 &exynos4_device_pd[PD_TV],
973 &s5p_device_hdmi,
974 &s5p_device_sdo,
975 &s5p_device_mixer,
717 976
718 /* Universal Devices */ 977 /* Universal Devices */
719 &i2c_gpio12, 978 &i2c_gpio12,
720 &universal_gpio_keys, 979 &universal_gpio_keys,
721 &s5p_device_onenand, 980 &s5p_device_onenand,
981 &s5p_device_fimd0,
722 &s5p_device_mfc, 982 &s5p_device_mfc,
723 &s5p_device_mfc_l, 983 &s5p_device_mfc_l,
724 &s5p_device_mfc_r, 984 &s5p_device_mfc_r,
725 &exynos4_device_pd[PD_MFC], 985 &exynos4_device_pd[PD_MFC],
986 &exynos4_device_pd[PD_LCD0],
987 &exynos4_device_pd[PD_CAM],
988 &cam_i_core_fixed_reg_dev,
989 &cam_s_if_fixed_reg_dev,
990 &s5p_device_fimc_md,
726}; 991};
727 992
728static void __init universal_map_io(void) 993static void __init universal_map_io(void)
@@ -732,6 +997,20 @@ static void __init universal_map_io(void)
732 s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); 997 s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
733} 998}
734 999
1000void s5p_tv_setup(void)
1001{
1002 /* direct HPD to HDMI chip */
1003 gpio_request(EXYNOS4_GPX3(7), "hpd-plug");
1004
1005 gpio_direction_input(EXYNOS4_GPX3(7));
1006 s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
1007 s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
1008
1009 /* setup dependencies between TV devices */
1010 s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
1011 s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
1012}
1013
735static void __init universal_reserve(void) 1014static void __init universal_reserve(void)
736{ 1015{
737 s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); 1016 s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
@@ -740,8 +1019,9 @@ static void __init universal_reserve(void)
740static void __init universal_machine_init(void) 1019static void __init universal_machine_init(void)
741{ 1020{
742 universal_sdhci_init(); 1021 universal_sdhci_init();
1022 s5p_tv_setup();
743 1023
744 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); 1024 s3c_i2c0_set_platdata(&universal_i2c0_platdata);
745 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 1025 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
746 1026
747 universal_tsp_init(); 1027 universal_tsp_init();
@@ -749,15 +1029,28 @@ static void __init universal_machine_init(void)
749 i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs)); 1029 i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
750 1030
751 s3c_i2c5_set_platdata(NULL); 1031 s3c_i2c5_set_platdata(NULL);
1032 s5p_i2c_hdmiphy_set_platdata(NULL);
752 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); 1033 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
753 1034
1035 s5p_fimd0_set_platdata(&universal_lcd_pdata);
1036
754 universal_touchkey_init(); 1037 universal_touchkey_init();
755 i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs, 1038 i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
756 ARRAY_SIZE(i2c_gpio12_devs)); 1039 ARRAY_SIZE(i2c_gpio12_devs));
757 1040
1041 universal_camera_init();
1042
758 /* Last */ 1043 /* Last */
759 platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices)); 1044 platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
1045
760 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev; 1046 s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
1047 s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
1048
1049 s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1050 s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1051 s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1052 s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
1053 s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
761} 1054}
762 1055
763MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") 1056MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos/mct.c
index f191608b28d6..97343df8f132 100644
--- a/arch/arm/mach-exynos4/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -44,7 +44,7 @@ struct mct_clock_event_device {
44 char name[10]; 44 char name[10];
45}; 45};
46 46
47struct mct_clock_event_device mct_tick[NR_CPUS]; 47static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
48 48
49static void exynos4_mct_write(unsigned int value, void *addr) 49static void exynos4_mct_write(unsigned int value, void *addr)
50{ 50{
@@ -302,7 +302,7 @@ static void exynos4_mct_tick_start(unsigned long cycles,
302static int exynos4_tick_set_next_event(unsigned long cycles, 302static int exynos4_tick_set_next_event(unsigned long cycles,
303 struct clock_event_device *evt) 303 struct clock_event_device *evt)
304{ 304{
305 struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()]; 305 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
306 306
307 exynos4_mct_tick_start(cycles, mevt); 307 exynos4_mct_tick_start(cycles, mevt);
308 308
@@ -312,7 +312,7 @@ static int exynos4_tick_set_next_event(unsigned long cycles,
312static inline void exynos4_tick_set_mode(enum clock_event_mode mode, 312static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
313 struct clock_event_device *evt) 313 struct clock_event_device *evt)
314{ 314{
315 struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()]; 315 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
316 316
317 exynos4_mct_tick_stop(mevt); 317 exynos4_mct_tick_stop(mevt);
318 318
@@ -376,14 +376,16 @@ static struct irqaction mct_tick1_event_irq = {
376 376
377static void exynos4_mct_tick_init(struct clock_event_device *evt) 377static void exynos4_mct_tick_init(struct clock_event_device *evt)
378{ 378{
379 struct mct_clock_event_device *mevt;
379 unsigned int cpu = smp_processor_id(); 380 unsigned int cpu = smp_processor_id();
380 381
381 mct_tick[cpu].evt = evt; 382 mevt = this_cpu_ptr(&percpu_mct_tick);
383 mevt->evt = evt;
382 384
383 mct_tick[cpu].base = EXYNOS4_MCT_L_BASE(cpu); 385 mevt->base = EXYNOS4_MCT_L_BASE(cpu);
384 sprintf(mct_tick[cpu].name, "mct_tick%d", cpu); 386 sprintf(mevt->name, "mct_tick%d", cpu);
385 387
386 evt->name = mct_tick[cpu].name; 388 evt->name = mevt->name;
387 evt->cpumask = cpumask_of(cpu); 389 evt->cpumask = cpumask_of(cpu);
388 evt->set_next_event = exynos4_tick_set_next_event; 390 evt->set_next_event = exynos4_tick_set_next_event;
389 evt->set_mode = exynos4_tick_set_mode; 391 evt->set_mode = exynos4_tick_set_mode;
@@ -398,21 +400,21 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
398 400
399 clockevents_register_device(evt); 401 clockevents_register_device(evt);
400 402
401 exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET); 403 exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET);
402 404
403 if (mct_int_type == MCT_INT_SPI) { 405 if (mct_int_type == MCT_INT_SPI) {
404 if (cpu == 0) { 406 if (cpu == 0) {
405 mct_tick0_event_irq.dev_id = &mct_tick[cpu]; 407 mct_tick0_event_irq.dev_id = mevt;
406 evt->irq = IRQ_MCT_L0; 408 evt->irq = IRQ_MCT_L0;
407 setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); 409 setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
408 } else { 410 } else {
409 mct_tick1_event_irq.dev_id = &mct_tick[cpu]; 411 mct_tick1_event_irq.dev_id = mevt;
410 evt->irq = IRQ_MCT_L1; 412 evt->irq = IRQ_MCT_L1;
411 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); 413 setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
412 irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); 414 irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
413 } 415 }
414 } else { 416 } else {
415 gic_enable_ppi(IRQ_MCT_LOCALTIMER); 417 enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0);
416 } 418 }
417} 419}
418 420
@@ -427,9 +429,11 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
427void local_timer_stop(struct clock_event_device *evt) 429void local_timer_stop(struct clock_event_device *evt)
428{ 430{
429 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 431 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
430 disable_irq(evt->irq); 432 if (mct_int_type == MCT_INT_SPI)
433 disable_irq(evt->irq);
434 else
435 disable_percpu_irq(IRQ_MCT_LOCALTIMER);
431} 436}
432
433#endif /* CONFIG_LOCAL_TIMERS */ 437#endif /* CONFIG_LOCAL_TIMERS */
434 438
435static void __init exynos4_timer_resources(void) 439static void __init exynos4_timer_resources(void)
@@ -438,6 +442,16 @@ static void __init exynos4_timer_resources(void)
438 mct_clk = clk_get(NULL, "xtal"); 442 mct_clk = clk_get(NULL, "xtal");
439 443
440 clk_rate = clk_get_rate(mct_clk); 444 clk_rate = clk_get_rate(mct_clk);
445
446 if (mct_int_type == MCT_INT_PPI) {
447 int err;
448
449 err = request_percpu_irq(IRQ_MCT_LOCALTIMER,
450 exynos4_mct_tick_isr, "MCT",
451 &percpu_mct_tick);
452 WARN(err, "MCT: can't request IRQ %d (%d)\n",
453 IRQ_MCT_LOCALTIMER, err);
454 }
441} 455}
442 456
443static void __init exynos4_timer_init(void) 457static void __init exynos4_timer_init(void)
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 05595407e9ff..69ffb2fb3875 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -110,8 +110,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
110 */ 110 */
111 spin_lock(&boot_lock); 111 spin_lock(&boot_lock);
112 spin_unlock(&boot_lock); 112 spin_unlock(&boot_lock);
113
114 set_cpu_online(cpu, true);
115} 113}
116 114
117int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 115int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos/pm.c
index 62e4f4363006..509a435afd4b 100644
--- a/arch/arm/mach-exynos4/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -339,6 +339,13 @@ static int exynos4_pm_suspend(void)
339 tmp &= ~S5P_CENTRAL_LOWPWR_CFG; 339 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
340 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); 340 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
341 341
342 if (soc_is_exynos4212()) {
343 tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
344 tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM |
345 S5P_USE_STANDBYWFE_ISP_ARM);
346 __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
347 }
348
342 /* Save Power control register */ 349 /* Save Power control register */
343 asm ("mrc p15, 0, %0, c15, c0, 0" 350 asm ("mrc p15, 0, %0, c15, c0, 0"
344 : "=r" (tmp) : : "cc"); 351 : "=r" (tmp) : : "cc");
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
new file mode 100644
index 000000000000..bba48f5c3e8f
--- /dev/null
+++ b/arch/arm/mach-exynos/pmu.c
@@ -0,0 +1,230 @@
1/* linux/arch/arm/mach-exynos4/pmu.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * EXYNOS4210 - CPU PMU(Power Management Unit) support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/io.h>
14#include <linux/kernel.h>
15
16#include <mach/regs-clock.h>
17#include <mach/pmu.h>
18
19static struct exynos4_pmu_conf *exynos4_pmu_config;
20
21static struct exynos4_pmu_conf exynos4210_pmu_config[] = {
22 /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
23 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
24 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
25 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
26 { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
27 { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
28 { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
29 { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
30 { S5P_L2_0_LOWPWR, { 0x2, 0x2, 0x3 } },
31 { S5P_L2_1_LOWPWR, { 0x2, 0x2, 0x3 } },
32 { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
33 { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
34 { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
35 { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
36 { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
37 { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
38 { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
39 { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
40 { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
41 { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
42 { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
43 { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
44 { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
45 { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
46 { S5P_CMU_CLKSTOP_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
47 { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
48 { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
49 { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
50 { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
51 { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
52 { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
53 { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
54 { S5P_CMU_RESET_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
55 { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
56 { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
57 { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
58 { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
59 { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
60 { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
61 { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
62 { S5P_MODIMIF_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
63 { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
64 { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
65 { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
66 { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
67 { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
68 { S5P_PCIE_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
69 { S5P_SATA_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
70 { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
71 { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
72 { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
73 { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
74 { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
75 { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
76 { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
77 { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
78 { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
79 { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
80 { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
81 { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
82 { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
83 { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
84 { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
85 { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
86 { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
87 { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
88 { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
89 { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
90 { S5P_LCD1_LOWPWR, { 0x7, 0x0, 0x0 } },
91 { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
92 { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
93 { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
94 { PMU_TABLE_END,},
95};
96
97static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
98 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
99 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
100 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
101 { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
102 { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
103 { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
104 { S5P_ISP_ARM_LOWPWR, { 0x1, 0x0, 0x0 } },
105 { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR, { 0x0, 0x0, 0x0 } },
106 { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR, { 0x0, 0x0, 0x0 } },
107 { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
108 { S5P_L2_0_LOWPWR, { 0x0, 0x0, 0x3 } },
109 /* XXX_OPTION register should be set other field */
110 { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0x0 } },
111 { S5P_L2_1_LOWPWR, { 0x0, 0x0, 0x3 } },
112 { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0x0 } },
113 { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
114 { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
115 { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
116 { S5P_DRAM_FREQ_DOWN_LOWPWR, { 0x1, 0x1, 0x1 } },
117 { S5P_DDRPHY_DLLOFF_LOWPWR, { 0x1, 0x1, 0x1 } },
118 { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR, { 0x1, 0x1, 0x1 } },
119 { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
120 { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
121 { S5P_CMU_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
122 { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
123 { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
124 { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
125 { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
126 { S5P_MPLLUSER_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
127 { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
128 { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
129 { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
130 { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
131 { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
132 { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
133 { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
134 { S5P_CMU_CLKSTOP_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
135 { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x0, 0x0 } },
136 { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
137 { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
138 { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
139 { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
140 { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
141 { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
142 { S5P_CMU_RESET_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
143 { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
144 { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
145 { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
146 { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
147 { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
148 { S5P_TOP_BUS_COREBLK_LOWPWR, { 0x3, 0x0, 0x0 } },
149 { S5P_TOP_RETENTION_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
150 { S5P_TOP_PWR_COREBLK_LOWPWR, { 0x3, 0x0, 0x3 } },
151 { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
152 { S5P_OSCCLK_GATE_LOWPWR, { 0x1, 0x0, 0x1 } },
153 { S5P_LOGIC_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
154 { S5P_OSCCLK_GATE_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
155 { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
156 { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0x0 } },
157 { S5P_HSI_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
158 { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0x0 } },
159 { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
160 { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0x0 } },
161 { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
162 { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0x0 } },
163 { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
164 { S5P_HSMMC_MEM_OPTION, { 0x10, 0x10, 0x0 } },
165 { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
166 { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
167 { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
168 { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
169 { S5P_ROTATOR_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
170 { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0x0 } },
171 { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
172 { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
173 { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
174 { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
175 { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
176 { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
177 { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
178 { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
179 { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } },
180 { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
181 { S5P_PAD_ISOLATION_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
182 { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
183 { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
184 { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
185 { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
186 { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
187 { S5P_GPIO_MODE_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
188 { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
189 { S5P_TOP_ASB_RESET_LOWPWR, { 0x1, 0x1, 0x1 } },
190 { S5P_TOP_ASB_ISOLATION_LOWPWR, { 0x1, 0x0, 0x1 } },
191 { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
192 { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
193 { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
194 { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
195 { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
196 { S5P_ISP_LOWPWR, { 0x7, 0x0, 0x0 } },
197 { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
198 { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
199 { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
200 { S5P_CMU_SYSCLK_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
201 { S5P_CMU_SYSCLK_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
202 { PMU_TABLE_END,},
203};
204
205void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
206{
207 unsigned int i;
208
209 for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++)
210 __raw_writel(exynos4_pmu_config[i].val[mode],
211 exynos4_pmu_config[i].reg);
212}
213
214static int __init exynos4_pmu_init(void)
215{
216 exynos4_pmu_config = exynos4210_pmu_config;
217
218 if (soc_is_exynos4210()) {
219 exynos4_pmu_config = exynos4210_pmu_config;
220 pr_info("EXYNOS4210 PMU Initialize\n");
221 } else if (soc_is_exynos4212()) {
222 exynos4_pmu_config = exynos4212_pmu_config;
223 pr_info("EXYNOS4212 PMU Initialize\n");
224 } else {
225 pr_info("EXYNOS4: PMU not supported\n");
226 }
227
228 return 0;
229}
230arch_initcall(exynos4_pmu_init);
diff --git a/arch/arm/mach-exynos4/setup-fimc.c b/arch/arm/mach-exynos/setup-fimc.c
index 6a45078d9d12..6a45078d9d12 100644
--- a/arch/arm/mach-exynos4/setup-fimc.c
+++ b/arch/arm/mach-exynos/setup-fimc.c
diff --git a/arch/arm/mach-exynos4/setup-fimd0.c b/arch/arm/mach-exynos/setup-fimd0.c
index 07a6dbeecdd0..07a6dbeecdd0 100644
--- a/arch/arm/mach-exynos4/setup-fimd0.c
+++ b/arch/arm/mach-exynos/setup-fimd0.c
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos/setup-i2c0.c
index d395bd17c38b..d395bd17c38b 100644
--- a/arch/arm/mach-exynos4/setup-i2c0.c
+++ b/arch/arm/mach-exynos/setup-i2c0.c
diff --git a/arch/arm/mach-exynos4/setup-i2c1.c b/arch/arm/mach-exynos/setup-i2c1.c
index fd7235a43f6e..fd7235a43f6e 100644
--- a/arch/arm/mach-exynos4/setup-i2c1.c
+++ b/arch/arm/mach-exynos/setup-i2c1.c
diff --git a/arch/arm/mach-exynos4/setup-i2c2.c b/arch/arm/mach-exynos/setup-i2c2.c
index 2694b19e8b37..2694b19e8b37 100644
--- a/arch/arm/mach-exynos4/setup-i2c2.c
+++ b/arch/arm/mach-exynos/setup-i2c2.c
diff --git a/arch/arm/mach-exynos4/setup-i2c3.c b/arch/arm/mach-exynos/setup-i2c3.c
index 379bd306993f..379bd306993f 100644
--- a/arch/arm/mach-exynos4/setup-i2c3.c
+++ b/arch/arm/mach-exynos/setup-i2c3.c
diff --git a/arch/arm/mach-exynos4/setup-i2c4.c b/arch/arm/mach-exynos/setup-i2c4.c
index 9f3c04855b76..9f3c04855b76 100644
--- a/arch/arm/mach-exynos4/setup-i2c4.c
+++ b/arch/arm/mach-exynos/setup-i2c4.c
diff --git a/arch/arm/mach-exynos4/setup-i2c5.c b/arch/arm/mach-exynos/setup-i2c5.c
index 77e1a1e57c76..77e1a1e57c76 100644
--- a/arch/arm/mach-exynos4/setup-i2c5.c
+++ b/arch/arm/mach-exynos/setup-i2c5.c
diff --git a/arch/arm/mach-exynos4/setup-i2c6.c b/arch/arm/mach-exynos/setup-i2c6.c
index 284d12b7af0e..284d12b7af0e 100644
--- a/arch/arm/mach-exynos4/setup-i2c6.c
+++ b/arch/arm/mach-exynos/setup-i2c6.c
diff --git a/arch/arm/mach-exynos4/setup-i2c7.c b/arch/arm/mach-exynos/setup-i2c7.c
index b7611ee359a2..b7611ee359a2 100644
--- a/arch/arm/mach-exynos4/setup-i2c7.c
+++ b/arch/arm/mach-exynos/setup-i2c7.c
diff --git a/arch/arm/mach-exynos4/setup-keypad.c b/arch/arm/mach-exynos/setup-keypad.c
index 7862bfb5933d..7862bfb5933d 100644
--- a/arch/arm/mach-exynos4/setup-keypad.c
+++ b/arch/arm/mach-exynos/setup-keypad.c
diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos/setup-sdhci-gpio.c
index e8d08bf8965a..e8d08bf8965a 100644
--- a/arch/arm/mach-exynos4/setup-sdhci-gpio.c
+++ b/arch/arm/mach-exynos/setup-sdhci-gpio.c
diff --git a/arch/arm/mach-exynos/setup-sdhci.c b/arch/arm/mach-exynos/setup-sdhci.c
new file mode 100644
index 000000000000..92937b410906
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-sdhci.c
@@ -0,0 +1,22 @@
1/* linux/arch/arm/mach-exynos4/setup-sdhci.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/types.h>
14
15/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
16
17char *exynos4_hsmmc_clksrcs[4] = {
18 [0] = NULL,
19 [1] = NULL,
20 [2] = "sclk_mmc", /* mmc_bus */
21 [3] = NULL,
22};
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index 39aca045f660..39aca045f660 100644
--- a/arch/arm/mach-exynos4/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
deleted file mode 100644
index 564bb530f332..000000000000
--- a/arch/arm/mach-exynos4/dma.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/* linux/arch/arm/mach-exynos4/dma.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
7 * Jaswinder Singh <jassi.brar@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/platform_device.h>
25#include <linux/dma-mapping.h>
26
27#include <plat/devs.h>
28#include <plat/irqs.h>
29
30#include <mach/map.h>
31#include <mach/irqs.h>
32
33#include <plat/s3c-pl330-pdata.h>
34
35static u64 dma_dmamask = DMA_BIT_MASK(32);
36
37static struct resource exynos4_pdma0_resource[] = {
38 [0] = {
39 .start = EXYNOS4_PA_PDMA0,
40 .end = EXYNOS4_PA_PDMA0 + SZ_4K,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .start = IRQ_PDMA0,
45 .end = IRQ_PDMA0,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
51 .peri = {
52 [0] = DMACH_PCM0_RX,
53 [1] = DMACH_PCM0_TX,
54 [2] = DMACH_PCM2_RX,
55 [3] = DMACH_PCM2_TX,
56 [4] = DMACH_MSM_REQ0,
57 [5] = DMACH_MSM_REQ2,
58 [6] = DMACH_SPI0_RX,
59 [7] = DMACH_SPI0_TX,
60 [8] = DMACH_SPI2_RX,
61 [9] = DMACH_SPI2_TX,
62 [10] = DMACH_I2S0S_TX,
63 [11] = DMACH_I2S0_RX,
64 [12] = DMACH_I2S0_TX,
65 [13] = DMACH_I2S2_RX,
66 [14] = DMACH_I2S2_TX,
67 [15] = DMACH_UART0_RX,
68 [16] = DMACH_UART0_TX,
69 [17] = DMACH_UART2_RX,
70 [18] = DMACH_UART2_TX,
71 [19] = DMACH_UART4_RX,
72 [20] = DMACH_UART4_TX,
73 [21] = DMACH_SLIMBUS0_RX,
74 [22] = DMACH_SLIMBUS0_TX,
75 [23] = DMACH_SLIMBUS2_RX,
76 [24] = DMACH_SLIMBUS2_TX,
77 [25] = DMACH_SLIMBUS4_RX,
78 [26] = DMACH_SLIMBUS4_TX,
79 [27] = DMACH_AC97_MICIN,
80 [28] = DMACH_AC97_PCMIN,
81 [29] = DMACH_AC97_PCMOUT,
82 [30] = DMACH_MAX,
83 [31] = DMACH_MAX,
84 },
85};
86
87static struct platform_device exynos4_device_pdma0 = {
88 .name = "s3c-pl330",
89 .id = 0,
90 .num_resources = ARRAY_SIZE(exynos4_pdma0_resource),
91 .resource = exynos4_pdma0_resource,
92 .dev = {
93 .dma_mask = &dma_dmamask,
94 .coherent_dma_mask = DMA_BIT_MASK(32),
95 .platform_data = &exynos4_pdma0_pdata,
96 },
97};
98
99static struct resource exynos4_pdma1_resource[] = {
100 [0] = {
101 .start = EXYNOS4_PA_PDMA1,
102 .end = EXYNOS4_PA_PDMA1 + SZ_4K,
103 .flags = IORESOURCE_MEM,
104 },
105 [1] = {
106 .start = IRQ_PDMA1,
107 .end = IRQ_PDMA1,
108 .flags = IORESOURCE_IRQ,
109 },
110};
111
112static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
113 .peri = {
114 [0] = DMACH_PCM0_RX,
115 [1] = DMACH_PCM0_TX,
116 [2] = DMACH_PCM1_RX,
117 [3] = DMACH_PCM1_TX,
118 [4] = DMACH_MSM_REQ1,
119 [5] = DMACH_MSM_REQ3,
120 [6] = DMACH_SPI1_RX,
121 [7] = DMACH_SPI1_TX,
122 [8] = DMACH_I2S0S_TX,
123 [9] = DMACH_I2S0_RX,
124 [10] = DMACH_I2S0_TX,
125 [11] = DMACH_I2S1_RX,
126 [12] = DMACH_I2S1_TX,
127 [13] = DMACH_UART0_RX,
128 [14] = DMACH_UART0_TX,
129 [15] = DMACH_UART1_RX,
130 [16] = DMACH_UART1_TX,
131 [17] = DMACH_UART3_RX,
132 [18] = DMACH_UART3_TX,
133 [19] = DMACH_SLIMBUS1_RX,
134 [20] = DMACH_SLIMBUS1_TX,
135 [21] = DMACH_SLIMBUS3_RX,
136 [22] = DMACH_SLIMBUS3_TX,
137 [23] = DMACH_SLIMBUS5_RX,
138 [24] = DMACH_SLIMBUS5_TX,
139 [25] = DMACH_SLIMBUS0AUX_RX,
140 [26] = DMACH_SLIMBUS0AUX_TX,
141 [27] = DMACH_SPDIF,
142 [28] = DMACH_MAX,
143 [29] = DMACH_MAX,
144 [30] = DMACH_MAX,
145 [31] = DMACH_MAX,
146 },
147};
148
149static struct platform_device exynos4_device_pdma1 = {
150 .name = "s3c-pl330",
151 .id = 1,
152 .num_resources = ARRAY_SIZE(exynos4_pdma1_resource),
153 .resource = exynos4_pdma1_resource,
154 .dev = {
155 .dma_mask = &dma_dmamask,
156 .coherent_dma_mask = DMA_BIT_MASK(32),
157 .platform_data = &exynos4_pdma1_pdata,
158 },
159};
160
161static struct platform_device *exynos4_dmacs[] __initdata = {
162 &exynos4_device_pdma0,
163 &exynos4_device_pdma1,
164};
165
166static int __init exynos4_dma_init(void)
167{
168 platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
169
170 return 0;
171}
172arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos4/include/mach/clkdev.h b/arch/arm/mach-exynos4/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/mach-exynos4/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c
deleted file mode 100644
index b5f6f38557c9..000000000000
--- a/arch/arm/mach-exynos4/mach-origen.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/* linux/arch/arm/mach-exynos4/mach-origen.c
2 *
3 * Copyright (c) 2011 Insignal Co., Ltd.
4 * http://www.insignal.co.kr/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/serial_core.h>
12#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/input.h>
17
18#include <asm/mach/arch.h>
19#include <asm/mach-types.h>
20
21#include <plat/regs-serial.h>
22#include <plat/exynos4.h>
23#include <plat/cpu.h>
24#include <plat/devs.h>
25#include <plat/sdhci.h>
26#include <plat/iic.h>
27
28#include <mach/map.h>
29
30/* Following are default values for UCON, ULCON and UFCON UART registers */
31#define ORIGEN_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
32 S3C2410_UCON_RXILEVEL | \
33 S3C2410_UCON_TXIRQMODE | \
34 S3C2410_UCON_RXIRQMODE | \
35 S3C2410_UCON_RXFIFO_TOI | \
36 S3C2443_UCON_RXERR_IRQEN)
37
38#define ORIGEN_ULCON_DEFAULT S3C2410_LCON_CS8
39
40#define ORIGEN_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
41 S5PV210_UFCON_TXTRIG4 | \
42 S5PV210_UFCON_RXTRIG4)
43
44static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
45 [0] = {
46 .hwport = 0,
47 .flags = 0,
48 .ucon = ORIGEN_UCON_DEFAULT,
49 .ulcon = ORIGEN_ULCON_DEFAULT,
50 .ufcon = ORIGEN_UFCON_DEFAULT,
51 },
52 [1] = {
53 .hwport = 1,
54 .flags = 0,
55 .ucon = ORIGEN_UCON_DEFAULT,
56 .ulcon = ORIGEN_ULCON_DEFAULT,
57 .ufcon = ORIGEN_UFCON_DEFAULT,
58 },
59 [2] = {
60 .hwport = 2,
61 .flags = 0,
62 .ucon = ORIGEN_UCON_DEFAULT,
63 .ulcon = ORIGEN_ULCON_DEFAULT,
64 .ufcon = ORIGEN_UFCON_DEFAULT,
65 },
66 [3] = {
67 .hwport = 3,
68 .flags = 0,
69 .ucon = ORIGEN_UCON_DEFAULT,
70 .ulcon = ORIGEN_ULCON_DEFAULT,
71 .ufcon = ORIGEN_UFCON_DEFAULT,
72 },
73};
74
75static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
76 .cd_type = S3C_SDHCI_CD_GPIO,
77 .ext_cd_gpio = EXYNOS4_GPK2(2),
78 .ext_cd_gpio_invert = 1,
79 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
80};
81
82static struct platform_device *origen_devices[] __initdata = {
83 &s3c_device_hsmmc2,
84 &s3c_device_rtc,
85 &s3c_device_wdt,
86};
87
88static void __init origen_map_io(void)
89{
90 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
91 s3c24xx_init_clocks(24000000);
92 s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
93}
94
95static void __init origen_machine_init(void)
96{
97 s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
98 platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
99}
100
101MACHINE_START(ORIGEN, "ORIGEN")
102 /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
103 .atag_offset = 0x100,
104 .init_irq = exynos4_init_irq,
105 .map_io = origen_map_io,
106 .init_machine = origen_machine_init,
107 .timer = &exynos4_timer,
108MACHINE_END
diff --git a/arch/arm/mach-exynos4/pmu.c b/arch/arm/mach-exynos4/pmu.c
deleted file mode 100644
index 7ea9eb2a20d2..000000000000
--- a/arch/arm/mach-exynos4/pmu.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/* linux/arch/arm/mach-exynos4/pmu.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * EXYNOS4210 - CPU PMU(Power Management Unit) support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/io.h>
14#include <linux/kernel.h>
15
16#include <mach/regs-clock.h>
17#include <mach/pmu.h>
18
19static void __iomem *sys_powerdown_reg[] = {
20 S5P_ARM_CORE0_LOWPWR,
21 S5P_DIS_IRQ_CORE0,
22 S5P_DIS_IRQ_CENTRAL0,
23 S5P_ARM_CORE1_LOWPWR,
24 S5P_DIS_IRQ_CORE1,
25 S5P_DIS_IRQ_CENTRAL1,
26 S5P_ARM_COMMON_LOWPWR,
27 S5P_L2_0_LOWPWR,
28 S5P_L2_1_LOWPWR,
29 S5P_CMU_ACLKSTOP_LOWPWR,
30 S5P_CMU_SCLKSTOP_LOWPWR,
31 S5P_CMU_RESET_LOWPWR,
32 S5P_APLL_SYSCLK_LOWPWR,
33 S5P_MPLL_SYSCLK_LOWPWR,
34 S5P_VPLL_SYSCLK_LOWPWR,
35 S5P_EPLL_SYSCLK_LOWPWR,
36 S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,
37 S5P_CMU_RESET_GPSALIVE_LOWPWR,
38 S5P_CMU_CLKSTOP_CAM_LOWPWR,
39 S5P_CMU_CLKSTOP_TV_LOWPWR,
40 S5P_CMU_CLKSTOP_MFC_LOWPWR,
41 S5P_CMU_CLKSTOP_G3D_LOWPWR,
42 S5P_CMU_CLKSTOP_LCD0_LOWPWR,
43 S5P_CMU_CLKSTOP_LCD1_LOWPWR,
44 S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,
45 S5P_CMU_CLKSTOP_GPS_LOWPWR,
46 S5P_CMU_RESET_CAM_LOWPWR,
47 S5P_CMU_RESET_TV_LOWPWR,
48 S5P_CMU_RESET_MFC_LOWPWR,
49 S5P_CMU_RESET_G3D_LOWPWR,
50 S5P_CMU_RESET_LCD0_LOWPWR,
51 S5P_CMU_RESET_LCD1_LOWPWR,
52 S5P_CMU_RESET_MAUDIO_LOWPWR,
53 S5P_CMU_RESET_GPS_LOWPWR,
54 S5P_TOP_BUS_LOWPWR,
55 S5P_TOP_RETENTION_LOWPWR,
56 S5P_TOP_PWR_LOWPWR,
57 S5P_LOGIC_RESET_LOWPWR,
58 S5P_ONENAND_MEM_LOWPWR,
59 S5P_MODIMIF_MEM_LOWPWR,
60 S5P_G2D_ACP_MEM_LOWPWR,
61 S5P_USBOTG_MEM_LOWPWR,
62 S5P_HSMMC_MEM_LOWPWR,
63 S5P_CSSYS_MEM_LOWPWR,
64 S5P_SECSS_MEM_LOWPWR,
65 S5P_PCIE_MEM_LOWPWR,
66 S5P_SATA_MEM_LOWPWR,
67 S5P_PAD_RETENTION_DRAM_LOWPWR,
68 S5P_PAD_RETENTION_MAUDIO_LOWPWR,
69 S5P_PAD_RETENTION_GPIO_LOWPWR,
70 S5P_PAD_RETENTION_UART_LOWPWR,
71 S5P_PAD_RETENTION_MMCA_LOWPWR,
72 S5P_PAD_RETENTION_MMCB_LOWPWR,
73 S5P_PAD_RETENTION_EBIA_LOWPWR,
74 S5P_PAD_RETENTION_EBIB_LOWPWR,
75 S5P_PAD_RETENTION_ISOLATION_LOWPWR,
76 S5P_PAD_RETENTION_ALV_SEL_LOWPWR,
77 S5P_XUSBXTI_LOWPWR,
78 S5P_XXTI_LOWPWR,
79 S5P_EXT_REGULATOR_LOWPWR,
80 S5P_GPIO_MODE_LOWPWR,
81 S5P_GPIO_MODE_MAUDIO_LOWPWR,
82 S5P_CAM_LOWPWR,
83 S5P_TV_LOWPWR,
84 S5P_MFC_LOWPWR,
85 S5P_G3D_LOWPWR,
86 S5P_LCD0_LOWPWR,
87 S5P_LCD1_LOWPWR,
88 S5P_MAUDIO_LOWPWR,
89 S5P_GPS_LOWPWR,
90 S5P_GPS_ALIVE_LOWPWR,
91};
92
93static const unsigned int sys_powerdown_val[][NUM_SYS_POWERDOWN] = {
94 /* { AFTR, LPA, SLEEP }*/
95 { 0, 0, 2 }, /* ARM_CORE0 */
96 { 0, 0, 0 }, /* ARM_DIS_IRQ_CORE0 */
97 { 0, 0, 0 }, /* ARM_DIS_IRQ_CENTRAL0 */
98 { 0, 0, 2 }, /* ARM_CORE1 */
99 { 0, 0, 0 }, /* ARM_DIS_IRQ_CORE1 */
100 { 0, 0, 0 }, /* ARM_DIS_IRQ_CENTRAL1 */
101 { 0, 0, 2 }, /* ARM_COMMON */
102 { 2, 2, 3 }, /* ARM_CPU_L2_0 */
103 { 2, 2, 3 }, /* ARM_CPU_L2_1 */
104 { 1, 0, 0 }, /* CMU_ACLKSTOP */
105 { 1, 0, 0 }, /* CMU_SCLKSTOP */
106 { 1, 1, 0 }, /* CMU_RESET */
107 { 1, 0, 0 }, /* APLL_SYSCLK */
108 { 1, 0, 0 }, /* MPLL_SYSCLK */
109 { 1, 0, 0 }, /* VPLL_SYSCLK */
110 { 1, 1, 0 }, /* EPLL_SYSCLK */
111 { 1, 1, 0 }, /* CMU_CLKSTOP_GPS_ALIVE */
112 { 1, 1, 0 }, /* CMU_RESET_GPS_ALIVE */
113 { 1, 1, 0 }, /* CMU_CLKSTOP_CAM */
114 { 1, 1, 0 }, /* CMU_CLKSTOP_TV */
115 { 1, 1, 0 }, /* CMU_CLKSTOP_MFC */
116 { 1, 1, 0 }, /* CMU_CLKSTOP_G3D */
117 { 1, 1, 0 }, /* CMU_CLKSTOP_LCD0 */
118 { 1, 1, 0 }, /* CMU_CLKSTOP_LCD1 */
119 { 1, 1, 0 }, /* CMU_CLKSTOP_MAUDIO */
120 { 1, 1, 0 }, /* CMU_CLKSTOP_GPS */
121 { 1, 1, 0 }, /* CMU_RESET_CAM */
122 { 1, 1, 0 }, /* CMU_RESET_TV */
123 { 1, 1, 0 }, /* CMU_RESET_MFC */
124 { 1, 1, 0 }, /* CMU_RESET_G3D */
125 { 1, 1, 0 }, /* CMU_RESET_LCD0 */
126 { 1, 1, 0 }, /* CMU_RESET_LCD1 */
127 { 1, 1, 0 }, /* CMU_RESET_MAUDIO */
128 { 1, 1, 0 }, /* CMU_RESET_GPS */
129 { 3, 0, 0 }, /* TOP_BUS */
130 { 1, 0, 1 }, /* TOP_RETENTION */
131 { 3, 0, 3 }, /* TOP_PWR */
132 { 1, 1, 0 }, /* LOGIC_RESET */
133 { 3, 0, 0 }, /* ONENAND_MEM */
134 { 3, 0, 0 }, /* MODIMIF_MEM */
135 { 3, 0, 0 }, /* G2D_ACP_MEM */
136 { 3, 0, 0 }, /* USBOTG_MEM */
137 { 3, 0, 0 }, /* HSMMC_MEM */
138 { 3, 0, 0 }, /* CSSYS_MEM */
139 { 3, 0, 0 }, /* SECSS_MEM */
140 { 3, 0, 0 }, /* PCIE_MEM */
141 { 3, 0, 0 }, /* SATA_MEM */
142 { 1, 0, 0 }, /* PAD_RETENTION_DRAM */
143 { 1, 1, 0 }, /* PAD_RETENTION_MAUDIO */
144 { 1, 0, 0 }, /* PAD_RETENTION_GPIO */
145 { 1, 0, 0 }, /* PAD_RETENTION_UART */
146 { 1, 0, 0 }, /* PAD_RETENTION_MMCA */
147 { 1, 0, 0 }, /* PAD_RETENTION_MMCB */
148 { 1, 0, 0 }, /* PAD_RETENTION_EBIA */
149 { 1, 0, 0 }, /* PAD_RETENTION_EBIB */
150 { 1, 0, 0 }, /* PAD_RETENTION_ISOLATION */
151 { 1, 0, 0 }, /* PAD_RETENTION_ALV_SEL */
152 { 1, 1, 0 }, /* XUSBXTI */
153 { 1, 1, 0 }, /* XXTI */
154 { 1, 1, 0 }, /* EXT_REGULATOR */
155 { 1, 0, 0 }, /* GPIO_MODE */
156 { 1, 1, 0 }, /* GPIO_MODE_MAUDIO */
157 { 7, 0, 0 }, /* CAM */
158 { 7, 0, 0 }, /* TV */
159 { 7, 0, 0 }, /* MFC */
160 { 7, 0, 0 }, /* G3D */
161 { 7, 0, 0 }, /* LCD0 */
162 { 7, 0, 0 }, /* LCD1 */
163 { 7, 7, 0 }, /* MAUDIO */
164 { 7, 0, 0 }, /* GPS */
165 { 7, 0, 0 }, /* GPS_ALIVE */
166};
167
168void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
169{
170 unsigned int count = ARRAY_SIZE(sys_powerdown_reg);
171
172 for (; count > 0; count--)
173 __raw_writel(sys_powerdown_val[count - 1][mode],
174 sys_powerdown_reg[count - 1]);
175}
diff --git a/arch/arm/mach-exynos4/setup-sdhci.c b/arch/arm/mach-exynos4/setup-sdhci.c
deleted file mode 100644
index 1e83f8cf236d..000000000000
--- a/arch/arm/mach-exynos4/setup-sdhci.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/* linux/arch/arm/mach-exynos4/setup-sdhci.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
21
22#include <plat/regs-sdhci.h>
23
24/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
25
26char *exynos4_hsmmc_clksrcs[4] = {
27 [0] = NULL,
28 [1] = NULL,
29 [2] = "sclk_mmc", /* mmc_bus */
30 [3] = NULL,
31};
32
33void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
34 struct mmc_ios *ios, struct mmc_card *card)
35{
36 u32 ctrl2, ctrl3;
37
38 /* don't need to alter anything according to card-type */
39
40 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
41
42 /* select base clock source to HCLK */
43
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45
46 /*
47 * clear async mode, enable conflict mask, rx feedback ctrl, SD
48 * clk hold and no use debounce count
49 */
50
51 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
52 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
53 S3C_SDHCI_CTRL2_ENFBCLKRX |
54 S3C_SDHCI_CTRL2_DFCNT_NONE |
55 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
56
57 /* Tx and Rx feedback clock delay control */
58
59 if (ios->clock < 25 * 1000000)
60 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
61 S3C_SDHCI_CTRL3_FCSEL2 |
62 S3C_SDHCI_CTRL3_FCSEL1 |
63 S3C_SDHCI_CTRL3_FCSEL0);
64 else
65 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
66
67 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
68 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
69}
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 8f948f981646..ba254a71691a 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -7,7 +7,7 @@ obj-y += common.o clock.o devices.o time.o
7# SoC support 7# SoC support
8obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o 8obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o
9obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o 9obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o
10obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o 10obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o sram.o
11 11
12# board support 12# board support
13obj-$(CONFIG_MACH_ASPENITE) += aspenite.o 13obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index e411252e3d39..983cfb15fbde 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -185,6 +185,15 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
185 | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, 185 | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
186}; 186};
187 187
188static struct sram_platdata mmp2_asram_platdata = {
189 .pool_name = "asram",
190 .granularity = SRAM_GRANULARITY,
191};
192
193static struct sram_platdata mmp2_isram_platdata = {
194 .pool_name = "isram",
195 .granularity = SRAM_GRANULARITY,
196};
188 197
189static void __init brownstone_init(void) 198static void __init brownstone_init(void)
190{ 199{
@@ -196,6 +205,8 @@ static void __init brownstone_init(void)
196 mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); 205 mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
197 mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ 206 mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
198 mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */ 207 mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
208 mmp2_add_asram(&mmp2_asram_platdata);
209 mmp2_add_isram(&mmp2_isram_platdata);
199 210
200 /* enable 5v regulator */ 211 /* enable 5v regulator */
201 platform_device_register(&brownstone_v_5vp_device); 212 platform_device_register(&brownstone_v_5vp_device);
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
index de7b88826ad7..2f7b2d3c2b18 100644
--- a/arch/arm/mach-mmp/include/mach/mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -13,6 +13,7 @@ extern void mmp2_clear_pmic_int(void);
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/i2c/pxa-i2c.h> 14#include <linux/i2c/pxa-i2c.h>
15#include <mach/devices.h> 15#include <mach/devices.h>
16#include <mach/sram.h>
16 17
17extern struct pxa_device_desc mmp2_device_uart1; 18extern struct pxa_device_desc mmp2_device_uart1;
18extern struct pxa_device_desc mmp2_device_uart2; 19extern struct pxa_device_desc mmp2_device_uart2;
@@ -28,6 +29,8 @@ extern struct pxa_device_desc mmp2_device_sdh0;
28extern struct pxa_device_desc mmp2_device_sdh1; 29extern struct pxa_device_desc mmp2_device_sdh1;
29extern struct pxa_device_desc mmp2_device_sdh2; 30extern struct pxa_device_desc mmp2_device_sdh2;
30extern struct pxa_device_desc mmp2_device_sdh3; 31extern struct pxa_device_desc mmp2_device_sdh3;
32extern struct pxa_device_desc mmp2_device_asram;
33extern struct pxa_device_desc mmp2_device_isram;
31 34
32static inline int mmp2_add_uart(int id) 35static inline int mmp2_add_uart(int id)
33{ 36{
@@ -85,5 +88,15 @@ static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
85 return pxa_register_device(d, data, sizeof(*data)); 88 return pxa_register_device(d, data, sizeof(*data));
86} 89}
87 90
91static inline int mmp2_add_asram(struct sram_platdata *data)
92{
93 return pxa_register_device(&mmp2_device_asram, data, sizeof(*data));
94}
95
96static inline int mmp2_add_isram(struct sram_platdata *data)
97{
98 return pxa_register_device(&mmp2_device_isram, data, sizeof(*data));
99}
100
88#endif /* __ASM_MACH_MMP2_H */ 101#endif /* __ASM_MACH_MMP2_H */
89 102
diff --git a/arch/arm/mach-mmp/include/mach/sram.h b/arch/arm/mach-mmp/include/mach/sram.h
new file mode 100644
index 000000000000..239e0fc1bb1f
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/sram.h
@@ -0,0 +1,35 @@
1/*
2 * linux/arch/arm/mach-mmp/include/mach/sram.h
3 *
4 * SRAM Memory Management
5 *
6 * Copyright (c) 2011 Marvell Semiconductors Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#ifndef __ASM_ARCH_SRAM_H
15#define __ASM_ARCH_SRAM_H
16
17#include <linux/genalloc.h>
18
19/* ARBITRARY: SRAM allocations are multiples of this 2^N size */
20#define SRAM_GRANULARITY 512
21
22enum sram_type {
23 MMP_SRAM_UNDEFINED = 0,
24 MMP_ASRAM,
25 MMP_ISRAM,
26};
27
28struct sram_platdata {
29 char *pool_name;
30 int granularity;
31};
32
33extern struct gen_pool *sram_get_gpool(char *pool_name);
34
35#endif /* __ASM_ARCH_SRAM_H */
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index 7a7e8e4dde41..5dd1d4a6aeb9 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -226,4 +226,7 @@ MMP2_DEVICE(sdh0, "sdhci-pxav3", 0, MMC, 0xd4280000, 0x120);
226MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120); 226MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120);
227MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120); 227MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120);
228MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120); 228MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120);
229MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000);
230/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */
231MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000);
229 232
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c
new file mode 100644
index 000000000000..4304f9519372
--- /dev/null
+++ b/arch/arm/mach-mmp/sram.c
@@ -0,0 +1,168 @@
1/*
2 * linux/arch/arm/mach-mmp/sram.c
3 *
4 * based on mach-davinci/sram.c - DaVinci simple SRAM allocator
5 *
6 * Copyright (c) 2011 Marvell Semiconductors Inc.
7 * All Rights Reserved
8 *
9 * Add for mmp sram support - Leo Yan <leoy@marvell.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/io.h>
21#include <linux/err.h>
22#include <linux/slab.h>
23#include <linux/genalloc.h>
24
25#include <mach/sram.h>
26
27struct sram_bank_info {
28 char *pool_name;
29 struct gen_pool *gpool;
30 int granularity;
31
32 phys_addr_t sram_phys;
33 void __iomem *sram_virt;
34 u32 sram_size;
35
36 struct list_head node;
37};
38
39static DEFINE_MUTEX(sram_lock);
40static LIST_HEAD(sram_bank_list);
41
42struct gen_pool *sram_get_gpool(char *pool_name)
43{
44 struct sram_bank_info *info = NULL;
45
46 if (!pool_name)
47 return NULL;
48
49 mutex_lock(&sram_lock);
50
51 list_for_each_entry(info, &sram_bank_list, node)
52 if (!strcmp(pool_name, info->pool_name))
53 break;
54
55 mutex_unlock(&sram_lock);
56
57 if (&info->node == &sram_bank_list)
58 return NULL;
59
60 return info->gpool;
61}
62EXPORT_SYMBOL(sram_get_gpool);
63
64static int __devinit sram_probe(struct platform_device *pdev)
65{
66 struct sram_platdata *pdata = pdev->dev.platform_data;
67 struct sram_bank_info *info;
68 struct resource *res;
69 int ret = 0;
70
71 if (!pdata && !pdata->pool_name)
72 return -ENODEV;
73
74 info = kzalloc(sizeof(*info), GFP_KERNEL);
75 if (!info)
76 return -ENOMEM;
77
78 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
79 if (res == NULL) {
80 dev_err(&pdev->dev, "no memory resource defined\n");
81 ret = -ENODEV;
82 goto out;
83 }
84
85 if (!resource_size(res))
86 return 0;
87
88 info->sram_phys = (phys_addr_t)res->start;
89 info->sram_size = resource_size(res);
90 info->sram_virt = ioremap(info->sram_phys, info->sram_size);
91 info->pool_name = kstrdup(pdata->pool_name, GFP_KERNEL);
92 info->granularity = pdata->granularity;
93
94 info->gpool = gen_pool_create(ilog2(info->granularity), -1);
95 if (!info->gpool) {
96 dev_err(&pdev->dev, "create pool failed\n");
97 ret = -ENOMEM;
98 goto create_pool_err;
99 }
100
101 ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
102 info->sram_phys, info->sram_size, -1);
103 if (ret < 0) {
104 dev_err(&pdev->dev, "add new chunk failed\n");
105 ret = -ENOMEM;
106 goto add_chunk_err;
107 }
108
109 mutex_lock(&sram_lock);
110 list_add(&info->node, &sram_bank_list);
111 mutex_unlock(&sram_lock);
112
113 platform_set_drvdata(pdev, info);
114
115 dev_info(&pdev->dev, "initialized\n");
116 return 0;
117
118add_chunk_err:
119 gen_pool_destroy(info->gpool);
120create_pool_err:
121 iounmap(info->sram_virt);
122 kfree(info->pool_name);
123out:
124 kfree(info);
125 return ret;
126}
127
128static int __devexit sram_remove(struct platform_device *pdev)
129{
130 struct sram_bank_info *info;
131
132 info = platform_get_drvdata(pdev);
133 if (info == NULL)
134 return -ENODEV;
135
136 mutex_lock(&sram_lock);
137 list_del(&info->node);
138 mutex_unlock(&sram_lock);
139
140 gen_pool_destroy(info->gpool);
141 iounmap(info->sram_virt);
142 kfree(info->pool_name);
143 kfree(info);
144 return 0;
145}
146
147static const struct platform_device_id sram_id_table[] = {
148 { "asram", MMP_ASRAM },
149 { "isram", MMP_ISRAM },
150 { }
151};
152
153static struct platform_driver sram_driver = {
154 .probe = sram_probe,
155 .remove = sram_remove,
156 .driver = {
157 .name = "mmp-sram",
158 },
159 .id_table = sram_id_table,
160};
161
162static int __init sram_init(void)
163{
164 return platform_driver_register(&sram_driver);
165}
166core_initcall(sram_init);
167
168MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 8e697dd8accd..d82b7aa3c096 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -144,7 +144,7 @@ static struct clk_lookup eseries_clkregs[] = {
144 INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"), 144 INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"),
145}; 145};
146 146
147void eseries_register_clks(void) 147static void __init eseries_register_clks(void)
148{ 148{
149 clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs)); 149 clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
150} 150}
diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h
index be921965e91a..b96949dd5adb 100644
--- a/arch/arm/mach-pxa/eseries.h
+++ b/arch/arm/mach-pxa/eseries.h
@@ -11,5 +11,4 @@ extern int eseries_tmio_resume(struct platform_device *dev);
11extern void eseries_get_tmio_gpios(void); 11extern void eseries_get_tmio_gpios(void);
12extern struct resource eseries_tmio_resources[]; 12extern struct resource eseries_tmio_resources[];
13extern struct platform_device e300_tc6387xb_device; 13extern struct platform_device e300_tc6387xb_device;
14extern void eseries_register_clks(void);
15 14
diff --git a/arch/arm/mach-pxa/include/mach/gpio-pxa.h b/arch/arm/mach-pxa/include/mach/gpio-pxa.h
index 576868f8b8c5..41b4c93a96c2 100644
--- a/arch/arm/mach-pxa/include/mach/gpio-pxa.h
+++ b/arch/arm/mach-pxa/include/mach/gpio-pxa.h
@@ -25,7 +25,7 @@
25#define GPIO_REGS_VIRT io_p2v(0x40E00000) 25#define GPIO_REGS_VIRT io_p2v(0x40E00000)
26 26
27#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) 27#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
28#define GPIO_REG(x) (GPIO_REGS_VIRT + (x)) 28#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
29 29
30/* GPIO Pin Level Registers */ 30/* GPIO Pin Level Registers */
31#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00) 31#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00)
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 9a9c539f6c01..6d38c6548b3d 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -394,9 +394,9 @@ static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
394 } 394 }
395 395
396 if (flags & SOCAM_DATAWIDTH_8) 396 if (flags & SOCAM_DATAWIDTH_8)
397 gpio_set_value(gpio_bus_switch, 1); 397 gpio_set_value_cansleep(gpio_bus_switch, 1);
398 else 398 else
399 gpio_set_value(gpio_bus_switch, 0); 399 gpio_set_value_cansleep(gpio_bus_switch, 0);
400 400
401 return 0; 401 return 0;
402} 402}
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 3700cf32af0f..5261a7ed0999 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -6,7 +6,6 @@ config CPU_S3C2410
6 bool 6 bool
7 depends on ARCH_S3C2410 7 depends on ARCH_S3C2410
8 select CPU_ARM920T 8 select CPU_ARM920T
9 select S3C_GPIO_PULL_UP
10 select S3C2410_CLOCK 9 select S3C2410_CLOCK
11 select CPU_LLSERIAL_S3C2410 10 select CPU_LLSERIAL_S3C2410
12 select S3C2410_PM if PM 11 select S3C2410_PM if PM
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index b2b2a5bb275e..ae8e482b6427 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -13,7 +13,6 @@
13#ifndef __ASM_ARCH_DMA_H 13#ifndef __ASM_ARCH_DMA_H
14#define __ASM_ARCH_DMA_H __FILE__ 14#define __ASM_ARCH_DMA_H __FILE__
15 15
16#include <plat/dma.h>
17#include <linux/sysdev.h> 16#include <linux/sysdev.h>
18 17
19#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ 18#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
@@ -51,6 +50,18 @@ enum dma_ch {
51 DMACH_MAX, /* the end entry */ 50 DMACH_MAX, /* the end entry */
52}; 51};
53 52
53static inline bool samsung_dma_has_circular(void)
54{
55 return false;
56}
57
58static inline bool samsung_dma_is_dmadev(void)
59{
60 return false;
61}
62
63#include <plat/dma.h>
64
54#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ 65#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
55 66
56/* we have 4 dma channels */ 67/* we have 4 dma channels */
@@ -163,7 +174,7 @@ struct s3c2410_dma_chan {
163 struct s3c2410_dma_client *client; 174 struct s3c2410_dma_client *client;
164 175
165 /* channel configuration */ 176 /* channel configuration */
166 enum s3c2410_dmasrc source; 177 enum dma_data_direction source;
167 enum dma_ch req_ch; 178 enum dma_ch req_ch;
168 unsigned long dev_addr; 179 unsigned long dev_addr;
169 unsigned long load_timeout; 180 unsigned long load_timeout;
@@ -196,9 +207,4 @@ struct s3c2410_dma_chan {
196 207
197typedef unsigned long dma_device_t; 208typedef unsigned long dma_device_t;
198 209
199static inline bool s3c_dma_has_circular(void)
200{
201 return false;
202}
203
204#endif /* __ASM_ARCH_DMA_H */ 210#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/fb.h b/arch/arm/mach-s3c2410/include/mach/fb.h
index eee0654eb8fb..a957bc8ed44f 100644
--- a/arch/arm/mach-s3c2410/include/mach/fb.h
+++ b/arch/arm/mach-s3c2410/include/mach/fb.h
@@ -1,74 +1 @@
1/* arch/arm/mach-s3c2410/include/mach/fb.h #include <plat/fb-s3c2410.h>
2 *
3 * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
4 *
5 * Inspired by pxafb.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifndef __ASM_ARM_FB_H
13#define __ASM_ARM_FB_H
14
15#include <mach/regs-lcd.h>
16
17struct s3c2410fb_hw {
18 unsigned long lcdcon1;
19 unsigned long lcdcon2;
20 unsigned long lcdcon3;
21 unsigned long lcdcon4;
22 unsigned long lcdcon5;
23};
24
25/* LCD description */
26struct s3c2410fb_display {
27 /* LCD type */
28 unsigned type;
29
30 /* Screen size */
31 unsigned short width;
32 unsigned short height;
33
34 /* Screen info */
35 unsigned short xres;
36 unsigned short yres;
37 unsigned short bpp;
38
39 unsigned pixclock; /* pixclock in picoseconds */
40 unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
41 unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
42 unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
43 unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
44 unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
45 unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
46
47 /* lcd configuration registers */
48 unsigned long lcdcon5;
49};
50
51struct s3c2410fb_mach_info {
52
53 struct s3c2410fb_display *displays; /* attached diplays info */
54 unsigned num_displays; /* number of defined displays */
55 unsigned default_display;
56
57 /* GPIOs */
58
59 unsigned long gpcup;
60 unsigned long gpcup_mask;
61 unsigned long gpccon;
62 unsigned long gpccon_mask;
63 unsigned long gpdup;
64 unsigned long gpdup_mask;
65 unsigned long gpdcon;
66 unsigned long gpdcon_mask;
67
68 /* lpc3600 control register */
69 unsigned long lpcsel;
70};
71
72extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
73
74#endif /* __ASM_ARM_FB_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
index bab139201761..c53ad34c6579 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -1,98 +1 @@
1/* arch/arm/mach-s3c2410/include/mach/gpio-fns.h #include <plat/gpio-fns.h>
2 *
3 * Copyright (c) 2003-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 - hardware
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __MACH_GPIO_FNS_H
14#define __MACH_GPIO_FNS_H __FILE__
15
16/* These functions are in the to-be-removed category and it is strongly
17 * encouraged not to use these in new code. They will be marked deprecated
18 * very soon.
19 *
20 * Most of the functionality can be either replaced by the gpiocfg calls
21 * for the s3c platform or by the generic GPIOlib API.
22 *
23 * As of 2.6.35-rc, these will be removed, with the few drivers using them
24 * either replaced or given a wrapper until the calls can be removed.
25*/
26
27#include <plat/gpio-cfg.h>
28
29static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
30{
31 /* 1:1 mapping between cfgpin and setcfg calls at the moment */
32 s3c_gpio_cfgpin(pin, cfg);
33}
34
35/* external functions for GPIO support
36 *
37 * These allow various different clients to access the same GPIO
38 * registers without conflicting. If your driver only owns the entire
39 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
40*/
41
42extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
43
44/* s3c2410_gpio_getirq
45 *
46 * turn the given pin number into the corresponding IRQ number
47 *
48 * returns:
49 * < 0 = no interrupt for this pin
50 * >=0 = interrupt number for the pin
51*/
52
53extern int s3c2410_gpio_getirq(unsigned int pin);
54
55/* s3c2410_gpio_irqfilter
56 *
57 * set the irq filtering on the given pin
58 *
59 * on = 0 => disable filtering
60 * 1 => enable filtering
61 *
62 * config = S3C2410_EINTFLT_PCLK or S3C2410_EINTFLT_EXTCLK orred with
63 * width of filter (0 through 63)
64 *
65 *
66*/
67
68extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
69 unsigned int config);
70
71/* s3c2410_gpio_pullup
72 *
73 * This call should be replaced with s3c_gpio_setpull().
74 *
75 * As a note, there is currently no distinction between pull-up and pull-down
76 * in the s3c24xx series devices with only an on/off configuration.
77 */
78
79/* s3c2410_gpio_pullup
80 *
81 * configure the pull-up control on the given pin
82 *
83 * to = 1 => disable the pull-up
84 * 0 => enable the pull-up
85 *
86 * eg;
87 *
88 * s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
89 * s3c2410_gpio_pullup(S3C2410_GPE(8), 0);
90*/
91
92extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
93
94extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
95
96extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
97
98#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
index 4f7bf3272e87..019ea86057f6 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -53,7 +53,7 @@
53#define S3C2410_GPIO_M_NR (32) /* technically 2. */ 53#define S3C2410_GPIO_M_NR (32) /* technically 2. */
54 54
55#if CONFIG_S3C_GPIO_SPACE != 0 55#if CONFIG_S3C_GPIO_SPACE != 0
56#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment 56#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment
57#endif 57#endif
58 58
59#define S3C2410_GPIO_NEXT(__gpio) \ 59#define S3C2410_GPIO_NEXT(__gpio) \
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
index d67819dde42a..c410a078622c 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
@@ -17,11 +17,11 @@
17 17
18#include <mach/regs-gpio.h> 18#include <mach/regs-gpio.h>
19 19
20extern struct s3c_gpio_chip s3c24xx_gpios[]; 20extern struct samsung_gpio_chip s3c24xx_gpios[];
21 21
22static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin) 22static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
23{ 23{
24 struct s3c_gpio_chip *chip; 24 struct samsung_gpio_chip *chip;
25 25
26 if (pin > S3C_GPIO_END) 26 if (pin > S3C_GPIO_END)
27 return NULL; 27 return NULL;
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index e5a68ea13113..e53b2177319e 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -191,9 +191,9 @@
191#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2 191#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2
192 192
193#ifdef CONFIG_CPU_S3C2440 193#ifdef CONFIG_CPU_S3C2440
194#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 194#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97
195#else 195#else
196#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97 196#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97
197#endif 197#endif
198 198
199/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ 199/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index 4cf495f813a7..78ae807f1281 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -149,6 +149,7 @@
149#define S3C24XX_PA_RTC S3C2410_PA_RTC 149#define S3C24XX_PA_RTC S3C2410_PA_RTC
150#define S3C24XX_PA_ADC S3C2410_PA_ADC 150#define S3C24XX_PA_ADC S3C2410_PA_ADC
151#define S3C24XX_PA_SPI S3C2410_PA_SPI 151#define S3C24XX_PA_SPI S3C2410_PA_SPI
152#define S3C24XX_PA_SPI1 (S3C2410_PA_SPI + S3C2410_SPI1)
152#define S3C24XX_PA_SDI S3C2410_PA_SDI 153#define S3C24XX_PA_SDI S3C2410_PA_SDI
153#define S3C24XX_PA_NAND S3C2410_PA_NAND 154#define S3C24XX_PA_NAND S3C2410_PA_NAND
154 155
diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h
index 45eea5210c87..2eef7e6f7675 100644
--- a/arch/arm/mach-s3c2410/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c2410/include/mach/pm-core.h
@@ -64,4 +64,4 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
64} 64}
65 65
66static inline void s3c_pm_restored_gpios(void) { } 66static inline void s3c_pm_restored_gpios(void) { }
67static inline void s3c_pm_saved_gpios(void) { } 67static inline void samsung_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index 5e06c7265835..c3feff3c0488 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -65,6 +65,7 @@
65#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4) 65#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4)
66#define S3C2443_CLKDIV0_PREDIV_SHIFT (4) 66#define S3C2443_CLKDIV0_PREDIV_SHIFT (4)
67 67
68#define S3C2416_CLKDIV0_ARMDIV_MASK (7 << 9)
68#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9) 69#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9)
69#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9) 70#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9)
70#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9) 71#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9)
@@ -102,6 +103,7 @@
102#define S3C2443_PCLKCON_UART3 (1<<3) 103#define S3C2443_PCLKCON_UART3 (1<<3)
103#define S3C2443_PCLKCON_IIC (1<<4) 104#define S3C2443_PCLKCON_IIC (1<<4)
104#define S3C2443_PCLKCON_SDI (1<<5) 105#define S3C2443_PCLKCON_SDI (1<<5)
106#define S3C2443_PCLKCON_HSSPI (1<<6)
105#define S3C2443_PCLKCON_ADC (1<<7) 107#define S3C2443_PCLKCON_ADC (1<<7)
106#define S3C2443_PCLKCON_AC97 (1<<8) 108#define S3C2443_PCLKCON_AC97 (1<<8)
107#define S3C2443_PCLKCON_IIS (1<<9) 109#define S3C2443_PCLKCON_IIS (1<<9)
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 556c535829f0..caa4ae29ec79 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -696,9 +696,9 @@ static void __init h1940_init(void)
696 S3C2410_MISCCR_USBSUSPND0 | 696 S3C2410_MISCCR_USBSUSPND0 |
697 S3C2410_MISCCR_USBSUSPND1, 0x0); 697 S3C2410_MISCCR_USBSUSPND1, 0x0);
698 698
699 tmp = (0x78 << S3C24XX_PLLCON_MDIVSHIFT) 699 tmp = (0x78 << S3C24XX_PLL_MDIV_SHIFT)
700 | (0x02 << S3C24XX_PLLCON_PDIVSHIFT) 700 | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
701 | (0x03 << S3C24XX_PLLCON_SDIVSHIFT); 701 | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
702 writel(tmp, S3C2410_UPLLCON); 702 writel(tmp, S3C2410_UPLLCON);
703 703
704 gpio_request(S3C2410_GPC(0), "LCD power"); 704 gpio_request(S3C2410_GPC(0), "LCD power");
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 367d376deb96..451852156254 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -49,6 +49,7 @@
49 49
50#include <mach/regs-gpio.h> 50#include <mach/regs-gpio.h>
51#include <mach/leds-gpio.h> 51#include <mach/leds-gpio.h>
52#include <mach/regs-lcd.h>
52#include <plat/regs-serial.h> 53#include <plat/regs-serial.h>
53#include <mach/fb.h> 54#include <mach/fb.h>
54#include <plat/nand.h> 55#include <plat/nand.h>
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 343a540d86a9..3d7ebc557a72 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -72,8 +72,8 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
72 72
73void __init s3c2410_map_io(void) 73void __init s3c2410_map_io(void)
74{ 74{
75 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; 75 s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
76 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; 76 s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
77 77
78 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); 78 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
79} 79}
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index c61e3261615d..d2a7d5ef3e67 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -130,11 +130,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
130 130
131static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan, 131static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
132 struct s3c24xx_dma_map *map, 132 struct s3c24xx_dma_map *map,
133 enum s3c2410_dmasrc dir) 133 enum dma_data_direction dir)
134{ 134{
135 unsigned long chsel; 135 unsigned long chsel;
136 136
137 if (dir == S3C2410_DMASRC_HW) 137 if (dir == DMA_FROM_DEVICE)
138 chsel = map->channels_rx[0]; 138 chsel = map->channels_rx[0];
139 else 139 else
140 chsel = map->channels[0]; 140 chsel = map->channels[0];
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
new file mode 100644
index 000000000000..4526f6ba31a8
--- /dev/null
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -0,0 +1,62 @@
1/* linux/arch/arm/mach-s3c2412/gpio.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/.
7 *
8 * S3C2412/S3C2413 specific GPIO support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19#include <linux/gpio.h>
20
21#include <asm/mach/arch.h>
22#include <asm/mach/map.h>
23
24#include <mach/regs-gpio.h>
25#include <mach/hardware.h>
26
27#include <plat/gpio-core.h>
28
29int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
30{
31 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
32 unsigned long offs = pin - chip->chip.base;
33 unsigned long flags;
34 unsigned long slpcon;
35
36 offs *= 2;
37
38 if (pin < S3C2410_GPB(0))
39 return -EINVAL;
40
41 if (pin >= S3C2410_GPF(0) &&
42 pin <= S3C2410_GPG(16))
43 return -EINVAL;
44
45 if (pin > S3C2410_GPH(16))
46 return -EINVAL;
47
48 local_irq_save(flags);
49
50 slpcon = __raw_readl(chip->base + 0x0C);
51
52 slpcon &= ~(3 << offs);
53 slpcon |= state << offs;
54
55 __raw_writel(slpcon, chip->base + 0x0C);
56
57 local_irq_restore(flags);
58
59 return 0;
60}
61
62EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg);
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index 69b48a7d1dbd..84c7b03e5a30 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -13,7 +13,6 @@ config CPU_S3C2416
13 select CPU_ARM926T 13 select CPU_ARM926T
14 select S3C2416_DMA if S3C2410_DMA 14 select S3C2416_DMA if S3C2410_DMA
15 select CPU_LLSERIAL_S3C2440 15 select CPU_LLSERIAL_S3C2440
16 select S3C_GPIO_PULL_UPDOWN
17 select SAMSUNG_CLKSRC 16 select SAMSUNG_CLKSRC
18 select S3C2443_CLOCK 17 select S3C2443_CLOCK
19 help 18 help
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 21a5e81f0ab5..afbbe8bc21d1 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -21,7 +21,6 @@
21#include <plat/cpu.h> 21#include <plat/cpu.h>
22 22
23#include <plat/cpu-freq.h> 23#include <plat/cpu-freq.h>
24#include <plat/pll6553x.h>
25#include <plat/pll.h> 24#include <plat/pll.h>
26 25
27#include <asm/mach/map.h> 26#include <asm/mach/map.h>
@@ -29,6 +28,14 @@
29#include <mach/regs-clock.h> 28#include <mach/regs-clock.h>
30#include <mach/regs-s3c2443-clock.h> 29#include <mach/regs-s3c2443-clock.h>
31 30
31/* armdiv
32 *
33 * this clock is sourced from msysclk and can have a number of
34 * divider values applied to it to then be fed into armclk.
35 * The real clock definition is done in s3c2443-clock.c,
36 * only the armdiv divisor table must be defined here.
37*/
38
32static unsigned int armdiv[8] = { 39static unsigned int armdiv[8] = {
33 [0] = 1, 40 [0] = 1,
34 [1] = 2, 41 [1] = 2,
@@ -38,6 +45,32 @@ static unsigned int armdiv[8] = {
38 [7] = 8, 45 [7] = 8,
39}; 46};
40 47
48static struct clksrc_clk hsspi_eplldiv = {
49 .clk = {
50 .name = "hsspi-eplldiv",
51 .parent = &clk_esysclk.clk,
52 .ctrlbit = (1 << 14),
53 .enable = s3c2443_clkcon_enable_s,
54 },
55 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
56};
57
58static struct clk *hsspi_sources[] = {
59 [0] = &hsspi_eplldiv.clk,
60 [1] = NULL, /* to fix */
61};
62
63static struct clksrc_clk hsspi_mux = {
64 .clk = {
65 .name = "hsspi-if",
66 },
67 .sources = &(struct clksrc_sources) {
68 .sources = hsspi_sources,
69 .nr_sources = ARRAY_SIZE(hsspi_sources),
70 },
71 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
72};
73
41static struct clksrc_clk hsmmc_div[] = { 74static struct clksrc_clk hsmmc_div[] = {
42 [0] = { 75 [0] = {
43 .clk = { 76 .clk = {
@@ -100,20 +133,15 @@ static struct clk hsmmc0_clk = {
100 .ctrlbit = S3C2416_HCLKCON_HSMMC0, 133 .ctrlbit = S3C2416_HCLKCON_HSMMC0,
101}; 134};
102 135
103static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
104{
105 clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
106
107 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
108}
109
110void __init_or_cpufreq s3c2416_setup_clocks(void) 136void __init_or_cpufreq s3c2416_setup_clocks(void)
111{ 137{
112 s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div); 138 s3c2443_common_setup_clocks(s3c2416_get_pll);
113} 139}
114 140
115 141
116static struct clksrc_clk *clksrcs[] __initdata = { 142static struct clksrc_clk *clksrcs[] __initdata = {
143 &hsspi_eplldiv,
144 &hsspi_mux,
117 &hsmmc_div[0], 145 &hsmmc_div[0],
118 &hsmmc_div[1], 146 &hsmmc_div[1],
119 &hsmmc_mux[0], 147 &hsmmc_mux[0],
@@ -131,7 +159,9 @@ void __init s3c2416_init_clocks(int xtal)
131 159
132 clk_epll.parent = &clk_epllref.clk; 160 clk_epll.parent = &clk_epllref.clk;
133 161
134 s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div); 162 s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
163 armdiv, ARRAY_SIZE(armdiv),
164 S3C2416_CLKDIV0_ARMDIV_MASK);
135 165
136 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 166 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
137 s3c_register_clksrc(clksrcs[ptr], 1); 167 s3c_register_clksrc(clksrcs[ptr], 1);
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index 20b3fdfb3051..ee214bc83c83 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -60,6 +60,7 @@
60#include <plat/iic-core.h> 60#include <plat/iic-core.h>
61#include <plat/fb-core.h> 61#include <plat/fb-core.h>
62#include <plat/nand-core.h> 62#include <plat/nand-core.h>
63#include <plat/adc-core.h>
63 64
64static struct map_desc s3c2416_iodesc[] __initdata = { 65static struct map_desc s3c2416_iodesc[] __initdata = {
65 IODESC_ENT(WATCHDOG), 66 IODESC_ENT(WATCHDOG),
@@ -97,6 +98,8 @@ int __init s3c2416_init(void)
97 98
98 s3c_fb_setname("s3c2443-fb"); 99 s3c_fb_setname("s3c2443-fb");
99 100
101 s3c_adc_setname("s3c2416-adc");
102
100#ifdef CONFIG_PM 103#ifdef CONFIG_PM
101 register_syscore_ops(&s3c2416_pm_syscore_ops); 104 register_syscore_ops(&s3c2416_pm_syscore_ops);
102#endif 105#endif
@@ -120,8 +123,8 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
120 123
121void __init s3c2416_map_io(void) 124void __init s3c2416_map_io(void)
122{ 125{
123 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown; 126 s3c24xx_gpiocfg_default.set_pull = samsung_gpio_setpull_updown;
124 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown; 127 s3c24xx_gpiocfg_default.get_pull = samsung_gpio_getpull_updown;
125 128
126 /* initialize device information early */ 129 /* initialize device information early */
127 s3c2416_default_sdhci0(); 130 s3c2416_default_sdhci0();
diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c
index ed34fad8f2c6..cee53955eb02 100644
--- a/arch/arm/mach-s3c2416/setup-sdhci.c
+++ b/arch/arm/mach-s3c2416/setup-sdhci.c
@@ -12,17 +12,7 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13*/ 13*/
14 14
15#include <linux/kernel.h>
16#include <linux/types.h> 15#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20
21#include <linux/mmc/card.h>
22#include <linux/mmc/host.h>
23
24#include <plat/regs-sdhci.h>
25#include <plat/sdhci.h>
26 16
27/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ 17/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
28 18
@@ -32,30 +22,3 @@ char *s3c2416_hsmmc_clksrcs[4] = {
32 [2] = "hsmmc-if", 22 [2] = "hsmmc-if",
33 /* [3] = "48m", - note not successfully used yet */ 23 /* [3] = "48m", - note not successfully used yet */
34}; 24};
35
36void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
37 void __iomem *r,
38 struct mmc_ios *ios,
39 struct mmc_card *card)
40{
41 u32 ctrl2, ctrl3;
42
43 ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2);
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
46 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
47 S3C_SDHCI_CTRL2_ENFBCLKRX |
48 S3C_SDHCI_CTRL2_DFCNT_NONE |
49 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
50
51 if (ios->clock < 25 * 1000000)
52 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
53 S3C_SDHCI_CTRL3_FCSEL2 |
54 S3C_SDHCI_CTRL3_FCSEL1 |
55 S3C_SDHCI_CTRL3_FCSEL0);
56 else
57 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
58
59 __raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2);
60 __raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3);
61}
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index c461fb8e15c0..914e620f1257 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -5,7 +5,6 @@
5config CPU_S3C2440 5config CPU_S3C2440
6 bool 6 bool
7 select CPU_ARM920T 7 select CPU_ARM920T
8 select S3C_GPIO_PULL_UP
9 select S3C2410_CLOCK 8 select S3C2410_CLOCK
10 select S3C2410_PM if PM 9 select S3C2410_PM if PM
11 select S3C2440_DMA if S3C2410_DMA 10 select S3C2440_DMA if S3C2410_DMA
@@ -17,7 +16,6 @@ config CPU_S3C2440
17config CPU_S3C2442 16config CPU_S3C2442
18 bool 17 bool
19 select CPU_ARM920T 18 select CPU_ARM920T
20 select S3C_GPIO_PULL_DOWN
21 select S3C2410_CLOCK 19 select S3C2410_CLOCK
22 select S3C2410_PM if PM 20 select S3C2410_PM if PM
23 select CPU_S3C244X 21 select CPU_S3C244X
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 684dbb3567f5..0d3453bf567c 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -43,6 +43,7 @@
43 43
44#include <mach/regs-gpio.h> 44#include <mach/regs-gpio.h>
45#include <mach/regs-gpioj.h> 45#include <mach/regs-gpioj.h>
46#include <mach/regs-lcd.h>
46#include <mach/h1940.h> 47#include <mach/h1940.h>
47#include <mach/fb.h> 48#include <mach/fb.h>
48 49
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 2270d3360216..37f8cc6aabd4 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -70,6 +70,6 @@ void __init s3c2440_map_io(void)
70{ 70{
71 s3c244x_map_io(); 71 s3c244x_map_io();
72 72
73 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; 73 s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
74 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; 74 s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
75} 75}
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
index 6f2b65e6e068..2c822e09392f 100644
--- a/arch/arm/mach-s3c2440/s3c2442.c
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -182,6 +182,6 @@ void __init s3c2442_map_io(void)
182{ 182{
183 s3c244x_map_io(); 183 s3c244x_map_io();
184 184
185 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down; 185 s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
186 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down; 186 s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
187} 187}
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index d8eb86823df7..8814031516ce 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -10,7 +10,6 @@ config CPU_S3C2443
10 select CPU_LLSERIAL_S3C2440 10 select CPU_LLSERIAL_S3C2440
11 select SAMSUNG_CLKSRC 11 select SAMSUNG_CLKSRC
12 select S3C2443_CLOCK 12 select S3C2443_CLOCK
13 select S3C_GPIO_PULL_S3C2443
14 help 13 help
15 Support for the S3C2443 SoC from the S3C24XX line 14 Support for the S3C2443 SoC from the S3C24XX line
16 15
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 38058af48972..1c2c088aa2e8 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -57,18 +57,14 @@
57 57
58/* clock selections */ 58/* clock selections */
59 59
60static struct clk clk_i2s_ext = {
61 .name = "i2s-ext",
62};
63
64/* armdiv 60/* armdiv
65 * 61 *
66 * this clock is sourced from msysclk and can have a number of 62 * this clock is sourced from msysclk and can have a number of
67 * divider values applied to it to then be fed into armclk. 63 * divider values applied to it to then be fed into armclk.
64 * The real clock definition is done in s3c2443-clock.c,
65 * only the armdiv divisor table must be defined here.
68*/ 66*/
69 67
70/* armdiv divisor table */
71
72static unsigned int armdiv[16] = { 68static unsigned int armdiv[16] = {
73 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, 69 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
74 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, 70 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
@@ -80,92 +76,6 @@ static unsigned int armdiv[16] = {
80 [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, 76 [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
81}; 77};
82 78
83static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
84{
85 clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
86
87 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
88}
89
90static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
91 unsigned long rate)
92{
93 unsigned long parent = clk_get_rate(clk->parent);
94 unsigned long calc;
95 unsigned best = 256; /* bigger than any value */
96 unsigned div;
97 int ptr;
98
99 for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
100 div = armdiv[ptr];
101 calc = parent / div;
102 if (calc <= rate && div < best)
103 best = div;
104 }
105
106 return parent / best;
107}
108
109static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
110{
111 unsigned long parent = clk_get_rate(clk->parent);
112 unsigned long calc;
113 unsigned div;
114 unsigned best = 256; /* bigger than any value */
115 int ptr;
116 int val = -1;
117
118 for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
119 div = armdiv[ptr];
120 calc = parent / div;
121 if (calc <= rate && div < best) {
122 best = div;
123 val = ptr;
124 }
125 }
126
127 if (val >= 0) {
128 unsigned long clkcon0;
129
130 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
131 clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK;
132 clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
133 __raw_writel(clkcon0, S3C2443_CLKDIV0);
134 }
135
136 return (val == -1) ? -EINVAL : 0;
137}
138
139static struct clk clk_armdiv = {
140 .name = "armdiv",
141 .parent = &clk_msysclk.clk,
142 .ops = &(struct clk_ops) {
143 .round_rate = s3c2443_armclk_roundrate,
144 .set_rate = s3c2443_armclk_setrate,
145 },
146};
147
148/* armclk
149 *
150 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
151 */
152
153static struct clk *clk_arm_sources[] = {
154 [0] = &clk_armdiv,
155 [1] = &clk_h,
156};
157
158static struct clksrc_clk clk_arm = {
159 .clk = {
160 .name = "armclk",
161 },
162 .sources = &(struct clksrc_sources) {
163 .sources = clk_arm_sources,
164 .nr_sources = ARRAY_SIZE(clk_arm_sources),
165 },
166 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
167};
168
169/* hsspi 79/* hsspi
170 * 80 *
171 * high-speed spi clock, sourced from esysclk 81 * high-speed spi clock, sourced from esysclk
@@ -173,7 +83,7 @@ static struct clksrc_clk clk_arm = {
173 83
174static struct clksrc_clk clk_hsspi = { 84static struct clksrc_clk clk_hsspi = {
175 .clk = { 85 .clk = {
176 .name = "hsspi", 86 .name = "hsspi-if",
177 .parent = &clk_esysclk.clk, 87 .parent = &clk_esysclk.clk,
178 .ctrlbit = S3C2443_SCLKCON_HSSPICLK, 88 .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
179 .enable = s3c2443_clkcon_enable_s, 89 .enable = s3c2443_clkcon_enable_s,
@@ -235,48 +145,6 @@ static struct clk clk_hsmmc = {
235 }, 145 },
236}; 146};
237 147
238/* i2s_eplldiv
239 *
240 * This clock is the output from the I2S divisor of ESYSCLK, and is separate
241 * from the mux that comes after it (cannot merge into one single clock)
242*/
243
244static struct clksrc_clk clk_i2s_eplldiv = {
245 .clk = {
246 .name = "i2s-eplldiv",
247 .parent = &clk_esysclk.clk,
248 },
249 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
250};
251
252/* i2s-ref
253 *
254 * i2s bus reference clock, selectable from external, esysclk or epllref
255 *
256 * Note, this used to be two clocks, but was compressed into one.
257*/
258
259struct clk *clk_i2s_srclist[] = {
260 [0] = &clk_i2s_eplldiv.clk,
261 [1] = &clk_i2s_ext,
262 [2] = &clk_epllref.clk,
263 [3] = &clk_epllref.clk,
264};
265
266static struct clksrc_clk clk_i2s = {
267 .clk = {
268 .name = "i2s-if",
269 .ctrlbit = S3C2443_SCLKCON_I2SCLK,
270 .enable = s3c2443_clkcon_enable_s,
271
272 },
273 .sources = &(struct clksrc_sources) {
274 .sources = clk_i2s_srclist,
275 .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
276 },
277 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
278};
279
280/* standard clock definitions */ 148/* standard clock definitions */
281 149
282static struct clk init_clocks_off[] = { 150static struct clk init_clocks_off[] = {
@@ -286,11 +154,6 @@ static struct clk init_clocks_off[] = {
286 .enable = s3c2443_clkcon_enable_p, 154 .enable = s3c2443_clkcon_enable_p,
287 .ctrlbit = S3C2443_PCLKCON_SDI, 155 .ctrlbit = S3C2443_PCLKCON_SDI,
288 }, { 156 }, {
289 .name = "iis",
290 .parent = &clk_p,
291 .enable = s3c2443_clkcon_enable_p,
292 .ctrlbit = S3C2443_PCLKCON_IIS,
293 }, {
294 .name = "spi", 157 .name = "spi",
295 .devname = "s3c2410-spi.0", 158 .devname = "s3c2410-spi.0",
296 .parent = &clk_p, 159 .parent = &clk_p,
@@ -305,27 +168,20 @@ static struct clk init_clocks_off[] = {
305 } 168 }
306}; 169};
307 170
308static struct clk init_clocks[] = {
309};
310
311/* clocks to add straight away */ 171/* clocks to add straight away */
312 172
313static struct clksrc_clk *clksrcs[] __initdata = { 173static struct clksrc_clk *clksrcs[] __initdata = {
314 &clk_arm,
315 &clk_i2s_eplldiv,
316 &clk_i2s,
317 &clk_hsspi, 174 &clk_hsspi,
318 &clk_hsmmc_div, 175 &clk_hsmmc_div,
319}; 176};
320 177
321static struct clk *clks[] __initdata = { 178static struct clk *clks[] __initdata = {
322 &clk_hsmmc, 179 &clk_hsmmc,
323 &clk_armdiv,
324}; 180};
325 181
326void __init_or_cpufreq s3c2443_setup_clocks(void) 182void __init_or_cpufreq s3c2443_setup_clocks(void)
327{ 183{
328 s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div); 184 s3c2443_common_setup_clocks(s3c2443_get_mpll);
329} 185}
330 186
331void __init s3c2443_init_clocks(int xtal) 187void __init s3c2443_init_clocks(int xtal)
@@ -336,7 +192,9 @@ void __init s3c2443_init_clocks(int xtal)
336 clk_epll.rate = s3c2443_get_epll(epllcon, xtal); 192 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
337 clk_epll.parent = &clk_epllref.clk; 193 clk_epll.parent = &clk_epllref.clk;
338 194
339 s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div); 195 s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
196 armdiv, ARRAY_SIZE(armdiv),
197 S3C2443_CLKDIV0_ARMDIV_MASK);
340 198
341 s3c2443_setup_clocks(); 199 s3c2443_setup_clocks();
342 200
@@ -345,10 +203,6 @@ void __init s3c2443_init_clocks(int xtal)
345 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 203 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
346 s3c_register_clksrc(clksrcs[ptr], 1); 204 s3c_register_clksrc(clksrcs[ptr], 1);
347 205
348 /* register clocks from clock array */
349
350 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
351
352 /* We must be careful disabling the clocks we are not intending to 206 /* We must be careful disabling the clocks we are not intending to
353 * be using at boot time, as subsystems such as the LCD which do 207 * be using at boot time, as subsystems such as the LCD which do
354 * their own DMA requests to the bus can cause the system to lockup 208 * their own DMA requests to the bus can cause the system to lockup
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index e6a28ba52c7d..a22b771b0f36 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -41,6 +41,7 @@
41#include <plat/cpu.h> 41#include <plat/cpu.h>
42#include <plat/fb-core.h> 42#include <plat/fb-core.h>
43#include <plat/nand-core.h> 43#include <plat/nand-core.h>
44#include <plat/adc-core.h>
44 45
45static struct map_desc s3c2443_iodesc[] __initdata = { 46static struct map_desc s3c2443_iodesc[] __initdata = {
46 IODESC_ENT(WATCHDOG), 47 IODESC_ENT(WATCHDOG),
@@ -70,6 +71,8 @@ int __init s3c2443_init(void)
70 s3c_nand_setname("s3c2412-nand"); 71 s3c_nand_setname("s3c2412-nand");
71 s3c_fb_setname("s3c2443-fb"); 72 s3c_fb_setname("s3c2443-fb");
72 73
74 s3c_adc_setname("s3c2443-adc");
75
73 /* change WDT IRQ number */ 76 /* change WDT IRQ number */
74 s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; 77 s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
75 s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; 78 s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
@@ -90,8 +93,8 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
90 93
91void __init s3c2443_map_io(void) 94void __init s3c2443_map_io(void)
92{ 95{
93 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_s3c2443; 96 s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull;
94 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_s3c2443; 97 s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
95 98
96 iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); 99 iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
97} 100}
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index f057b6ae4f90..5552e048c2be 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -288,5 +288,6 @@ config MACH_WLF_CRAGG_6410
288 select S3C_DEV_RTC 288 select S3C_DEV_RTC
289 select S3C64XX_DEV_SPI 289 select S3C64XX_DEV_SPI
290 select S3C24XX_GPIO_EXTRA128 290 select S3C24XX_GPIO_EXTRA128
291 select I2C
291 help 292 help
292 Machine support for the Wolfson Cragganmore S3C6410 variant. 293 Machine support for the Wolfson Cragganmore S3C6410 variant.
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 61b4034a0c22..cfc0b9941808 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -13,7 +13,6 @@ obj- :=
13# Core files 13# Core files
14obj-y += cpu.o 14obj-y += cpu.o
15obj-y += clock.o 15obj-y += clock.o
16obj-y += gpiolib.o
17 16
18# Core support for S3C6400 system 17# Core support for S3C6400 system
19 18
@@ -55,12 +54,10 @@ obj-$(CONFIG_MACH_HMT) += mach-hmt.o
55obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o 54obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
56obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o 55obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o
57obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o 56obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o
58obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o 57obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
59 58
60# device support 59# device support
61 60
62obj-y += dev-uart.o 61obj-y += dev-uart.o
63obj-y += dev-audio.o 62obj-y += dev-audio.o
64obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o 63obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
65obj-$(CONFIG_S3C64XX_DEV_TS) += dev-ts.o
66obj-$(CONFIG_S3C64XX_DEV_ONENAND1) += dev-onenand1.o
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 8cf39e33579e..39c238d7a3dc 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -25,13 +25,13 @@
25 25
26#include <mach/regs-sys.h> 26#include <mach/regs-sys.h>
27#include <mach/regs-clock.h> 27#include <mach/regs-clock.h>
28#include <mach/pll.h>
29 28
30#include <plat/cpu.h> 29#include <plat/cpu.h>
31#include <plat/devs.h> 30#include <plat/devs.h>
32#include <plat/cpu-freq.h> 31#include <plat/cpu-freq.h>
33#include <plat/clock.h> 32#include <plat/clock.h>
34#include <plat/clock-clksrc.h> 33#include <plat/clock-clksrc.h>
34#include <plat/pll.h>
35 35
36/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call 36/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
37 * ext_xtal_mux for want of an actual name from the manual. 37 * ext_xtal_mux for want of an actual name from the manual.
@@ -735,7 +735,8 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
735 /* For now assume the mux always selects the crystal */ 735 /* For now assume the mux always selects the crystal */
736 clk_ext_xtal_mux.parent = xtal_clk; 736 clk_ext_xtal_mux.parent = xtal_clk;
737 737
738 epll = s3c6400_get_epll(xtal); 738 epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0),
739 __raw_readl(S3C_EPLL_CON1));
739 mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); 740 mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
740 apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); 741 apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
741 742
@@ -744,7 +745,13 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
744 printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n", 745 printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
745 apll, mpll, epll); 746 apll, mpll, epll);
746 747
747 hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); 748 if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL)
749 /* Synchronous mode */
750 hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
751 else
752 /* Asynchronous mode */
753 hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
754
748 hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK); 755 hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
749 pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK); 756 pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
750 757
diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c
index c7047838e112..de085b798aa4 100644
--- a/arch/arm/mach-s3c64xx/cpu.c
+++ b/arch/arm/mach-s3c64xx/cpu.c
@@ -34,8 +34,8 @@
34#include <plat/devs.h> 34#include <plat/devs.h>
35#include <plat/clock.h> 35#include <plat/clock.h>
36 36
37#include <mach/s3c6400.h> 37#include <plat/s3c6400.h>
38#include <mach/s3c6410.h> 38#include <plat/s3c6410.h>
39 39
40/* table of supported CPUs */ 40/* table of supported CPUs */
41 41
diff --git a/arch/arm/mach-s3c64xx/dev-onenand1.c b/arch/arm/mach-s3c64xx/dev-onenand1.c
deleted file mode 100644
index 999f9e17a1e4..000000000000
--- a/arch/arm/mach-s3c64xx/dev-onenand1.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * linux/arch/arm/mach-s3c64xx/dev-onenand1.c
3 *
4 * Copyright (c) 2008-2010 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * S3C64XX series device definition for OneNAND devices
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/onenand.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/devs.h>
23
24static struct resource s3c64xx_onenand1_resources[] = {
25 [0] = {
26 .start = S3C64XX_PA_ONENAND1,
27 .end = S3C64XX_PA_ONENAND1 + 0x400 - 1,
28 .flags = IORESOURCE_MEM,
29 },
30 [1] = {
31 .start = S3C64XX_PA_ONENAND1_BUF,
32 .end = S3C64XX_PA_ONENAND1_BUF + S3C64XX_SZ_ONENAND1_BUF - 1,
33 .flags = IORESOURCE_MEM,
34 },
35 [2] = {
36 .start = IRQ_ONENAND1,
37 .end = IRQ_ONENAND1,
38 .flags = IORESOURCE_IRQ,
39 },
40};
41
42struct platform_device s3c64xx_device_onenand1 = {
43 .name = "samsung-onenand",
44 .id = 1,
45 .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources),
46 .resource = s3c64xx_onenand1_resources,
47};
48
49void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
50{
51 s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
52 &s3c64xx_device_onenand1);
53}
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
index 204bfafe4bfc..17d62f4f8204 100644
--- a/arch/arm/mach-s3c64xx/dma.c
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
147 u32 control0, control1; 147 u32 control0, control1;
148 148
149 switch (chan->source) { 149 switch (chan->source) {
150 case S3C2410_DMASRC_HW: 150 case DMA_FROM_DEVICE:
151 src = chan->dev_addr; 151 src = chan->dev_addr;
152 dst = data; 152 dst = data;
153 control0 = PL080_CONTROL_SRC_AHB2; 153 control0 = PL080_CONTROL_SRC_AHB2;
154 control0 |= PL080_CONTROL_DST_INCR; 154 control0 |= PL080_CONTROL_DST_INCR;
155 break; 155 break;
156 156
157 case S3C2410_DMASRC_MEM: 157 case DMA_TO_DEVICE:
158 src = data; 158 src = data;
159 dst = chan->dev_addr; 159 dst = chan->dev_addr;
160 control0 = PL080_CONTROL_DST_AHB2; 160 control0 = PL080_CONTROL_DST_AHB2;
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue);
416 416
417 417
418int s3c2410_dma_devconfig(enum dma_ch channel, 418int s3c2410_dma_devconfig(enum dma_ch channel,
419 enum s3c2410_dmasrc source, 419 enum dma_data_direction source,
420 unsigned long devaddr) 420 unsigned long devaddr)
421{ 421{
422 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); 422 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
437 pr_debug("%s: peripheral %d\n", __func__, peripheral); 437 pr_debug("%s: peripheral %d\n", __func__, peripheral);
438 438
439 switch (source) { 439 switch (source) {
440 case S3C2410_DMASRC_HW: 440 case DMA_FROM_DEVICE:
441 config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT; 441 config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
442 config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT; 442 config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
443 break; 443 break;
444 case S3C2410_DMASRC_MEM: 444 case DMA_TO_DEVICE:
445 config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT; 445 config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
446 config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT; 446 config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
447 break; 447 break;
@@ -740,7 +740,7 @@ static int __init s3c64xx_dma_init(void)
740 } 740 }
741 741
742 /* Set all DMA configuration to be DMA, not SDMA */ 742 /* Set all DMA configuration to be DMA, not SDMA */
743 writel(0xffffff, S3C_SYSREG(0x110)); 743 writel(0xffffff, S3C64XX_SDMA_SEL);
744 744
745 /* Register standard DMA controllers */ 745 /* Register standard DMA controllers */
746 s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); 746 s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
deleted file mode 100644
index 92b09085caaa..000000000000
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ /dev/null
@@ -1,290 +0,0 @@
1/* arch/arm/plat-s3c64xx/gpiolib.c
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C64XX - GPIOlib support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19
20#include <mach/map.h>
21
22#include <plat/gpio-core.h>
23#include <plat/gpio-cfg.h>
24#include <plat/gpio-cfg-helpers.h>
25#include <mach/regs-gpio.h>
26
27/* GPIO bank summary:
28 *
29 * Bank GPIOs Style SlpCon ExtInt Group
30 * A 8 4Bit Yes 1
31 * B 7 4Bit Yes 1
32 * C 8 4Bit Yes 2
33 * D 5 4Bit Yes 3
34 * E 5 4Bit Yes None
35 * F 16 2Bit Yes 4 [1]
36 * G 7 4Bit Yes 5
37 * H 10 4Bit[2] Yes 6
38 * I 16 2Bit Yes None
39 * J 12 2Bit Yes None
40 * K 16 4Bit[2] No None
41 * L 15 4Bit[2] No None
42 * M 6 4Bit No IRQ_EINT
43 * N 16 2Bit No IRQ_EINT
44 * O 16 2Bit Yes 7
45 * P 15 2Bit Yes 8
46 * Q 9 2Bit Yes 9
47 *
48 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
49 * [2] BANK has two control registers, GPxCON0 and GPxCON1
50 */
51
52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
53 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
54 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
55 .set_pull = s3c_gpio_setpull_updown,
56 .get_pull = s3c_gpio_getpull_updown,
57};
58
59static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
60 .cfg_eint = 7,
61 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
62 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
63 .set_pull = s3c_gpio_setpull_updown,
64 .get_pull = s3c_gpio_getpull_updown,
65};
66
67static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
68 .cfg_eint = 3,
69 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
70 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
71 .set_pull = s3c_gpio_setpull_updown,
72 .get_pull = s3c_gpio_getpull_updown,
73};
74
75static int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
76{
77 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
78}
79
80static struct s3c_gpio_chip gpio_4bit[] = {
81 {
82 .base = S3C64XX_GPA_BASE,
83 .config = &gpio_4bit_cfg_eint0111,
84 .chip = {
85 .base = S3C64XX_GPA(0),
86 .ngpio = S3C64XX_GPIO_A_NR,
87 .label = "GPA",
88 },
89 }, {
90 .base = S3C64XX_GPB_BASE,
91 .config = &gpio_4bit_cfg_eint0111,
92 .chip = {
93 .base = S3C64XX_GPB(0),
94 .ngpio = S3C64XX_GPIO_B_NR,
95 .label = "GPB",
96 },
97 }, {
98 .base = S3C64XX_GPC_BASE,
99 .config = &gpio_4bit_cfg_eint0111,
100 .chip = {
101 .base = S3C64XX_GPC(0),
102 .ngpio = S3C64XX_GPIO_C_NR,
103 .label = "GPC",
104 },
105 }, {
106 .base = S3C64XX_GPD_BASE,
107 .config = &gpio_4bit_cfg_eint0111,
108 .chip = {
109 .base = S3C64XX_GPD(0),
110 .ngpio = S3C64XX_GPIO_D_NR,
111 .label = "GPD",
112 },
113 }, {
114 .base = S3C64XX_GPE_BASE,
115 .config = &gpio_4bit_cfg_noint,
116 .chip = {
117 .base = S3C64XX_GPE(0),
118 .ngpio = S3C64XX_GPIO_E_NR,
119 .label = "GPE",
120 },
121 }, {
122 .base = S3C64XX_GPG_BASE,
123 .config = &gpio_4bit_cfg_eint0111,
124 .chip = {
125 .base = S3C64XX_GPG(0),
126 .ngpio = S3C64XX_GPIO_G_NR,
127 .label = "GPG",
128 },
129 }, {
130 .base = S3C64XX_GPM_BASE,
131 .config = &gpio_4bit_cfg_eint0011,
132 .chip = {
133 .base = S3C64XX_GPM(0),
134 .ngpio = S3C64XX_GPIO_M_NR,
135 .label = "GPM",
136 .to_irq = s3c64xx_gpio2int_gpm,
137 },
138 },
139};
140
141static int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
142{
143 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
144}
145
146static struct s3c_gpio_chip gpio_4bit2[] = {
147 {
148 .base = S3C64XX_GPH_BASE + 0x4,
149 .config = &gpio_4bit_cfg_eint0111,
150 .chip = {
151 .base = S3C64XX_GPH(0),
152 .ngpio = S3C64XX_GPIO_H_NR,
153 .label = "GPH",
154 },
155 }, {
156 .base = S3C64XX_GPK_BASE + 0x4,
157 .config = &gpio_4bit_cfg_noint,
158 .chip = {
159 .base = S3C64XX_GPK(0),
160 .ngpio = S3C64XX_GPIO_K_NR,
161 .label = "GPK",
162 },
163 }, {
164 .base = S3C64XX_GPL_BASE + 0x4,
165 .config = &gpio_4bit_cfg_eint0011,
166 .chip = {
167 .base = S3C64XX_GPL(0),
168 .ngpio = S3C64XX_GPIO_L_NR,
169 .label = "GPL",
170 .to_irq = s3c64xx_gpio2int_gpl,
171 },
172 },
173};
174
175static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
176 .set_config = s3c_gpio_setcfg_s3c24xx,
177 .get_config = s3c_gpio_getcfg_s3c24xx,
178 .set_pull = s3c_gpio_setpull_updown,
179 .get_pull = s3c_gpio_getpull_updown,
180};
181
182static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
183 .cfg_eint = 2,
184 .set_config = s3c_gpio_setcfg_s3c24xx,
185 .get_config = s3c_gpio_getcfg_s3c24xx,
186 .set_pull = s3c_gpio_setpull_updown,
187 .get_pull = s3c_gpio_getpull_updown,
188};
189
190static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
191 .cfg_eint = 3,
192 .set_config = s3c_gpio_setcfg_s3c24xx,
193 .get_config = s3c_gpio_getcfg_s3c24xx,
194 .set_pull = s3c_gpio_setpull_updown,
195 .get_pull = s3c_gpio_getpull_updown,
196};
197
198static struct s3c_gpio_chip gpio_2bit[] = {
199 {
200 .base = S3C64XX_GPF_BASE,
201 .config = &gpio_2bit_cfg_eint11,
202 .chip = {
203 .base = S3C64XX_GPF(0),
204 .ngpio = S3C64XX_GPIO_F_NR,
205 .label = "GPF",
206 },
207 }, {
208 .base = S3C64XX_GPI_BASE,
209 .config = &gpio_2bit_cfg_noint,
210 .chip = {
211 .base = S3C64XX_GPI(0),
212 .ngpio = S3C64XX_GPIO_I_NR,
213 .label = "GPI",
214 },
215 }, {
216 .base = S3C64XX_GPJ_BASE,
217 .config = &gpio_2bit_cfg_noint,
218 .chip = {
219 .base = S3C64XX_GPJ(0),
220 .ngpio = S3C64XX_GPIO_J_NR,
221 .label = "GPJ",
222 },
223 }, {
224 .base = S3C64XX_GPN_BASE,
225 .irq_base = IRQ_EINT(0),
226 .config = &gpio_2bit_cfg_eint10,
227 .chip = {
228 .base = S3C64XX_GPN(0),
229 .ngpio = S3C64XX_GPIO_N_NR,
230 .label = "GPN",
231 .to_irq = samsung_gpiolib_to_irq,
232 },
233 }, {
234 .base = S3C64XX_GPO_BASE,
235 .config = &gpio_2bit_cfg_eint11,
236 .chip = {
237 .base = S3C64XX_GPO(0),
238 .ngpio = S3C64XX_GPIO_O_NR,
239 .label = "GPO",
240 },
241 }, {
242 .base = S3C64XX_GPP_BASE,
243 .config = &gpio_2bit_cfg_eint11,
244 .chip = {
245 .base = S3C64XX_GPP(0),
246 .ngpio = S3C64XX_GPIO_P_NR,
247 .label = "GPP",
248 },
249 }, {
250 .base = S3C64XX_GPQ_BASE,
251 .config = &gpio_2bit_cfg_eint11,
252 .chip = {
253 .base = S3C64XX_GPQ(0),
254 .ngpio = S3C64XX_GPIO_Q_NR,
255 .label = "GPQ",
256 },
257 },
258};
259
260static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
261{
262 chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
263}
264
265static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
266 int nr_chips,
267 void (*fn)(struct s3c_gpio_chip *))
268{
269 for (; nr_chips > 0; nr_chips--, chips++) {
270 if (fn)
271 (fn)(chips);
272 s3c_gpiolib_add(chips);
273 }
274}
275
276static __init int s3c64xx_gpiolib_init(void)
277{
278 s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
279 samsung_gpiolib_add_4bit);
280
281 s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
282 samsung_gpiolib_add_4bit2);
283
284 s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
285 s3c64xx_gpiolib_add_2bit);
286
287 return 0;
288}
289
290core_initcall(s3c64xx_gpiolib_init);
diff --git a/arch/arm/mach-s3c64xx/include/mach/clkdev.h b/arch/arm/mach-s3c64xx/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/mach-s3c64xx/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h
new file mode 100644
index 000000000000..be9074e17dfd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h
@@ -0,0 +1,23 @@
1/* Cragganmore 6410 shared definitions
2 *
3 * Copyright 2011 Wolfson Microelectronics plc
4 * Mark Brown <broonie@opensource.wolfsonmicro.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef MACH_CRAG6410_H
12#define MACH_CRAG6410_H
13
14#include <linux/gpio.h>
15
16#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START
17#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
18
19#define PCA935X_GPIO_BASE GPIO_BOARD_START
20#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
21#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16)
22
23#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 0a5d9268a23e..fe1a98cf0e4c 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -58,11 +58,15 @@ enum dma_ch {
58 DMACH_MAX /* the end */ 58 DMACH_MAX /* the end */
59}; 59};
60 60
61static __inline__ bool s3c_dma_has_circular(void) 61static inline bool samsung_dma_has_circular(void)
62{ 62{
63 return true; 63 return true;
64} 64}
65 65
66static inline bool samsung_dma_is_dmadev(void)
67{
68 return false;
69}
66#define S3C2410_DMAF_CIRCULAR (1 << 0) 70#define S3C2410_DMAF_CIRCULAR (1 << 0)
67 71
68#include <plat/dma.h> 72#include <plat/dma.h>
@@ -95,7 +99,7 @@ struct s3c2410_dma_chan {
95 unsigned char peripheral; 99 unsigned char peripheral;
96 100
97 unsigned int flags; 101 unsigned int flags;
98 enum s3c2410_dmasrc source; 102 enum dma_data_direction source;
99 103
100 104
101 dma_addr_t dev_addr; 105 dma_addr_t dev_addr;
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
deleted file mode 100644
index 5ef0bb698ee0..000000000000
--- a/arch/arm/mach-s3c64xx/include/mach/pll.h
+++ /dev/null
@@ -1,45 +0,0 @@
1/* arch/arm/plat-s3c64xx/include/plat/pll.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C64XX PLL code
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define S3C6400_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
16#define S3C6400_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
17#define S3C6400_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
18#define S3C6400_PLL_MDIV_SHIFT (16)
19#define S3C6400_PLL_PDIV_SHIFT (8)
20#define S3C6400_PLL_SDIV_SHIFT (0)
21
22#include <asm/div64.h>
23#include <plat/pll6553x.h>
24
25static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
26 u32 pllcon)
27{
28 u32 mdiv, pdiv, sdiv;
29 u64 fvco = baseclk;
30
31 mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
32 pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
33 sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
34
35 fvco *= mdiv;
36 do_div(fvco, (pdiv << sdiv));
37
38 return (unsigned long)fvco;
39}
40
41static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
42{
43 return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
44 __raw_readl(S3C_EPLL_CON1));
45}
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
index 38659bebe4b1..fcf3dcabb694 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -104,7 +104,7 @@ static inline void s3c_pm_restored_gpios(void)
104 __raw_writel(0, S3C64XX_SLPEN); 104 __raw_writel(0, S3C64XX_SLPEN);
105} 105}
106 106
107static inline void s3c_pm_saved_gpios(void) 107static inline void samsung_pm_saved_gpios(void)
108{ 108{
109 /* turn on the sleep mode and keep it there, as it seems that during 109 /* turn on the sleep mode and keep it there, as it seems that during
110 * suspend the xCON registers get re-set and thus you can end up with 110 * suspend the xCON registers get re-set and thus you can end up with
diff --git a/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h b/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
deleted file mode 100644
index b25bedee0d52..000000000000
--- a/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C64xx - pwm clock and timer support
9 */
10
11/**
12 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
13 * @tcfg: The timer TCFG1 register bits shifted down to 0.
14 *
15 * Return true if the given configuration from TCFG1 is a TCLK instead
16 * any of the TDIV clocks.
17 */
18static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
19{
20 return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
21}
22
23/**
24 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
25 * @tcfg1: The tcfg1 setting, shifted down.
26 *
27 * Get the divisor value for the given tcfg1 setting. We assume the
28 * caller has already checked to see if this is not a TCLK source.
29 */
30static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
31{
32 return 1 << tcfg1;
33}
34
35/**
36 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
37 *
38 * Return true if we have a /1 in the tdiv setting.
39 */
40static inline unsigned int pwm_tdiv_has_div1(void)
41{
42 return 1;
43}
44
45/**
46 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
47 * @div: The divisor to calculate the bit information for.
48 *
49 * Turn a divisor into the necessary bit field for TCFG1.
50 */
51static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
52{
53 return ilog2(div);
54}
55
56#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-sys.h b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
index 69b78d9f83b8..b91e02093289 100644
--- a/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
@@ -21,8 +21,11 @@
21#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104) 21#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104)
22#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108) 22#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108)
23 23
24#define S3C64XX_SDMA_SEL S3C_SYSREG(0x110)
25
24#define S3C64XX_OTHERS S3C_SYSREG(0x900) 26#define S3C64XX_OTHERS S3C_SYSREG(0x900)
25 27
26#define S3C64XX_OTHERS_USBMASK (1 << 16) 28#define S3C64XX_OTHERS_USBMASK (1 << 16)
29#define S3C64XX_OTHERS_SYNCMUXSEL (1 << 6)
27 30
28#endif /* _PLAT_REGS_SYS_H */ 31#endif /* _PLAT_REGS_SYS_H */
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index d164a282bfb4..8eba88e7209e 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -45,7 +45,7 @@
45#include <plat/fb.h> 45#include <plat/fb.h>
46#include <plat/regs-fb-v4.h> 46#include <plat/regs-fb-v4.h>
47 47
48#include <mach/s3c6410.h> 48#include <plat/s3c6410.h>
49#include <plat/clock.h> 49#include <plat/clock.h>
50#include <plat/devs.h> 50#include <plat/devs.h>
51#include <plat/cpu.h> 51#include <plat/cpu.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
new file mode 100644
index 000000000000..66668565ee75
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -0,0 +1,182 @@
1/* Speyside modules for Cragganmore - board data probing
2 *
3 * Copyright 2011 Wolfson Microelectronics plc
4 * Mark Brown <broonie@opensource.wolfsonmicro.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/interrupt.h>
13#include <linux/i2c.h>
14
15#include <linux/mfd/wm831x/irq.h>
16#include <linux/mfd/wm831x/gpio.h>
17
18#include <sound/wm8996.h>
19#include <sound/wm8962.h>
20#include <sound/wm9081.h>
21
22#include <mach/crag6410.h>
23
24static struct wm8996_retune_mobile_config wm8996_retune[] = {
25 {
26 .name = "Sub LPF",
27 .rate = 48000,
28 .regs = {
29 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
30 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
31 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
32 },
33 },
34 {
35 .name = "Sub HPF",
36 .rate = 48000,
37 .regs = {
38 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
39 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
40 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
41 },
42 },
43};
44
45static struct wm8996_pdata wm8996_pdata __initdata = {
46 .ldo_ena = S3C64XX_GPN(7),
47 .gpio_base = CODEC_GPIO_BASE,
48 .micdet_def = 1,
49 .inl_mode = WM8996_DIFFERRENTIAL_1,
50 .inr_mode = WM8996_DIFFERRENTIAL_1,
51
52 .irq_flags = IRQF_TRIGGER_RISING,
53
54 .gpio_default = {
55 0x8001, /* GPIO1 == ADCLRCLK1 */
56 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
57 0x0141, /* GPIO3 == HP_SEL */
58 0x0002, /* GPIO4 == IRQ */
59 0x020e, /* GPIO5 == CLKOUT */
60 },
61
62 .retune_mobile_cfgs = wm8996_retune,
63 .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
64};
65
66static struct wm8962_pdata wm8962_pdata __initdata = {
67 .gpio_init = {
68 0,
69 WM8962_GPIO_FN_OPCLK,
70 WM8962_GPIO_FN_DMICCLK,
71 0,
72 0x8000 | WM8962_GPIO_FN_DMICDAT,
73 WM8962_GPIO_FN_IRQ, /* Open drain mode */
74 },
75 .irq_active_low = true,
76};
77
78static struct wm9081_pdata wm9081_pdata __initdata = {
79 .irq_high = false,
80 .irq_cmos = false,
81};
82
83static const struct i2c_board_info wm1254_devs[] = {
84 { I2C_BOARD_INFO("wm8996", 0x1a),
85 .platform_data = &wm8996_pdata,
86 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
87 },
88 { I2C_BOARD_INFO("wm9081", 0x6c),
89 .platform_data = &wm9081_pdata, },
90};
91
92static const struct i2c_board_info wm1255_devs[] = {
93 { I2C_BOARD_INFO("wm5100", 0x1a),
94 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
95 },
96 { I2C_BOARD_INFO("wm9081", 0x6c),
97 .platform_data = &wm9081_pdata, },
98};
99
100static const struct i2c_board_info wm1259_devs[] = {
101 { I2C_BOARD_INFO("wm8962", 0x1a),
102 .platform_data = &wm8962_pdata,
103 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
104 },
105};
106
107
108static __devinitdata const struct {
109 u8 id;
110 const char *name;
111 const struct i2c_board_info *i2c_devs;
112 int num_i2c_devs;
113} gf_mods[] = {
114 { .id = 0x01, .name = "1250-EV1 Springbank" },
115 { .id = 0x02, .name = "1251-EV1 Jura" },
116 { .id = 0x03, .name = "1252-EV1 Glenlivet" },
117 { .id = 0x11, .name = "6249-EV2 Glenfarclas", },
118 { .id = 0x21, .name = "1275-EV1 Mortlach" },
119 { .id = 0x25, .name = "1274-EV1 Glencadam" },
120 { .id = 0x31, .name = "1253-EV1 Tomatin", },
121 { .id = 0x39, .name = "1254-EV1 Dallas Dhu",
122 .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
123 { .id = 0x3a, .name = "1259-EV1 Tobermory",
124 .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
125 { .id = 0x3b, .name = "1255-EV1 Kilchoman",
126 .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
127 { .id = 0x3c, .name = "1273-EV1 Longmorn" },
128};
129
130static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
131 const struct i2c_device_id *i2c_id)
132{
133 int ret, i, j, id, rev;
134
135 ret = i2c_smbus_read_byte_data(i2c, 0);
136 if (ret < 0) {
137 dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
138 return ret;
139 }
140
141 id = (ret & 0xfe) >> 2;
142 rev = ret & 0x3;
143 for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
144 if (id == gf_mods[i].id)
145 break;
146
147 if (i < ARRAY_SIZE(gf_mods)) {
148 dev_info(&i2c->dev, "%s revision %d\n",
149 gf_mods[i].name, rev + 1);
150 for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
151 if (!i2c_new_device(i2c->adapter,
152 &(gf_mods[i].i2c_devs[j])))
153 dev_err(&i2c->dev,
154 "Failed to register dev: %d\n", ret);
155 }
156 } else {
157 dev_warn(&i2c->dev, "Unknown module ID %d revision %d\n",
158 id, rev);
159 }
160
161 return 0;
162}
163
164static const struct i2c_device_id wlf_gf_module_id[] = {
165 { "wlf-gf-module", 0 },
166 { }
167};
168
169static struct i2c_driver wlf_gf_module_driver = {
170 .driver = {
171 .name = "wlf-gf-module",
172 .owner = THIS_MODULE,
173 },
174 .probe = wlf_gf_module_probe,
175 .id_table = wlf_gf_module_id,
176};
177
178static int __init wlf_gf_module_register(void)
179{
180 return i2c_add_driver(&wlf_gf_module_driver);
181}
182module_init(wlf_gf_module_register);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 806580388f30..d04b65448510 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -43,13 +43,14 @@
43#include <mach/hardware.h> 43#include <mach/hardware.h>
44#include <mach/map.h> 44#include <mach/map.h>
45 45
46#include <mach/s3c6410.h>
47#include <mach/regs-sys.h> 46#include <mach/regs-sys.h>
48#include <mach/regs-gpio.h> 47#include <mach/regs-gpio.h>
49#include <mach/regs-modem.h> 48#include <mach/regs-modem.h>
49#include <mach/crag6410.h>
50 50
51#include <mach/regs-gpio-memport.h> 51#include <mach/regs-gpio-memport.h>
52 52
53#include <plat/s3c6410.h>
53#include <plat/regs-serial.h> 54#include <plat/regs-serial.h>
54#include <plat/regs-fb-v4.h> 55#include <plat/regs-fb-v4.h>
55#include <plat/fb.h> 56#include <plat/fb.h>
@@ -65,17 +66,6 @@
65#include <plat/iic.h> 66#include <plat/iic.h>
66#include <plat/pm.h> 67#include <plat/pm.h>
67 68
68#include <sound/wm8996.h>
69#include <sound/wm8962.h>
70#include <sound/wm9081.h>
71
72#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START
73#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
74
75#define PCA935X_GPIO_BASE GPIO_BOARD_START
76#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
77#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16)
78
79/* serial port setup */ 69/* serial port setup */
80 70
81#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) 71#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
@@ -287,6 +277,11 @@ static struct platform_device speyside_device = {
287 .id = -1, 277 .id = -1,
288}; 278};
289 279
280static struct platform_device lowland_device = {
281 .name = "lowland",
282 .id = -1,
283};
284
290static struct platform_device speyside_wm8962_device = { 285static struct platform_device speyside_wm8962_device = {
291 .name = "speyside-wm8962", 286 .name = "speyside-wm8962",
292 .id = -1, 287 .id = -1,
@@ -295,6 +290,8 @@ static struct platform_device speyside_wm8962_device = {
295static struct regulator_consumer_supply wallvdd_consumers[] = { 290static struct regulator_consumer_supply wallvdd_consumers[] = {
296 REGULATOR_SUPPLY("SPKVDD1", "1-001a"), 291 REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
297 REGULATOR_SUPPLY("SPKVDD2", "1-001a"), 292 REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
293 REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
294 REGULATOR_SUPPLY("SPKVDDR", "1-001a"),
298}; 295};
299 296
300static struct regulator_init_data wallvdd_data = { 297static struct regulator_init_data wallvdd_data = {
@@ -342,6 +339,7 @@ static struct platform_device *crag6410_devices[] __initdata = {
342 &crag6410_backlight_device, 339 &crag6410_backlight_device,
343 &speyside_device, 340 &speyside_device,
344 &speyside_wm8962_device, 341 &speyside_wm8962_device,
342 &lowland_device,
345 &wallvdd_device, 343 &wallvdd_device,
346}; 344};
347 345
@@ -350,6 +348,12 @@ static struct pca953x_platform_data crag6410_pca_data = {
350 .irq_base = 0, 348 .irq_base = 0,
351}; 349};
352 350
351/* VDDARM is controlled by DVS1 connected to GPK(0) */
352static struct wm831x_buckv_pdata vddarm_pdata = {
353 .dvs_control_src = 1,
354 .dvs_gpio = S3C64XX_GPK(0),
355};
356
353static struct regulator_consumer_supply vddarm_consumers[] __initdata = { 357static struct regulator_consumer_supply vddarm_consumers[] __initdata = {
354 REGULATOR_SUPPLY("vddarm", NULL), 358 REGULATOR_SUPPLY("vddarm", NULL),
355}; 359};
@@ -365,6 +369,7 @@ static struct regulator_init_data vddarm __initdata = {
365 .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers), 369 .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers),
366 .consumer_supplies = vddarm_consumers, 370 .consumer_supplies = vddarm_consumers,
367 .supply_regulator = "WALLVDD", 371 .supply_regulator = "WALLVDD",
372 .driver_data = &vddarm_pdata,
368}; 373};
369 374
370static struct regulator_init_data vddint __initdata = { 375static struct regulator_init_data vddint __initdata = {
@@ -500,6 +505,8 @@ static struct wm831x_pdata crag_pmic_pdata __initdata = {
500 .backup = &banff_backup_pdata, 505 .backup = &banff_backup_pdata,
501 506
502 .gpio_defaults = { 507 .gpio_defaults = {
508 /* GPIO5: DVS1_REQ - CMOS, DBVDD, active high */
509 [4] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA | 0x8,
503 /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/ 510 /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
504 [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6, 511 [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
505 /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/ 512 /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
@@ -557,8 +564,12 @@ static struct regulator_init_data pvdd_1v2 __initdata = {
557}; 564};
558 565
559static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { 566static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
567 REGULATOR_SUPPLY("LDOVDD", "1-001a"),
560 REGULATOR_SUPPLY("PLLVDD", "1-001a"), 568 REGULATOR_SUPPLY("PLLVDD", "1-001a"),
561 REGULATOR_SUPPLY("DBVDD", "1-001a"), 569 REGULATOR_SUPPLY("DBVDD", "1-001a"),
570 REGULATOR_SUPPLY("DBVDD1", "1-001a"),
571 REGULATOR_SUPPLY("DBVDD2", "1-001a"),
572 REGULATOR_SUPPLY("DBVDD3", "1-001a"),
562 REGULATOR_SUPPLY("CPVDD", "1-001a"), 573 REGULATOR_SUPPLY("CPVDD", "1-001a"),
563 REGULATOR_SUPPLY("AVDD2", "1-001a"), 574 REGULATOR_SUPPLY("AVDD2", "1-001a"),
564 REGULATOR_SUPPLY("DCVDD", "1-001a"), 575 REGULATOR_SUPPLY("DCVDD", "1-001a"),
@@ -611,81 +622,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
611 .disable_touch = true, 622 .disable_touch = true,
612}; 623};
613 624
614static struct wm8996_retune_mobile_config wm8996_retune[] = {
615 {
616 .name = "Sub LPF",
617 .rate = 48000,
618 .regs = {
619 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
620 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
621 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
622 },
623 },
624 {
625 .name = "Sub HPF",
626 .rate = 48000,
627 .regs = {
628 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
629 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
630 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
631 },
632 },
633};
634
635static struct wm8996_pdata wm8996_pdata __initdata = {
636 .ldo_ena = S3C64XX_GPN(7),
637 .gpio_base = CODEC_GPIO_BASE,
638 .micdet_def = 1,
639 .inl_mode = WM8996_DIFFERRENTIAL_1,
640 .inr_mode = WM8996_DIFFERRENTIAL_1,
641
642 .irq_flags = IRQF_TRIGGER_RISING,
643
644 .gpio_default = {
645 0x8001, /* GPIO1 == ADCLRCLK1 */
646 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
647 0x0141, /* GPIO3 == HP_SEL */
648 0x0002, /* GPIO4 == IRQ */
649 0x020e, /* GPIO5 == CLKOUT */
650 },
651
652 .retune_mobile_cfgs = wm8996_retune,
653 .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
654};
655
656static struct wm8962_pdata wm8962_pdata __initdata = {
657 .gpio_init = {
658 0,
659 WM8962_GPIO_FN_OPCLK,
660 WM8962_GPIO_FN_DMICCLK,
661 0,
662 0x8000 | WM8962_GPIO_FN_DMICDAT,
663 WM8962_GPIO_FN_IRQ, /* Open drain mode */
664 },
665 .irq_active_low = true,
666};
667
668static struct wm9081_pdata wm9081_pdata __initdata = {
669 .irq_high = false,
670 .irq_cmos = false,
671};
672
673static struct i2c_board_info i2c_devs1[] __initdata = { 625static struct i2c_board_info i2c_devs1[] __initdata = {
674 { I2C_BOARD_INFO("wm8311", 0x34), 626 { I2C_BOARD_INFO("wm8311", 0x34),
675 .irq = S3C_EINT(0), 627 .irq = S3C_EINT(0),
676 .platform_data = &glenfarclas_pmic_pdata }, 628 .platform_data = &glenfarclas_pmic_pdata },
677 629
630 { I2C_BOARD_INFO("wlf-gf-module", 0x24) },
631 { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
632 { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
633
678 { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, 634 { I2C_BOARD_INFO("wm1250-ev1", 0x27) },
679 { I2C_BOARD_INFO("wm8996", 0x1a),
680 .platform_data = &wm8996_pdata,
681 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
682 },
683 { I2C_BOARD_INFO("wm9081", 0x6c),
684 .platform_data = &wm9081_pdata, },
685 { I2C_BOARD_INFO("wm8962", 0x1a),
686 .platform_data = &wm8962_pdata,
687 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
688 },
689}; 635};
690 636
691static void __init crag6410_map_io(void) 637static void __init crag6410_map_io(void)
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 19a0887e1c1e..952f75ff5deb 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -37,7 +37,7 @@
37#include <plat/fb.h> 37#include <plat/fb.h>
38#include <plat/nand.h> 38#include <plat/nand.h>
39 39
40#include <mach/s3c6410.h> 40#include <plat/s3c6410.h>
41#include <plat/clock.h> 41#include <plat/clock.h>
42#include <plat/devs.h> 42#include <plat/devs.h>
43#include <plat/cpu.h> 43#include <plat/cpu.h>
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index fb8969aa412e..1bc85c359498 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -32,8 +32,8 @@
32#include <mach/regs-gpio.h> 32#include <mach/regs-gpio.h>
33#include <mach/regs-modem.h> 33#include <mach/regs-modem.h>
34#include <mach/regs-srom.h> 34#include <mach/regs-srom.h>
35#include <mach/s3c6410.h>
36 35
36#include <plat/s3c6410.h>
37#include <plat/adc.h> 37#include <plat/adc.h>
38#include <plat/cpu.h> 38#include <plat/cpu.h>
39#include <plat/devs.h> 39#include <plat/devs.h>
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index c30f2e5e0d85..cb13cba98b3d 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -39,7 +39,7 @@
39#include <plat/iic.h> 39#include <plat/iic.h>
40#include <plat/fb.h> 40#include <plat/fb.h>
41 41
42#include <mach/s3c6410.h> 42#include <plat/s3c6410.h>
43#include <plat/clock.h> 43#include <plat/clock.h>
44#include <plat/devs.h> 44#include <plat/devs.h>
45#include <plat/cpu.h> 45#include <plat/cpu.h>
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 93170d4834e7..87281e4b8471 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -33,8 +33,8 @@
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-modem.h> 34#include <mach/regs-modem.h>
35#include <mach/regs-srom.h> 35#include <mach/regs-srom.h>
36#include <mach/s3c6410.h>
37 36
37#include <plat/s3c6410.h>
38#include <plat/adc.h> 38#include <plat/adc.h>
39#include <plat/cpu.h> 39#include <plat/cpu.h>
40#include <plat/devs.h> 40#include <plat/devs.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index cbb57ded3d95..94c831d88365 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -22,8 +22,8 @@
22 22
23#include <mach/map.h> 23#include <mach/map.h>
24#include <mach/regs-gpio.h> 24#include <mach/regs-gpio.h>
25#include <mach/s3c6410.h>
26 25
26#include <plat/s3c6410.h>
27#include <plat/cpu.h> 27#include <plat/cpu.h>
28#include <plat/devs.h> 28#include <plat/devs.h>
29#include <plat/fb.h> 29#include <plat/fb.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index 04f914b85fdf..f112547ce80a 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -22,8 +22,8 @@
22 22
23#include <mach/map.h> 23#include <mach/map.h>
24#include <mach/regs-gpio.h> 24#include <mach/regs-gpio.h>
25#include <mach/s3c6410.h>
26 25
26#include <plat/s3c6410.h>
27#include <plat/cpu.h> 27#include <plat/cpu.h>
28#include <plat/devs.h> 28#include <plat/devs.h>
29#include <plat/fb.h> 29#include <plat/fb.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index 6fd5e95f8f75..73450c2b530a 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -31,7 +31,7 @@
31 31
32#include <plat/regs-serial.h> 32#include <plat/regs-serial.h>
33 33
34#include <mach/s3c6400.h> 34#include <plat/s3c6400.h>
35#include <plat/clock.h> 35#include <plat/clock.h>
36#include <plat/devs.h> 36#include <plat/devs.h>
37#include <plat/cpu.h> 37#include <plat/cpu.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 5f147c33edad..8bc8edd85e5a 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -63,7 +63,7 @@
63#include <plat/fb.h> 63#include <plat/fb.h>
64#include <plat/gpio-cfg.h> 64#include <plat/gpio-cfg.h>
65 65
66#include <mach/s3c6410.h> 66#include <plat/s3c6410.h>
67#include <plat/clock.h> 67#include <plat/clock.h>
68#include <plat/devs.h> 68#include <plat/devs.h>
69#include <plat/cpu.h> 69#include <plat/cpu.h>
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 055e2858b0dd..b375cd5c47cb 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -29,6 +29,7 @@
29#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
30#include <mach/regs-syscon-power.h> 30#include <mach/regs-syscon-power.h>
31#include <mach/regs-gpio-memport.h> 31#include <mach/regs-gpio-memport.h>
32#include <mach/regs-modem.h>
32 33
33#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK 34#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
34void s3c_pm_debug_smdkled(u32 set, u32 clear) 35void s3c_pm_debug_smdkled(u32 set, u32 clear)
@@ -85,6 +86,9 @@ static struct sleep_save misc_save[] = {
85 SAVE_ITEM(S3C64XX_MEM0CONSLP0), 86 SAVE_ITEM(S3C64XX_MEM0CONSLP0),
86 SAVE_ITEM(S3C64XX_MEM0CONSLP1), 87 SAVE_ITEM(S3C64XX_MEM0CONSLP1),
87 SAVE_ITEM(S3C64XX_MEM1CONSLP), 88 SAVE_ITEM(S3C64XX_MEM1CONSLP),
89
90 SAVE_ITEM(S3C64XX_SDMA_SEL),
91 SAVE_ITEM(S3C64XX_MODEM_MIFPCON),
88}; 92};
89 93
90void s3c_pm_configure_extint(void) 94void s3c_pm_configure_extint(void)
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
index 5e93fe3f3f40..7a3bc32df425 100644
--- a/arch/arm/mach-s3c64xx/s3c6400.c
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -38,7 +38,7 @@
38#include <plat/sdhci.h> 38#include <plat/sdhci.h>
39#include <plat/iic-core.h> 39#include <plat/iic-core.h>
40#include <plat/onenand-core.h> 40#include <plat/onenand-core.h>
41#include <mach/s3c6400.h> 41#include <plat/s3c6400.h>
42 42
43void __init s3c6400_map_io(void) 43void __init s3c6400_map_io(void)
44{ 44{
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
index 312aa6b115e8..4117003464ad 100644
--- a/arch/arm/mach-s3c64xx/s3c6410.c
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -41,8 +41,8 @@
41#include <plat/adc-core.h> 41#include <plat/adc-core.h>
42#include <plat/iic-core.h> 42#include <plat/iic-core.h>
43#include <plat/onenand-core.h> 43#include <plat/onenand-core.h>
44#include <mach/s3c6400.h> 44#include <plat/s3c6400.h>
45#include <mach/s3c6410.h> 45#include <plat/s3c6410.h>
46 46
47void __init s3c6410_map_io(void) 47void __init s3c6410_map_io(void)
48{ 48{
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c
index f344a222bc84..c75a71b21165 100644
--- a/arch/arm/mach-s3c64xx/setup-sdhci.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci.c
@@ -12,17 +12,7 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13*/ 13*/
14 14
15#include <linux/kernel.h>
16#include <linux/types.h> 15#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20
21#include <linux/mmc/card.h>
22#include <linux/mmc/host.h>
23
24#include <plat/regs-sdhci.h>
25#include <plat/sdhci.h>
26 16
27/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ 17/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
28 18
@@ -32,41 +22,3 @@ char *s3c64xx_hsmmc_clksrcs[4] = {
32 [2] = "mmc_bus", 22 [2] = "mmc_bus",
33 /* [3] = "48m", - note not successfully used yet */ 23 /* [3] = "48m", - note not successfully used yet */
34}; 24};
35
36void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
37 void __iomem *r,
38 struct mmc_ios *ios,
39 struct mmc_card *card)
40{
41 u32 ctrl2, ctrl3;
42
43 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
46 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
47 S3C_SDHCI_CTRL2_ENFBCLKRX |
48 S3C_SDHCI_CTRL2_DFCNT_NONE |
49 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
50
51 if (ios->clock < 25 * 1000000)
52 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
53 S3C_SDHCI_CTRL3_FCSEL2 |
54 S3C_SDHCI_CTRL3_FCSEL1 |
55 S3C_SDHCI_CTRL3_FCSEL0);
56 else
57 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
58
59 pr_debug("%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
60 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
61 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
62}
63
64void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
65 void __iomem *r,
66 struct mmc_ios *ios,
67 struct mmc_card *card)
68{
69 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
70
71 s3c6400_setup_sdhci_cfg_card(dev, r, ios, card);
72}
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 65c7518dad7f..18690c5f99e6 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -9,18 +9,28 @@ if ARCH_S5P64X0
9 9
10config CPU_S5P6440 10config CPU_S5P6440
11 bool 11 bool
12 select S3C_PL330_DMA 12 select SAMSUNG_DMADEV
13 select S5P_HRT 13 select S5P_HRT
14 select S5P_SLEEP if PM
15 select SAMSUNG_WAKEMASK if PM
14 help 16 help
15 Enable S5P6440 CPU support 17 Enable S5P6440 CPU support
16 18
17config CPU_S5P6450 19config CPU_S5P6450
18 bool 20 bool
19 select S3C_PL330_DMA 21 select SAMSUNG_DMADEV
20 select S5P_HRT 22 select S5P_HRT
23 select S5P_SLEEP if PM
24 select SAMSUNG_WAKEMASK if PM
21 help 25 help
22 Enable S5P6450 CPU support 26 Enable S5P6450 CPU support
23 27
28config S5P64X0_SETUP_FB_24BPP
29 bool
30 help
31 Common setup code for S5P64X0 based boards with a LCD display
32 through RGB interface.
33
24config S5P64X0_SETUP_I2C1 34config S5P64X0_SETUP_I2C1
25 bool 35 bool
26 help 36 help
@@ -31,6 +41,7 @@ config S5P64X0_SETUP_I2C1
31config MACH_SMDK6440 41config MACH_SMDK6440
32 bool "SMDK6440" 42 bool "SMDK6440"
33 select CPU_S5P6440 43 select CPU_S5P6440
44 select S3C_DEV_FB
34 select S3C_DEV_I2C1 45 select S3C_DEV_I2C1
35 select S3C_DEV_RTC 46 select S3C_DEV_RTC
36 select S3C_DEV_WDT 47 select S3C_DEV_WDT
@@ -39,6 +50,7 @@ config MACH_SMDK6440
39 select SAMSUNG_DEV_BACKLIGHT 50 select SAMSUNG_DEV_BACKLIGHT
40 select SAMSUNG_DEV_PWM 51 select SAMSUNG_DEV_PWM
41 select SAMSUNG_DEV_TS 52 select SAMSUNG_DEV_TS
53 select S5P64X0_SETUP_FB_24BPP
42 select S5P64X0_SETUP_I2C1 54 select S5P64X0_SETUP_I2C1
43 help 55 help
44 Machine support for the Samsung SMDK6440 56 Machine support for the Samsung SMDK6440
@@ -46,6 +58,7 @@ config MACH_SMDK6440
46config MACH_SMDK6450 58config MACH_SMDK6450
47 bool "SMDK6450" 59 bool "SMDK6450"
48 select CPU_S5P6450 60 select CPU_S5P6450
61 select S3C_DEV_FB
49 select S3C_DEV_I2C1 62 select S3C_DEV_I2C1
50 select S3C_DEV_RTC 63 select S3C_DEV_RTC
51 select S3C_DEV_WDT 64 select S3C_DEV_WDT
@@ -54,6 +67,7 @@ config MACH_SMDK6450
54 select SAMSUNG_DEV_BACKLIGHT 67 select SAMSUNG_DEV_BACKLIGHT
55 select SAMSUNG_DEV_PWM 68 select SAMSUNG_DEV_PWM
56 select SAMSUNG_DEV_TS 69 select SAMSUNG_DEV_TS
70 select S5P64X0_SETUP_FB_24BPP
57 select S5P64X0_SETUP_I2C1 71 select S5P64X0_SETUP_I2C1
58 help 72 help
59 Machine support for the Samsung SMDK6450 73 Machine support for the Samsung SMDK6450
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index 5f6afdf067ed..a1324d8dc4e0 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -12,10 +12,11 @@ obj- :=
12 12
13# Core support for S5P64X0 system 13# Core support for S5P64X0 system
14 14
15obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o 15obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
16obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o 16obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o
17obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o 17obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
18obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o 18obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
19obj-$(CONFIG_PM) += pm.o irq-pm.o
19 20
20# machine support 21# machine support
21 22
@@ -28,3 +29,4 @@ obj-y += dev-audio.o
28obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o 29obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
29 30
30obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o 31obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
32obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 0e9cd3092dd2..c54c65d511f0 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -146,7 +146,8 @@ static struct clk init_clocks_off[] = {
146 .enable = s5p64x0_hclk0_ctrl, 146 .enable = s5p64x0_hclk0_ctrl,
147 .ctrlbit = (1 << 8), 147 .ctrlbit = (1 << 8),
148 }, { 148 }, {
149 .name = "pdma", 149 .name = "dma",
150 .devname = "dma-pl330",
150 .parent = &clk_hclk_low.clk, 151 .parent = &clk_hclk_low.clk,
151 .enable = s5p64x0_hclk0_ctrl, 152 .enable = s5p64x0_hclk0_ctrl,
152 .ctrlbit = (1 << 12), 153 .ctrlbit = (1 << 12),
@@ -499,6 +500,11 @@ static struct clksrc_clk *sysclks[] = {
499 &clk_pclk_low, 500 &clk_pclk_low,
500}; 501};
501 502
503static struct clk dummy_apb_pclk = {
504 .name = "apb_pclk",
505 .id = -1,
506};
507
502void __init_or_cpufreq s5p6440_setup_clocks(void) 508void __init_or_cpufreq s5p6440_setup_clocks(void)
503{ 509{
504 struct clk *xtal_clk; 510 struct clk *xtal_clk;
@@ -581,5 +587,7 @@ void __init s5p6440_register_clocks(void)
581 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 587 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
582 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 588 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
583 589
590 s3c24xx_register_clock(&dummy_apb_pclk);
591
584 s3c_pwmclk_init(); 592 s3c_pwmclk_init();
585} 593}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index d9dc16cde109..2d04abfba12e 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -179,7 +179,8 @@ static struct clk init_clocks_off[] = {
179 .enable = s5p64x0_hclk0_ctrl, 179 .enable = s5p64x0_hclk0_ctrl,
180 .ctrlbit = (1 << 3), 180 .ctrlbit = (1 << 3),
181 }, { 181 }, {
182 .name = "pdma", 182 .name = "dma",
183 .devname = "dma-pl330",
183 .parent = &clk_hclk_low.clk, 184 .parent = &clk_hclk_low.clk,
184 .enable = s5p64x0_hclk0_ctrl, 185 .enable = s5p64x0_hclk0_ctrl,
185 .ctrlbit = (1 << 12), 186 .ctrlbit = (1 << 12),
@@ -553,6 +554,11 @@ static struct clksrc_clk *sysclks[] = {
553 &clk_sclk_audio0, 554 &clk_sclk_audio0,
554}; 555};
555 556
557static struct clk dummy_apb_pclk = {
558 .name = "apb_pclk",
559 .id = -1,
560};
561
556void __init_or_cpufreq s5p6450_setup_clocks(void) 562void __init_or_cpufreq s5p6450_setup_clocks(void)
557{ 563{
558 struct clk *xtal_clk; 564 struct clk *xtal_clk;
@@ -632,5 +638,7 @@ void __init s5p6450_register_clocks(void)
632 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 638 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
633 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 639 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
634 640
641 s3c24xx_register_clock(&dummy_apb_pclk);
642
635 s3c_pwmclk_init(); 643 s3c_pwmclk_init();
636} 644}
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
index 8a938542c54d..ecab40cf19ab 100644
--- a/arch/arm/mach-s5p64x0/cpu.c
+++ b/arch/arm/mach-s5p64x0/cpu.c
@@ -39,6 +39,7 @@
39#include <plat/s5p6440.h> 39#include <plat/s5p6440.h>
40#include <plat/s5p6450.h> 40#include <plat/s5p6450.h>
41#include <plat/adc-core.h> 41#include <plat/adc-core.h>
42#include <plat/fb-core.h>
42 43
43/* Initial IO mappings */ 44/* Initial IO mappings */
44 45
@@ -109,6 +110,7 @@ void __init s5p6440_map_io(void)
109{ 110{
110 /* initialize any device information early */ 111 /* initialize any device information early */
111 s3c_adc_setname("s3c64xx-adc"); 112 s3c_adc_setname("s3c64xx-adc");
113 s3c_fb_setname("s5p64x0-fb");
112 114
113 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); 115 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
114 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); 116 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
@@ -119,6 +121,7 @@ void __init s5p6450_map_io(void)
119{ 121{
120 /* initialize any device information early */ 122 /* initialize any device information early */
121 s3c_adc_setname("s3c64xx-adc"); 123 s3c_adc_setname("s3c64xx-adc");
124 s3c_fb_setname("s5p64x0-fb");
122 125
123 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); 126 iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
124 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc)); 127 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 0e5b3e63e5b3..442dd4ad12da 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -21,115 +21,208 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/ 22*/
23 23
24#include <linux/platform_device.h>
25#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h>
27
28#include <asm/irq.h>
26 29
27#include <mach/map.h> 30#include <mach/map.h>
28#include <mach/irqs.h> 31#include <mach/irqs.h>
29#include <mach/regs-clock.h> 32#include <mach/regs-clock.h>
33#include <mach/dma.h>
30 34
31#include <plat/cpu.h> 35#include <plat/cpu.h>
32#include <plat/devs.h> 36#include <plat/devs.h>
33#include <plat/s3c-pl330-pdata.h> 37#include <plat/irqs.h>
34 38
35static u64 dma_dmamask = DMA_BIT_MASK(32); 39static u64 dma_dmamask = DMA_BIT_MASK(32);
36 40
37static struct resource s5p64x0_pdma_resource[] = { 41struct dma_pl330_peri s5p6440_pdma_peri[22] = {
38 [0] = { 42 {
39 .start = S5P64X0_PA_PDMA, 43 .peri_id = (u8)DMACH_UART0_RX,
40 .end = S5P64X0_PA_PDMA + SZ_4K, 44 .rqtype = DEVTOMEM,
41 .flags = IORESOURCE_MEM, 45 }, {
42 }, 46 .peri_id = (u8)DMACH_UART0_TX,
43 [1] = { 47 .rqtype = MEMTODEV,
44 .start = IRQ_DMA0, 48 }, {
45 .end = IRQ_DMA0, 49 .peri_id = (u8)DMACH_UART1_RX,
46 .flags = IORESOURCE_IRQ, 50 .rqtype = DEVTOMEM,
51 }, {
52 .peri_id = (u8)DMACH_UART1_TX,
53 .rqtype = MEMTODEV,
54 }, {
55 .peri_id = (u8)DMACH_UART2_RX,
56 .rqtype = DEVTOMEM,
57 }, {
58 .peri_id = (u8)DMACH_UART2_TX,
59 .rqtype = MEMTODEV,
60 }, {
61 .peri_id = (u8)DMACH_UART3_RX,
62 .rqtype = DEVTOMEM,
63 }, {
64 .peri_id = (u8)DMACH_UART3_TX,
65 .rqtype = MEMTODEV,
66 }, {
67 .peri_id = DMACH_MAX,
68 }, {
69 .peri_id = DMACH_MAX,
70 }, {
71 .peri_id = (u8)DMACH_PCM0_TX,
72 .rqtype = MEMTODEV,
73 }, {
74 .peri_id = (u8)DMACH_PCM0_RX,
75 .rqtype = DEVTOMEM,
76 }, {
77 .peri_id = (u8)DMACH_I2S0_TX,
78 .rqtype = MEMTODEV,
79 }, {
80 .peri_id = (u8)DMACH_I2S0_RX,
81 .rqtype = DEVTOMEM,
82 }, {
83 .peri_id = (u8)DMACH_SPI0_TX,
84 .rqtype = MEMTODEV,
85 }, {
86 .peri_id = (u8)DMACH_SPI0_RX,
87 .rqtype = DEVTOMEM,
88 }, {
89 .peri_id = (u8)DMACH_MAX,
90 }, {
91 .peri_id = (u8)DMACH_MAX,
92 }, {
93 .peri_id = (u8)DMACH_MAX,
94 }, {
95 .peri_id = (u8)DMACH_MAX,
96 }, {
97 .peri_id = (u8)DMACH_SPI1_TX,
98 .rqtype = MEMTODEV,
99 }, {
100 .peri_id = (u8)DMACH_SPI1_RX,
101 .rqtype = DEVTOMEM,
47 }, 102 },
48}; 103};
49 104
50static struct s3c_pl330_platdata s5p6440_pdma_pdata = { 105struct dma_pl330_platdata s5p6440_pdma_pdata = {
51 .peri = { 106 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
52 [0] = DMACH_UART0_RX, 107 .peri = s5p6440_pdma_peri,
53 [1] = DMACH_UART0_TX,
54 [2] = DMACH_UART1_RX,
55 [3] = DMACH_UART1_TX,
56 [4] = DMACH_UART2_RX,
57 [5] = DMACH_UART2_TX,
58 [6] = DMACH_UART3_RX,
59 [7] = DMACH_UART3_TX,
60 [8] = DMACH_MAX,
61 [9] = DMACH_MAX,
62 [10] = DMACH_PCM0_TX,
63 [11] = DMACH_PCM0_RX,
64 [12] = DMACH_I2S0_TX,
65 [13] = DMACH_I2S0_RX,
66 [14] = DMACH_SPI0_TX,
67 [15] = DMACH_SPI0_RX,
68 [16] = DMACH_MAX,
69 [17] = DMACH_MAX,
70 [18] = DMACH_MAX,
71 [19] = DMACH_MAX,
72 [20] = DMACH_SPI1_TX,
73 [21] = DMACH_SPI1_RX,
74 [22] = DMACH_MAX,
75 [23] = DMACH_MAX,
76 [24] = DMACH_MAX,
77 [25] = DMACH_MAX,
78 [26] = DMACH_MAX,
79 [27] = DMACH_MAX,
80 [28] = DMACH_MAX,
81 [29] = DMACH_PWM,
82 [30] = DMACH_MAX,
83 [31] = DMACH_MAX,
84 },
85}; 108};
86 109
87static struct s3c_pl330_platdata s5p6450_pdma_pdata = { 110struct dma_pl330_peri s5p6450_pdma_peri[32] = {
88 .peri = { 111 {
89 [0] = DMACH_UART0_RX, 112 .peri_id = (u8)DMACH_UART0_RX,
90 [1] = DMACH_UART0_TX, 113 .rqtype = DEVTOMEM,
91 [2] = DMACH_UART1_RX, 114 }, {
92 [3] = DMACH_UART1_TX, 115 .peri_id = (u8)DMACH_UART0_TX,
93 [4] = DMACH_UART2_RX, 116 .rqtype = MEMTODEV,
94 [5] = DMACH_UART2_TX, 117 }, {
95 [6] = DMACH_UART3_RX, 118 .peri_id = (u8)DMACH_UART1_RX,
96 [7] = DMACH_UART3_TX, 119 .rqtype = DEVTOMEM,
97 [8] = DMACH_UART4_RX, 120 }, {
98 [9] = DMACH_UART4_TX, 121 .peri_id = (u8)DMACH_UART1_TX,
99 [10] = DMACH_PCM0_TX, 122 .rqtype = MEMTODEV,
100 [11] = DMACH_PCM0_RX, 123 }, {
101 [12] = DMACH_I2S0_TX, 124 .peri_id = (u8)DMACH_UART2_RX,
102 [13] = DMACH_I2S0_RX, 125 .rqtype = DEVTOMEM,
103 [14] = DMACH_SPI0_TX, 126 }, {
104 [15] = DMACH_SPI0_RX, 127 .peri_id = (u8)DMACH_UART2_TX,
105 [16] = DMACH_PCM1_TX, 128 .rqtype = MEMTODEV,
106 [17] = DMACH_PCM1_RX, 129 }, {
107 [18] = DMACH_PCM2_TX, 130 .peri_id = (u8)DMACH_UART3_RX,
108 [19] = DMACH_PCM2_RX, 131 .rqtype = DEVTOMEM,
109 [20] = DMACH_SPI1_TX, 132 }, {
110 [21] = DMACH_SPI1_RX, 133 .peri_id = (u8)DMACH_UART3_TX,
111 [22] = DMACH_USI_TX, 134 .rqtype = MEMTODEV,
112 [23] = DMACH_USI_RX, 135 }, {
113 [24] = DMACH_MAX, 136 .peri_id = (u8)DMACH_UART4_RX,
114 [25] = DMACH_I2S1_TX, 137 .rqtype = DEVTOMEM,
115 [26] = DMACH_I2S1_RX, 138 }, {
116 [27] = DMACH_I2S2_TX, 139 .peri_id = (u8)DMACH_UART4_TX,
117 [28] = DMACH_I2S2_RX, 140 .rqtype = MEMTODEV,
118 [29] = DMACH_PWM, 141 }, {
119 [30] = DMACH_UART5_RX, 142 .peri_id = (u8)DMACH_PCM0_TX,
120 [31] = DMACH_UART5_TX, 143 .rqtype = MEMTODEV,
144 }, {
145 .peri_id = (u8)DMACH_PCM0_RX,
146 .rqtype = DEVTOMEM,
147 }, {
148 .peri_id = (u8)DMACH_I2S0_TX,
149 .rqtype = MEMTODEV,
150 }, {
151 .peri_id = (u8)DMACH_I2S0_RX,
152 .rqtype = DEVTOMEM,
153 }, {
154 .peri_id = (u8)DMACH_SPI0_TX,
155 .rqtype = MEMTODEV,
156 }, {
157 .peri_id = (u8)DMACH_SPI0_RX,
158 .rqtype = DEVTOMEM,
159 }, {
160 .peri_id = (u8)DMACH_PCM1_TX,
161 .rqtype = MEMTODEV,
162 }, {
163 .peri_id = (u8)DMACH_PCM1_RX,
164 .rqtype = DEVTOMEM,
165 }, {
166 .peri_id = (u8)DMACH_PCM2_TX,
167 .rqtype = MEMTODEV,
168 }, {
169 .peri_id = (u8)DMACH_PCM2_RX,
170 .rqtype = DEVTOMEM,
171 }, {
172 .peri_id = (u8)DMACH_SPI1_TX,
173 .rqtype = MEMTODEV,
174 }, {
175 .peri_id = (u8)DMACH_SPI1_RX,
176 .rqtype = DEVTOMEM,
177 }, {
178 .peri_id = (u8)DMACH_USI_TX,
179 .rqtype = MEMTODEV,
180 }, {
181 .peri_id = (u8)DMACH_USI_RX,
182 .rqtype = DEVTOMEM,
183 }, {
184 .peri_id = (u8)DMACH_MAX,
185 }, {
186 .peri_id = (u8)DMACH_I2S1_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_I2S1_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_I2S2_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_I2S2_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_PWM,
199 }, {
200 .peri_id = (u8)DMACH_UART5_RX,
201 .rqtype = DEVTOMEM,
202 }, {
203 .peri_id = (u8)DMACH_UART5_TX,
204 .rqtype = MEMTODEV,
121 }, 205 },
122}; 206};
123 207
124static struct platform_device s5p64x0_device_pdma = { 208struct dma_pl330_platdata s5p6450_pdma_pdata = {
125 .name = "s3c-pl330", 209 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
126 .id = -1, 210 .peri = s5p6450_pdma_peri,
127 .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource), 211};
128 .resource = s5p64x0_pdma_resource, 212
129 .dev = { 213struct amba_device s5p64x0_device_pdma = {
214 .dev = {
215 .init_name = "dma-pl330",
130 .dma_mask = &dma_dmamask, 216 .dma_mask = &dma_dmamask,
131 .coherent_dma_mask = DMA_BIT_MASK(32), 217 .coherent_dma_mask = DMA_BIT_MASK(32),
132 }, 218 },
219 .res = {
220 .start = S5P64X0_PA_PDMA,
221 .end = S5P64X0_PA_PDMA + SZ_4K,
222 .flags = IORESOURCE_MEM,
223 },
224 .irq = {IRQ_DMA0, NO_IRQ},
225 .periphid = 0x00041330,
133}; 226};
134 227
135static int __init s5p64x0_dma_init(void) 228static int __init s5p64x0_dma_init(void)
@@ -139,7 +232,7 @@ static int __init s5p64x0_dma_init(void)
139 else 232 else
140 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; 233 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
141 234
142 platform_device_register(&s5p64x0_device_pdma); 235 amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
143 236
144 return 0; 237 return 0;
145} 238}
diff --git a/arch/arm/mach-s5p64x0/include/mach/clkdev.h b/arch/arm/mach-s5p64x0/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/mach-s5p64x0/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h
index 81209eb1409b..5a622af461d7 100644
--- a/arch/arm/mach-s5p64x0/include/mach/dma.h
+++ b/arch/arm/mach-s5p64x0/include/mach/dma.h
@@ -20,7 +20,7 @@
20#ifndef __MACH_DMA_H 20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H 21#define __MACH_DMA_H
22 22
23/* This platform uses the common S3C DMA API driver for PL330 */ 23/* This platform uses the common common DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h> 24#include <plat/dma-pl330.h>
25 25
26#endif /* __MACH_DMA_H */ 26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 5837a36ece8d..53982db9d259 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -87,6 +87,10 @@
87 87
88#define IRQ_I2S0 IRQ_I2SV40 88#define IRQ_I2S0 IRQ_I2SV40
89 89
90#define IRQ_LCD_FIFO IRQ_DISPCON0
91#define IRQ_LCD_VSYNC IRQ_DISPCON1
92#define IRQ_LCD_SYSTEM IRQ_DISPCON2
93
90/* S5P6450 EINT feature will be added */ 94/* S5P6450 EINT feature will be added */
91 95
92/* 96/*
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 95c91257c7ca..4d3ac8a3709d 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -47,6 +47,8 @@
47 47
48#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) 48#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
49 49
50#define S5P64X0_PA_FB 0xEE000000
51
50#define S5P64X0_PA_I2S 0xF2000000 52#define S5P64X0_PA_I2S 0xF2000000
51#define S5P6450_PA_I2S1 0xF2800000 53#define S5P6450_PA_I2S1 0xF2800000
52#define S5P6450_PA_I2S2 0xF2900000 54#define S5P6450_PA_I2S2 0xF2900000
@@ -64,6 +66,7 @@
64#define S3C_PA_IIC1 S5P6440_PA_IIC1 66#define S3C_PA_IIC1 S5P6440_PA_IIC1
65#define S3C_PA_RTC S5P64X0_PA_RTC 67#define S3C_PA_RTC S5P64X0_PA_RTC
66#define S3C_PA_WDT S5P64X0_PA_WDT 68#define S3C_PA_WDT S5P64X0_PA_WDT
69#define S3C_PA_FB S5P64X0_PA_FB
67 70
68#define S5P_PA_CHIPID S5P64X0_PA_CHIPID 71#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
69#define S5P_PA_SROMC S5P64X0_PA_SROMC 72#define S5P_PA_SROMC S5P64X0_PA_SROMC
@@ -85,5 +88,6 @@
85#define S5P_PA_UART5 S5P6450_PA_UART(5) 88#define S5P_PA_UART5 S5P6450_PA_UART(5)
86 89
87#define S5P_SZ_UART SZ_256 90#define S5P_SZ_UART SZ_256
91#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
88 92
89#endif /* __ASM_ARCH_MAP_H */ 93#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/pm-core.h b/arch/arm/mach-s5p64x0/include/mach/pm-core.h
new file mode 100644
index 000000000000..e52f7545d3aa
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/pm-core.h
@@ -0,0 +1,117 @@
1/* linux/arch/arm/mach-s5p64x0/include/mach/pm-core.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P64X0 - PM core support for arch/arm/plat-samsung/pm.c
7 *
8 * Based on PM core support for S3C64XX by Ben Dooks
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <mach/regs-gpio.h>
16
17static inline void s3c_pm_debug_init_uart(void)
18{
19 u32 tmp = __raw_readl(S5P64X0_CLK_GATE_PCLK);
20
21 /*
22 * As a note, since the S5P64X0 UARTs generally have multiple
23 * clock sources, we simply enable PCLK at the moment and hope
24 * that the resume settings for the UART are suitable for the
25 * use with PCLK.
26 */
27 tmp |= S5P64X0_CLK_GATE_PCLK_UART0;
28 tmp |= S5P64X0_CLK_GATE_PCLK_UART1;
29 tmp |= S5P64X0_CLK_GATE_PCLK_UART2;
30 tmp |= S5P64X0_CLK_GATE_PCLK_UART3;
31
32 __raw_writel(tmp, S5P64X0_CLK_GATE_PCLK);
33 udelay(10);
34}
35
36static inline void s3c_pm_arch_prepare_irqs(void)
37{
38 /* VIC should have already been taken care of */
39
40 /* clear any pending EINT0 interrupts */
41 __raw_writel(__raw_readl(S5P64X0_EINT0PEND), S5P64X0_EINT0PEND);
42}
43
44static inline void s3c_pm_arch_stop_clocks(void) { }
45static inline void s3c_pm_arch_show_resume_irqs(void) { }
46
47/*
48 * make these defines, we currently do not have any need to change
49 * the IRQ wake controls depending on the CPU we are running on
50 */
51#define s3c_irqwake_eintallow ((1 << 16) - 1)
52#define s3c_irqwake_intallow (~0)
53
54static inline void s3c_pm_arch_update_uart(void __iomem *regs,
55 struct pm_uart_save *save)
56{
57 u32 ucon = __raw_readl(regs + S3C2410_UCON);
58 u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
59 u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
60 u32 new_ucon;
61 u32 delta;
62
63 /*
64 * S5P64X0 UART blocks only support level interrupts, so ensure that
65 * when we restore unused UART blocks we force the level interrupt
66 * settings.
67 */
68 save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
69
70 /*
71 * We have a constraint on changing the clock type of the UART
72 * between UCLKx and PCLK, so ensure that when we restore UCON
73 * that the CLK field is correctly modified if the bootloader
74 * has changed anything.
75 */
76 if (ucon_clk != save_clk) {
77 new_ucon = save->ucon;
78 delta = ucon_clk ^ save_clk;
79
80 /*
81 * change from UCLKx => wrong PCLK,
82 * either UCLK can be tested for by a bit-test
83 * with UCLK0
84 */
85 if (ucon_clk & S3C6400_UCON_UCLK0 &&
86 !(save_clk & S3C6400_UCON_UCLK0) &&
87 delta & S3C6400_UCON_PCLK2) {
88 new_ucon &= ~S3C6400_UCON_UCLK0;
89 } else if (delta == S3C6400_UCON_PCLK2) {
90 /*
91 * as a precaution, don't change from
92 * PCLK2 => PCLK or vice-versa
93 */
94 new_ucon ^= S3C6400_UCON_PCLK2;
95 }
96
97 S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
98 ucon, new_ucon, save->ucon);
99 save->ucon = new_ucon;
100 }
101}
102
103static inline void s3c_pm_restored_gpios(void)
104{
105 /* ensure sleep mode has been cleared from the system */
106 __raw_writel(0, S5P64X0_SLPEN);
107}
108
109static inline void samsung_pm_saved_gpios(void)
110{
111 /*
112 * turn on the sleep mode and keep it there, as it seems that during
113 * suspend the xCON registers get re-set and thus you can end up with
114 * problems between going to sleep and resuming.
115 */
116 __raw_writel(S5P64X0_SLPEN_USE_xSLP, S5P64X0_SLPEN);
117}
diff --git a/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
deleted file mode 100644
index 19fff8b701c0..000000000000
--- a/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
+++ /dev/null
@@ -1,68 +0,0 @@
1/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright 2008 Openmoko, Inc.
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * S5P64X0 - pwm clock and timer support
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16*/
17
18#ifndef __ASM_ARCH_PWMCLK_H
19#define __ASM_ARCH_PWMCLK_H __FILE__
20
21/**
22 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
23 * @tcfg: The timer TCFG1 register bits shifted down to 0.
24 *
25 * Return true if the given configuration from TCFG1 is a TCLK instead
26 * any of the TDIV clocks.
27 */
28static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
29{
30 return 0;
31}
32
33/**
34 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
35 * @tcfg1: The tcfg1 setting, shifted down.
36 *
37 * Get the divisor value for the given tcfg1 setting. We assume the
38 * caller has already checked to see if this is not a TCLK source.
39 */
40static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
41{
42 return 1 << tcfg1;
43}
44
45/**
46 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
47 *
48 * Return true if we have a /1 in the tdiv setting.
49 */
50static inline unsigned int pwm_tdiv_has_div1(void)
51{
52 return 1;
53}
54
55/**
56 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
57 * @div: The divisor to calculate the bit information for.
58 *
59 * Turn a divisor into the necessary bit field for TCFG1.
60 */
61static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
62{
63 return ilog2(div);
64}
65
66#define S3C_TCFG1_MUX_TCLK 0
67
68#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index a133f22fa155..bd91112c813c 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -41,17 +41,50 @@
41#define S5P6450_DPLL_CON S5P_CLKREG(0x50) 41#define S5P6450_DPLL_CON S5P_CLKREG(0x50)
42#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54) 42#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54)
43 43
44#define S5P64X0_AHB_CON0 S5P_CLKREG(0x100)
44#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C) 45#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C)
45 46
46#define S5P64X0_SYS_ID S5P_CLKREG(0x118) 47#define S5P64X0_SYS_ID S5P_CLKREG(0x118)
47#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C) 48#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C)
48 49
49#define S5P64X0_PWR_CFG S5P_CLKREG(0x804) 50#define S5P64X0_PWR_CFG S5P_CLKREG(0x804)
51#define S5P64X0_EINT_WAKEUP_MASK S5P_CLKREG(0x808)
52#define S5P64X0_SLEEP_CFG S5P_CLKREG(0x818)
53#define S5P64X0_PWR_STABLE S5P_CLKREG(0x828)
54
50#define S5P64X0_OTHERS S5P_CLKREG(0x900) 55#define S5P64X0_OTHERS S5P_CLKREG(0x900)
56#define S5P64X0_WAKEUP_STAT S5P_CLKREG(0x908)
57
58#define S5P64X0_INFORM0 S5P_CLKREG(0xA00)
51 59
52#define S5P64X0_CLKDIV0_HCLK_SHIFT (8) 60#define S5P64X0_CLKDIV0_HCLK_SHIFT (8)
53#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT) 61#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
54 62
63/* HCLK GATE Registers */
64#define S5P64X0_CLK_GATE_HCLK1_FIMGVG (1 << 2)
65#define S5P64X0_CLK_GATE_SCLK1_FIMGVG (1 << 2)
66
67/* PCLK GATE Registers */
68#define S5P64X0_CLK_GATE_PCLK_UART3 (1 << 4)
69#define S5P64X0_CLK_GATE_PCLK_UART2 (1 << 3)
70#define S5P64X0_CLK_GATE_PCLK_UART1 (1 << 2)
71#define S5P64X0_CLK_GATE_PCLK_UART0 (1 << 1)
72
73#define S5P64X0_PWR_CFG_MMC1_DISABLE (1 << 15)
74#define S5P64X0_PWR_CFG_MMC0_DISABLE (1 << 14)
75#define S5P64X0_PWR_CFG_RTC_TICK_DISABLE (1 << 11)
76#define S5P64X0_PWR_CFG_RTC_ALRM_DISABLE (1 << 10)
77#define S5P64X0_PWR_CFG_WFI_MASK (3 << 5)
78#define S5P64X0_PWR_CFG_WFI_SLEEP (3 << 5)
79
80#define S5P64X0_SLEEP_CFG_OSC_EN (1 << 0)
81
82#define S5P64X0_PWR_STABLE_PWR_CNT_VAL4 (4 << 0)
83
84#define S5P6450_OTHERS_DISABLE_INT (1 << 31)
85#define S5P64X0_OTHERS_RET_UART (1 << 26)
86#define S5P64X0_OTHERS_RET_MMC1 (1 << 25)
87#define S5P64X0_OTHERS_RET_MMC0 (1 << 24)
55#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16) 88#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16)
56 89
57/* Compatibility defines */ 90/* Compatibility defines */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 6ce254729f3b..cfdfa4fdadf2 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -34,14 +34,35 @@
34#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180) 34#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
35#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300) 35#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
36 36
37#define S5P64X0_SPCON0 (S5P_VA_GPIO + 0x1A0)
38#define S5P64X0_SPCON0_LCD_SEL_MASK (0x3 << 0)
39#define S5P64X0_SPCON0_LCD_SEL_RGB (0x1 << 0)
40#define S5P64X0_SPCON1 (S5P_VA_GPIO + 0x2B0)
41
42#define S5P64X0_MEM0CONSLP0 (S5P_VA_GPIO + 0x1C0)
43#define S5P64X0_MEM0CONSLP1 (S5P_VA_GPIO + 0x1C4)
44#define S5P64X0_MEM0DRVCON (S5P_VA_GPIO + 0x1D0)
45#define S5P64X0_MEM1DRVCON (S5P_VA_GPIO + 0x1D4)
46
47#define S5P64X0_EINT12CON (S5P_VA_GPIO + 0x200)
48#define S5P64X0_EINT12FLTCON (S5P_VA_GPIO + 0x220)
49#define S5P64X0_EINT12MASK (S5P_VA_GPIO + 0x240)
50
37/* External interrupt control registers for group0 */ 51/* External interrupt control registers for group0 */
38 52
39#define EINT0CON0_OFFSET (0x900) 53#define EINT0CON0_OFFSET (0x900)
54#define EINT0FLTCON0_OFFSET (0x910)
55#define EINT0FLTCON1_OFFSET (0x914)
40#define EINT0MASK_OFFSET (0x920) 56#define EINT0MASK_OFFSET (0x920)
41#define EINT0PEND_OFFSET (0x924) 57#define EINT0PEND_OFFSET (0x924)
42 58
43#define S5P64X0_EINT0CON0 (S5P_VA_GPIO + EINT0CON0_OFFSET) 59#define S5P64X0_EINT0CON0 (S5P_VA_GPIO + EINT0CON0_OFFSET)
60#define S5P64X0_EINT0FLTCON0 (S5P_VA_GPIO + EINT0FLTCON0_OFFSET)
61#define S5P64X0_EINT0FLTCON1 (S5P_VA_GPIO + EINT0FLTCON1_OFFSET)
44#define S5P64X0_EINT0MASK (S5P_VA_GPIO + EINT0MASK_OFFSET) 62#define S5P64X0_EINT0MASK (S5P_VA_GPIO + EINT0MASK_OFFSET)
45#define S5P64X0_EINT0PEND (S5P_VA_GPIO + EINT0PEND_OFFSET) 63#define S5P64X0_EINT0PEND (S5P_VA_GPIO + EINT0PEND_OFFSET)
46 64
65#define S5P64X0_SLPEN (S5P_VA_GPIO + 0x930)
66#define S5P64X0_SLPEN_USE_xSLP (1 << 0)
67
47#endif /* __ASM_ARCH_REGS_GPIO_H */ 68#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c
index 494e1a8f6f6d..275dc74f4a7b 100644
--- a/arch/arm/mach-s5p64x0/irq-eint.c
+++ b/arch/arm/mach-s5p64x0/irq-eint.c
@@ -20,6 +20,7 @@
20#include <plat/cpu.h> 20#include <plat/cpu.h>
21#include <plat/regs-irqtype.h> 21#include <plat/regs-irqtype.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23#include <plat/pm.h>
23 24
24#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
25#include <mach/regs-clock.h> 26#include <mach/regs-clock.h>
@@ -134,6 +135,7 @@ static int s5p64x0_alloc_gc(void)
134 ct->chip.irq_mask = irq_gc_mask_set_bit; 135 ct->chip.irq_mask = irq_gc_mask_set_bit;
135 ct->chip.irq_unmask = irq_gc_mask_clr_bit; 136 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
136 ct->chip.irq_set_type = s5p64x0_irq_eint_set_type; 137 ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
138 ct->chip.irq_set_wake = s3c_irqext_wake;
137 ct->regs.ack = EINT0PEND_OFFSET; 139 ct->regs.ack = EINT0PEND_OFFSET;
138 ct->regs.mask = EINT0MASK_OFFSET; 140 ct->regs.mask = EINT0MASK_OFFSET;
139 irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE, 141 irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
diff --git a/arch/arm/mach-s5p64x0/irq-pm.c b/arch/arm/mach-s5p64x0/irq-pm.c
new file mode 100644
index 000000000000..3e6f2456ee9d
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/irq-pm.c
@@ -0,0 +1,92 @@
1/* linux/arch/arm/mach-s5p64x0/irq-pm.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P64X0 - Interrupt handling Power Management
7 *
8 * Based on arch/arm/mach-s3c64xx/irq-pm.c by Ben Dooks
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/syscore_ops.h>
16#include <linux/serial_core.h>
17#include <linux/io.h>
18
19#include <plat/regs-serial.h>
20#include <plat/pm.h>
21
22#include <mach/regs-gpio.h>
23
24static struct sleep_save irq_save[] = {
25 SAVE_ITEM(S5P64X0_EINT0CON0),
26 SAVE_ITEM(S5P64X0_EINT0FLTCON0),
27 SAVE_ITEM(S5P64X0_EINT0FLTCON1),
28 SAVE_ITEM(S5P64X0_EINT0MASK),
29};
30
31static struct irq_grp_save {
32 u32 con;
33 u32 fltcon;
34 u32 mask;
35} eint_grp_save[4];
36
37static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
38
39static int s5p64x0_irq_pm_suspend(void)
40{
41 struct irq_grp_save *grp = eint_grp_save;
42 int i;
43
44 S3C_PMDBG("%s: suspending IRQs\n", __func__);
45
46 s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
47
48 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
49 irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
50
51 for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
52 grp->con = __raw_readl(S5P64X0_EINT12CON + (i * 4));
53 grp->mask = __raw_readl(S5P64X0_EINT12MASK + (i * 4));
54 grp->fltcon = __raw_readl(S5P64X0_EINT12FLTCON + (i * 4));
55 }
56
57 return 0;
58}
59
60static void s5p64x0_irq_pm_resume(void)
61{
62 struct irq_grp_save *grp = eint_grp_save;
63 int i;
64
65 S3C_PMDBG("%s: resuming IRQs\n", __func__);
66
67 s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
68
69 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
70 __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
71
72 for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
73 __raw_writel(grp->con, S5P64X0_EINT12CON + (i * 4));
74 __raw_writel(grp->mask, S5P64X0_EINT12MASK + (i * 4));
75 __raw_writel(grp->fltcon, S5P64X0_EINT12FLTCON + (i * 4));
76 }
77
78 S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
79}
80
81static struct syscore_ops s5p64x0_irq_syscore_ops = {
82 .suspend = s5p64x0_irq_pm_suspend,
83 .resume = s5p64x0_irq_pm_resume,
84};
85
86static int __init s5p64x0_syscore_init(void)
87{
88 register_syscore_ops(&s5p64x0_irq_syscore_ops);
89
90 return 0;
91}
92core_initcall(s5p64x0_syscore_init);
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 88857f5a49f7..4a1250cd1356 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -23,6 +23,9 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/pwm_backlight.h> 25#include <linux/pwm_backlight.h>
26#include <linux/fb.h>
27
28#include <video/platform_lcd.h>
26 29
27#include <asm/mach/arch.h> 30#include <asm/mach/arch.h>
28#include <asm/mach/map.h> 31#include <asm/mach/map.h>
@@ -47,6 +50,8 @@
47#include <plat/ts.h> 50#include <plat/ts.h>
48#include <plat/s5p-time.h> 51#include <plat/s5p-time.h>
49#include <plat/backlight.h> 52#include <plat/backlight.h>
53#include <plat/fb.h>
54#include <plat/regs-fb.h>
50 55
51#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 56#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
52 S3C2410_UCON_RXILEVEL | \ 57 S3C2410_UCON_RXILEVEL | \
@@ -92,6 +97,59 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
92 }, 97 },
93}; 98};
94 99
100/* Frame Buffer */
101static struct s3c_fb_pd_win smdk6440_fb_win0 = {
102 .win_mode = {
103 .left_margin = 8,
104 .right_margin = 13,
105 .upper_margin = 7,
106 .lower_margin = 5,
107 .hsync_len = 3,
108 .vsync_len = 1,
109 .xres = 800,
110 .yres = 480,
111 },
112 .max_bpp = 32,
113 .default_bpp = 24,
114};
115
116static struct s3c_fb_platdata smdk6440_lcd_pdata __initdata = {
117 .win[0] = &smdk6440_fb_win0,
118 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
119 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
120 .setup_gpio = s5p64x0_fb_gpio_setup_24bpp,
121};
122
123/* LCD power controller */
124static void smdk6440_lte480_reset_power(struct plat_lcd_data *pd,
125 unsigned int power)
126{
127 int err;
128
129 if (power) {
130 err = gpio_request(S5P6440_GPN(5), "GPN");
131 if (err) {
132 printk(KERN_ERR "failed to request GPN for lcd reset\n");
133 return;
134 }
135
136 gpio_direction_output(S5P6440_GPN(5), 1);
137 gpio_set_value(S5P6440_GPN(5), 0);
138 gpio_set_value(S5P6440_GPN(5), 1);
139 gpio_free(S5P6440_GPN(5));
140 }
141}
142
143static struct plat_lcd_data smdk6440_lcd_power_data = {
144 .set_power = smdk6440_lte480_reset_power,
145};
146
147static struct platform_device smdk6440_lcd_lte480wv = {
148 .name = "platform-lcd",
149 .dev.parent = &s3c_device_fb.dev,
150 .dev.platform_data = &smdk6440_lcd_power_data,
151};
152
95static struct platform_device *smdk6440_devices[] __initdata = { 153static struct platform_device *smdk6440_devices[] __initdata = {
96 &s3c_device_adc, 154 &s3c_device_adc,
97 &s3c_device_rtc, 155 &s3c_device_rtc,
@@ -101,6 +159,8 @@ static struct platform_device *smdk6440_devices[] __initdata = {
101 &s3c_device_wdt, 159 &s3c_device_wdt,
102 &samsung_asoc_dma, 160 &samsung_asoc_dma,
103 &s5p6440_device_iis, 161 &s5p6440_device_iis,
162 &s3c_device_fb,
163 &smdk6440_lcd_lte480wv,
104}; 164};
105 165
106static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = { 166static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -147,6 +207,17 @@ static void __init smdk6440_map_io(void)
147 s5p_set_timer_source(S5P_PWM3, S5P_PWM4); 207 s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
148} 208}
149 209
210static void s5p6440_set_lcd_interface(void)
211{
212 unsigned int cfg;
213
214 /* select TFT LCD type (RGB I/F) */
215 cfg = __raw_readl(S5P64X0_SPCON0);
216 cfg &= ~S5P64X0_SPCON0_LCD_SEL_MASK;
217 cfg |= S5P64X0_SPCON0_LCD_SEL_RGB;
218 __raw_writel(cfg, S5P64X0_SPCON0);
219}
220
150static void __init smdk6440_machine_init(void) 221static void __init smdk6440_machine_init(void)
151{ 222{
152 s3c24xx_ts_set_platdata(NULL); 223 s3c24xx_ts_set_platdata(NULL);
@@ -160,6 +231,9 @@ static void __init smdk6440_machine_init(void)
160 231
161 samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data); 232 samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
162 233
234 s5p6440_set_lcd_interface();
235 s3c_fb_set_platdata(&smdk6440_lcd_pdata);
236
163 platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices)); 237 platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
164} 238}
165 239
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index e1b277b94610..0ab129ecf009 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -23,6 +23,9 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/pwm_backlight.h> 25#include <linux/pwm_backlight.h>
26#include <linux/fb.h>
27
28#include <video/platform_lcd.h>
26 29
27#include <asm/mach/arch.h> 30#include <asm/mach/arch.h>
28#include <asm/mach/map.h> 31#include <asm/mach/map.h>
@@ -47,6 +50,8 @@
47#include <plat/ts.h> 50#include <plat/ts.h>
48#include <plat/s5p-time.h> 51#include <plat/s5p-time.h>
49#include <plat/backlight.h> 52#include <plat/backlight.h>
53#include <plat/fb.h>
54#include <plat/regs-fb.h>
50 55
51#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 56#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
52 S3C2410_UCON_RXILEVEL | \ 57 S3C2410_UCON_RXILEVEL | \
@@ -110,6 +115,59 @@ static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
110#endif 115#endif
111}; 116};
112 117
118/* Frame Buffer */
119static struct s3c_fb_pd_win smdk6450_fb_win0 = {
120 .win_mode = {
121 .left_margin = 8,
122 .right_margin = 13,
123 .upper_margin = 7,
124 .lower_margin = 5,
125 .hsync_len = 3,
126 .vsync_len = 1,
127 .xres = 800,
128 .yres = 480,
129 },
130 .max_bpp = 32,
131 .default_bpp = 24,
132};
133
134static struct s3c_fb_platdata smdk6450_lcd_pdata __initdata = {
135 .win[0] = &smdk6450_fb_win0,
136 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
137 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
138 .setup_gpio = s5p64x0_fb_gpio_setup_24bpp,
139};
140
141/* LCD power controller */
142static void smdk6450_lte480_reset_power(struct plat_lcd_data *pd,
143 unsigned int power)
144{
145 int err;
146
147 if (power) {
148 err = gpio_request(S5P6450_GPN(5), "GPN");
149 if (err) {
150 printk(KERN_ERR "failed to request GPN for lcd reset\n");
151 return;
152 }
153
154 gpio_direction_output(S5P6450_GPN(5), 1);
155 gpio_set_value(S5P6450_GPN(5), 0);
156 gpio_set_value(S5P6450_GPN(5), 1);
157 gpio_free(S5P6450_GPN(5));
158 }
159}
160
161static struct plat_lcd_data smdk6450_lcd_power_data = {
162 .set_power = smdk6450_lte480_reset_power,
163};
164
165static struct platform_device smdk6450_lcd_lte480wv = {
166 .name = "platform-lcd",
167 .dev.parent = &s3c_device_fb.dev,
168 .dev.platform_data = &smdk6450_lcd_power_data,
169};
170
113static struct platform_device *smdk6450_devices[] __initdata = { 171static struct platform_device *smdk6450_devices[] __initdata = {
114 &s3c_device_adc, 172 &s3c_device_adc,
115 &s3c_device_rtc, 173 &s3c_device_rtc,
@@ -119,6 +177,9 @@ static struct platform_device *smdk6450_devices[] __initdata = {
119 &s3c_device_wdt, 177 &s3c_device_wdt,
120 &samsung_asoc_dma, 178 &samsung_asoc_dma,
121 &s5p6450_device_iis0, 179 &s5p6450_device_iis0,
180 &s3c_device_fb,
181 &smdk6450_lcd_lte480wv,
182
122 /* s5p6450_device_spi0 will be added */ 183 /* s5p6450_device_spi0 will be added */
123}; 184};
124 185
@@ -166,6 +227,17 @@ static void __init smdk6450_map_io(void)
166 s5p_set_timer_source(S5P_PWM3, S5P_PWM4); 227 s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
167} 228}
168 229
230static void s5p6450_set_lcd_interface(void)
231{
232 unsigned int cfg;
233
234 /* select TFT LCD type (RGB I/F) */
235 cfg = __raw_readl(S5P64X0_SPCON0);
236 cfg &= ~S5P64X0_SPCON0_LCD_SEL_MASK;
237 cfg |= S5P64X0_SPCON0_LCD_SEL_RGB;
238 __raw_writel(cfg, S5P64X0_SPCON0);
239}
240
169static void __init smdk6450_machine_init(void) 241static void __init smdk6450_machine_init(void)
170{ 242{
171 s3c24xx_ts_set_platdata(NULL); 243 s3c24xx_ts_set_platdata(NULL);
@@ -179,6 +251,9 @@ static void __init smdk6450_machine_init(void)
179 251
180 samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data); 252 samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
181 253
254 s5p6450_set_lcd_interface();
255 s3c_fb_set_platdata(&smdk6450_lcd_pdata);
256
182 platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices)); 257 platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
183} 258}
184 259
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
new file mode 100644
index 000000000000..69927243d25f
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -0,0 +1,204 @@
1/* linux/arch/arm/mach-s5p64x0/pm.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P64X0 Power Management Support
7 *
8 * Based on arch/arm/mach-s3c64xx/pm.c by Ben Dooks
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/suspend.h>
16#include <linux/syscore_ops.h>
17#include <linux/io.h>
18
19#include <plat/cpu.h>
20#include <plat/pm.h>
21#include <plat/regs-timer.h>
22#include <plat/wakeup-mask.h>
23
24#include <mach/regs-clock.h>
25#include <mach/regs-gpio.h>
26
27static struct sleep_save s5p64x0_core_save[] = {
28 SAVE_ITEM(S5P64X0_APLL_CON),
29 SAVE_ITEM(S5P64X0_MPLL_CON),
30 SAVE_ITEM(S5P64X0_EPLL_CON),
31 SAVE_ITEM(S5P64X0_EPLL_CON_K),
32 SAVE_ITEM(S5P64X0_CLK_SRC0),
33 SAVE_ITEM(S5P64X0_CLK_SRC1),
34 SAVE_ITEM(S5P64X0_CLK_DIV0),
35 SAVE_ITEM(S5P64X0_CLK_DIV1),
36 SAVE_ITEM(S5P64X0_CLK_DIV2),
37 SAVE_ITEM(S5P64X0_CLK_DIV3),
38 SAVE_ITEM(S5P64X0_CLK_GATE_MEM0),
39 SAVE_ITEM(S5P64X0_CLK_GATE_HCLK1),
40 SAVE_ITEM(S5P64X0_CLK_GATE_SCLK1),
41};
42
43static struct sleep_save s5p64x0_misc_save[] = {
44 SAVE_ITEM(S5P64X0_AHB_CON0),
45 SAVE_ITEM(S5P64X0_SPCON0),
46 SAVE_ITEM(S5P64X0_SPCON1),
47 SAVE_ITEM(S5P64X0_MEM0CONSLP0),
48 SAVE_ITEM(S5P64X0_MEM0CONSLP1),
49 SAVE_ITEM(S5P64X0_MEM0DRVCON),
50 SAVE_ITEM(S5P64X0_MEM1DRVCON),
51
52 SAVE_ITEM(S3C64XX_TINT_CSTAT),
53};
54
55/* DPLL is present only in S5P6450 */
56static struct sleep_save s5p6450_core_save[] = {
57 SAVE_ITEM(S5P6450_DPLL_CON),
58 SAVE_ITEM(S5P6450_DPLL_CON_K),
59};
60
61void s3c_pm_configure_extint(void)
62{
63 __raw_writel(s3c_irqwake_eintmask, S5P64X0_EINT_WAKEUP_MASK);
64}
65
66void s3c_pm_restore_core(void)
67{
68 __raw_writel(0, S5P64X0_EINT_WAKEUP_MASK);
69
70 s3c_pm_do_restore_core(s5p64x0_core_save,
71 ARRAY_SIZE(s5p64x0_core_save));
72
73 if (soc_is_s5p6450())
74 s3c_pm_do_restore_core(s5p6450_core_save,
75 ARRAY_SIZE(s5p6450_core_save));
76
77 s3c_pm_do_restore(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
78}
79
80void s3c_pm_save_core(void)
81{
82 s3c_pm_do_save(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
83
84 if (soc_is_s5p6450())
85 s3c_pm_do_save(s5p6450_core_save,
86 ARRAY_SIZE(s5p6450_core_save));
87
88 s3c_pm_do_save(s5p64x0_core_save, ARRAY_SIZE(s5p64x0_core_save));
89}
90
91static int s5p64x0_cpu_suspend(unsigned long arg)
92{
93 unsigned long tmp = 0;
94
95 /*
96 * Issue the standby signal into the pm unit. Note, we
97 * issue a write-buffer drain just in case.
98 */
99 asm("b 1f\n\t"
100 ".align 5\n\t"
101 "1:\n\t"
102 "mcr p15, 0, %0, c7, c10, 5\n\t"
103 "mcr p15, 0, %0, c7, c10, 4\n\t"
104 "mcr p15, 0, %0, c7, c0, 4" : : "r" (tmp));
105
106 /* we should never get past here */
107 panic("sleep resumed to originator?");
108}
109
110/* mapping of interrupts to parts of the wakeup mask */
111static struct samsung_wakeup_mask s5p64x0_wake_irqs[] = {
112 { .irq = IRQ_RTC_ALARM, .bit = S5P64X0_PWR_CFG_RTC_ALRM_DISABLE, },
113 { .irq = IRQ_RTC_TIC, .bit = S5P64X0_PWR_CFG_RTC_TICK_DISABLE, },
114 { .irq = IRQ_HSMMC0, .bit = S5P64X0_PWR_CFG_MMC0_DISABLE, },
115 { .irq = IRQ_HSMMC1, .bit = S5P64X0_PWR_CFG_MMC1_DISABLE, },
116};
117
118static void s5p64x0_pm_prepare(void)
119{
120 u32 tmp;
121
122 samsung_sync_wakemask(S5P64X0_PWR_CFG,
123 s5p64x0_wake_irqs, ARRAY_SIZE(s5p64x0_wake_irqs));
124
125 /* store the resume address in INFORM0 register */
126 __raw_writel(virt_to_phys(s3c_cpu_resume), S5P64X0_INFORM0);
127
128 /* setup clock gating for FIMGVG block */
129 __raw_writel((__raw_readl(S5P64X0_CLK_GATE_HCLK1) | \
130 (S5P64X0_CLK_GATE_HCLK1_FIMGVG)), S5P64X0_CLK_GATE_HCLK1);
131 __raw_writel((__raw_readl(S5P64X0_CLK_GATE_SCLK1) | \
132 (S5P64X0_CLK_GATE_SCLK1_FIMGVG)), S5P64X0_CLK_GATE_SCLK1);
133
134 /* Configure the stabilization counter with wait time required */
135 __raw_writel(S5P64X0_PWR_STABLE_PWR_CNT_VAL4, S5P64X0_PWR_STABLE);
136
137 /* set WFI to SLEEP mode configuration */
138 tmp = __raw_readl(S5P64X0_SLEEP_CFG);
139 tmp &= ~(S5P64X0_SLEEP_CFG_OSC_EN);
140 __raw_writel(tmp, S5P64X0_SLEEP_CFG);
141
142 tmp = __raw_readl(S5P64X0_PWR_CFG);
143 tmp &= ~(S5P64X0_PWR_CFG_WFI_MASK);
144 tmp |= S5P64X0_PWR_CFG_WFI_SLEEP;
145 __raw_writel(tmp, S5P64X0_PWR_CFG);
146
147 /*
148 * set OTHERS register to disable interrupt before going to
149 * sleep. This bit is present only in S5P6450, it is reserved
150 * in S5P6440.
151 */
152 if (soc_is_s5p6450()) {
153 tmp = __raw_readl(S5P64X0_OTHERS);
154 tmp |= S5P6450_OTHERS_DISABLE_INT;
155 __raw_writel(tmp, S5P64X0_OTHERS);
156 }
157
158 /* ensure previous wakeup state is cleared before sleeping */
159 __raw_writel(__raw_readl(S5P64X0_WAKEUP_STAT), S5P64X0_WAKEUP_STAT);
160
161}
162
163static int s5p64x0_pm_add(struct sys_device *sysdev)
164{
165 pm_cpu_prep = s5p64x0_pm_prepare;
166 pm_cpu_sleep = s5p64x0_cpu_suspend;
167 pm_uart_udivslot = 1;
168
169 return 0;
170}
171
172static struct sysdev_driver s5p64x0_pm_driver = {
173 .add = s5p64x0_pm_add,
174};
175
176static __init int s5p64x0_pm_drvinit(void)
177{
178 s3c_pm_init();
179
180 return sysdev_driver_register(&s5p64x0_sysclass, &s5p64x0_pm_driver);
181}
182arch_initcall(s5p64x0_pm_drvinit);
183
184static void s5p64x0_pm_resume(void)
185{
186 u32 tmp;
187
188 tmp = __raw_readl(S5P64X0_OTHERS);
189 tmp |= (S5P64X0_OTHERS_RET_MMC0 | S5P64X0_OTHERS_RET_MMC1 | \
190 S5P64X0_OTHERS_RET_UART);
191 __raw_writel(tmp , S5P64X0_OTHERS);
192}
193
194static struct syscore_ops s5p64x0_pm_syscore_ops = {
195 .resume = s5p64x0_pm_resume,
196};
197
198static __init int s5p64x0_pm_syscore_init(void)
199{
200 register_syscore_ops(&s5p64x0_pm_syscore_ops);
201
202 return 0;
203}
204arch_initcall(s5p64x0_pm_syscore_init);
diff --git a/arch/arm/mach-s5p64x0/setup-fb-24bpp.c b/arch/arm/mach-s5p64x0/setup-fb-24bpp.c
new file mode 100644
index 000000000000..f346ee4af54d
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-fb-24bpp.c
@@ -0,0 +1,29 @@
1/* linux/arch/arm/mach-s5p64x0/setup-fb-24bpp.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Base S5P64X0 GPIO setup information for LCD framebuffer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/fb.h>
14#include <linux/gpio.h>
15
16#include <plat/cpu.h>
17#include <plat/fb.h>
18#include <plat/gpio-cfg.h>
19
20void s5p64x0_fb_gpio_setup_24bpp(void)
21{
22 if (soc_is_s5p6440()) {
23 s3c_gpio_cfgrange_nopull(S5P6440_GPI(0), 16, S3C_GPIO_SFN(2));
24 s3c_gpio_cfgrange_nopull(S5P6440_GPJ(0), 12, S3C_GPIO_SFN(2));
25 } else if (soc_is_s5p6450()) {
26 s3c_gpio_cfgrange_nopull(S5P6450_GPI(0), 16, S3C_GPIO_SFN(2));
27 s3c_gpio_cfgrange_nopull(S5P6450_GPJ(0), 12, S3C_GPIO_SFN(2));
28 }
29}
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index e8a33c4b054c..e538a4c67e9c 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -10,7 +10,7 @@ if ARCH_S5PC100
10config CPU_S5PC100 10config CPU_S5PC100
11 bool 11 bool
12 select S5P_EXT_INT 12 select S5P_EXT_INT
13 select S3C_PL330_DMA 13 select SAMSUNG_DMADEV
14 help 14 help
15 Enable S5PC100 CPU support 15 Enable S5PC100 CPU support
16 16
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index ff5cbb30de5b..8d47709da713 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = {
33 .name = "otg_phy", 33 .name = "otg_phy",
34}; 34};
35 35
36static struct clk dummy_apb_pclk = {
37 .name = "apb_pclk",
38 .id = -1,
39};
40
36static struct clk *clk_src_mout_href_list[] = { 41static struct clk *clk_src_mout_href_list[] = {
37 [0] = &s5p_clk_27m, 42 [0] = &s5p_clk_27m,
38 [1] = &clk_fin_hpll, 43 [1] = &clk_fin_hpll,
@@ -454,14 +459,14 @@ static struct clk init_clocks_off[] = {
454 .enable = s5pc100_d1_0_ctrl, 459 .enable = s5pc100_d1_0_ctrl,
455 .ctrlbit = (1 << 2), 460 .ctrlbit = (1 << 2),
456 }, { 461 }, {
457 .name = "pdma", 462 .name = "dma",
458 .devname = "s3c-pl330.1", 463 .devname = "dma-pl330.1",
459 .parent = &clk_div_d1_bus.clk, 464 .parent = &clk_div_d1_bus.clk,
460 .enable = s5pc100_d1_0_ctrl, 465 .enable = s5pc100_d1_0_ctrl,
461 .ctrlbit = (1 << 1), 466 .ctrlbit = (1 << 1),
462 }, { 467 }, {
463 .name = "pdma", 468 .name = "dma",
464 .devname = "s3c-pl330.0", 469 .devname = "dma-pl330.0",
465 .parent = &clk_div_d1_bus.clk, 470 .parent = &clk_div_d1_bus.clk,
466 .enable = s5pc100_d1_0_ctrl, 471 .enable = s5pc100_d1_0_ctrl,
467 .ctrlbit = (1 << 0), 472 .ctrlbit = (1 << 0),
@@ -1276,5 +1281,7 @@ void __init s5pc100_register_clocks(void)
1276 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1281 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1277 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1282 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1278 1283
1284 s3c24xx_register_clock(&dummy_apb_pclk);
1285
1279 s3c_pwmclk_init(); 1286 s3c_pwmclk_init();
1280} 1287}
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index bf4cd0fb97c6..065a087f5a8b 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -1,4 +1,8 @@
1/* 1/* linux/arch/arm/mach-s5pc100/dma.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd. 6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com> 7 * Jaswinder Singh <jassi.brar@samsung.com>
4 * 8 *
@@ -17,150 +21,246 @@
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */ 22 */
19 23
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h>
22 27
28#include <asm/irq.h>
23#include <plat/devs.h> 29#include <plat/devs.h>
30#include <plat/irqs.h>
24 31
25#include <mach/map.h> 32#include <mach/map.h>
26#include <mach/irqs.h> 33#include <mach/irqs.h>
27 34#include <mach/dma.h>
28#include <plat/s3c-pl330-pdata.h>
29 35
30static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
31 37
32static struct resource s5pc100_pdma0_resource[] = { 38struct dma_pl330_peri pdma0_peri[30] = {
33 [0] = { 39 {
34 .start = S5PC100_PA_PDMA0, 40 .peri_id = (u8)DMACH_UART0_RX,
35 .end = S5PC100_PA_PDMA0 + SZ_4K, 41 .rqtype = DEVTOMEM,
36 .flags = IORESOURCE_MEM, 42 }, {
37 }, 43 .peri_id = (u8)DMACH_UART0_TX,
38 [1] = { 44 .rqtype = MEMTODEV,
39 .start = IRQ_PDMA0, 45 }, {
40 .end = IRQ_PDMA0, 46 .peri_id = (u8)DMACH_UART1_RX,
41 .flags = IORESOURCE_IRQ, 47 .rqtype = DEVTOMEM,
48 }, {
49 .peri_id = (u8)DMACH_UART1_TX,
50 .rqtype = MEMTODEV,
51 }, {
52 .peri_id = (u8)DMACH_UART2_RX,
53 .rqtype = DEVTOMEM,
54 }, {
55 .peri_id = (u8)DMACH_UART2_TX,
56 .rqtype = MEMTODEV,
57 }, {
58 .peri_id = (u8)DMACH_UART3_RX,
59 .rqtype = DEVTOMEM,
60 }, {
61 .peri_id = (u8)DMACH_UART3_TX,
62 .rqtype = MEMTODEV,
63 }, {
64 .peri_id = DMACH_IRDA,
65 }, {
66 .peri_id = (u8)DMACH_I2S0_RX,
67 .rqtype = DEVTOMEM,
68 }, {
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_I2S2_RX,
82 .rqtype = DEVTOMEM,
83 }, {
84 .peri_id = (u8)DMACH_I2S2_TX,
85 .rqtype = MEMTODEV,
86 }, {
87 .peri_id = (u8)DMACH_SPI0_RX,
88 .rqtype = DEVTOMEM,
89 }, {
90 .peri_id = (u8)DMACH_SPI0_TX,
91 .rqtype = MEMTODEV,
92 }, {
93 .peri_id = (u8)DMACH_SPI1_RX,
94 .rqtype = DEVTOMEM,
95 }, {
96 .peri_id = (u8)DMACH_SPI1_TX,
97 .rqtype = MEMTODEV,
98 }, {
99 .peri_id = (u8)DMACH_SPI2_RX,
100 .rqtype = DEVTOMEM,
101 }, {
102 .peri_id = (u8)DMACH_SPI2_TX,
103 .rqtype = MEMTODEV,
104 }, {
105 .peri_id = (u8)DMACH_AC97_MICIN,
106 .rqtype = DEVTOMEM,
107 }, {
108 .peri_id = (u8)DMACH_AC97_PCMIN,
109 .rqtype = DEVTOMEM,
110 }, {
111 .peri_id = (u8)DMACH_AC97_PCMOUT,
112 .rqtype = MEMTODEV,
113 }, {
114 .peri_id = (u8)DMACH_EXTERNAL,
115 }, {
116 .peri_id = (u8)DMACH_PWM,
117 }, {
118 .peri_id = (u8)DMACH_SPDIF,
119 .rqtype = MEMTODEV,
120 }, {
121 .peri_id = (u8)DMACH_HSI_RX,
122 .rqtype = DEVTOMEM,
123 }, {
124 .peri_id = (u8)DMACH_HSI_TX,
125 .rqtype = MEMTODEV,
42 }, 126 },
43}; 127};
44 128
45static struct s3c_pl330_platdata s5pc100_pdma0_pdata = { 129struct dma_pl330_platdata s5pc100_pdma0_pdata = {
46 .peri = { 130 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
47 [0] = DMACH_UART0_RX, 131 .peri = pdma0_peri,
48 [1] = DMACH_UART0_TX,
49 [2] = DMACH_UART1_RX,
50 [3] = DMACH_UART1_TX,
51 [4] = DMACH_UART2_RX,
52 [5] = DMACH_UART2_TX,
53 [6] = DMACH_UART3_RX,
54 [7] = DMACH_UART3_TX,
55 [8] = DMACH_IRDA,
56 [9] = DMACH_I2S0_RX,
57 [10] = DMACH_I2S0_TX,
58 [11] = DMACH_I2S0S_TX,
59 [12] = DMACH_I2S1_RX,
60 [13] = DMACH_I2S1_TX,
61 [14] = DMACH_I2S2_RX,
62 [15] = DMACH_I2S2_TX,
63 [16] = DMACH_SPI0_RX,
64 [17] = DMACH_SPI0_TX,
65 [18] = DMACH_SPI1_RX,
66 [19] = DMACH_SPI1_TX,
67 [20] = DMACH_SPI2_RX,
68 [21] = DMACH_SPI2_TX,
69 [22] = DMACH_AC97_MICIN,
70 [23] = DMACH_AC97_PCMIN,
71 [24] = DMACH_AC97_PCMOUT,
72 [25] = DMACH_EXTERNAL,
73 [26] = DMACH_PWM,
74 [27] = DMACH_SPDIF,
75 [28] = DMACH_HSI_RX,
76 [29] = DMACH_HSI_TX,
77 [30] = DMACH_MAX,
78 [31] = DMACH_MAX,
79 },
80}; 132};
81 133
82static struct platform_device s5pc100_device_pdma0 = { 134struct amba_device s5pc100_device_pdma0 = {
83 .name = "s3c-pl330", 135 .dev = {
84 .id = 0, 136 .init_name = "dma-pl330.0",
85 .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
86 .resource = s5pc100_pdma0_resource,
87 .dev = {
88 .dma_mask = &dma_dmamask, 137 .dma_mask = &dma_dmamask,
89 .coherent_dma_mask = DMA_BIT_MASK(32), 138 .coherent_dma_mask = DMA_BIT_MASK(32),
90 .platform_data = &s5pc100_pdma0_pdata, 139 .platform_data = &s5pc100_pdma0_pdata,
91 }, 140 },
92}; 141 .res = {
93 142 .start = S5PC100_PA_PDMA0,
94static struct resource s5pc100_pdma1_resource[] = { 143 .end = S5PC100_PA_PDMA0 + SZ_4K,
95 [0] = {
96 .start = S5PC100_PA_PDMA1,
97 .end = S5PC100_PA_PDMA1 + SZ_4K,
98 .flags = IORESOURCE_MEM, 144 .flags = IORESOURCE_MEM,
99 }, 145 },
100 [1] = { 146 .irq = {IRQ_PDMA0, NO_IRQ},
101 .start = IRQ_PDMA1, 147 .periphid = 0x00041330,
102 .end = IRQ_PDMA1,
103 .flags = IORESOURCE_IRQ,
104 },
105}; 148};
106 149
107static struct s3c_pl330_platdata s5pc100_pdma1_pdata = { 150struct dma_pl330_peri pdma1_peri[30] = {
108 .peri = { 151 {
109 [0] = DMACH_UART0_RX, 152 .peri_id = (u8)DMACH_UART0_RX,
110 [1] = DMACH_UART0_TX, 153 .rqtype = DEVTOMEM,
111 [2] = DMACH_UART1_RX, 154 }, {
112 [3] = DMACH_UART1_TX, 155 .peri_id = (u8)DMACH_UART0_TX,
113 [4] = DMACH_UART2_RX, 156 .rqtype = MEMTODEV,
114 [5] = DMACH_UART2_TX, 157 }, {
115 [6] = DMACH_UART3_RX, 158 .peri_id = (u8)DMACH_UART1_RX,
116 [7] = DMACH_UART3_TX, 159 .rqtype = DEVTOMEM,
117 [8] = DMACH_IRDA, 160 }, {
118 [9] = DMACH_I2S0_RX, 161 .peri_id = (u8)DMACH_UART1_TX,
119 [10] = DMACH_I2S0_TX, 162 .rqtype = MEMTODEV,
120 [11] = DMACH_I2S0S_TX, 163 }, {
121 [12] = DMACH_I2S1_RX, 164 .peri_id = (u8)DMACH_UART2_RX,
122 [13] = DMACH_I2S1_TX, 165 .rqtype = DEVTOMEM,
123 [14] = DMACH_I2S2_RX, 166 }, {
124 [15] = DMACH_I2S2_TX, 167 .peri_id = (u8)DMACH_UART2_TX,
125 [16] = DMACH_SPI0_RX, 168 .rqtype = MEMTODEV,
126 [17] = DMACH_SPI0_TX, 169 }, {
127 [18] = DMACH_SPI1_RX, 170 .peri_id = (u8)DMACH_UART3_RX,
128 [19] = DMACH_SPI1_TX, 171 .rqtype = DEVTOMEM,
129 [20] = DMACH_SPI2_RX, 172 }, {
130 [21] = DMACH_SPI2_TX, 173 .peri_id = (u8)DMACH_UART3_TX,
131 [22] = DMACH_PCM0_RX, 174 .rqtype = MEMTODEV,
132 [23] = DMACH_PCM0_TX, 175 }, {
133 [24] = DMACH_PCM1_RX, 176 .peri_id = DMACH_IRDA,
134 [25] = DMACH_PCM1_TX, 177 }, {
135 [26] = DMACH_MSM_REQ0, 178 .peri_id = (u8)DMACH_I2S0_RX,
136 [27] = DMACH_MSM_REQ1, 179 .rqtype = DEVTOMEM,
137 [28] = DMACH_MSM_REQ2, 180 }, {
138 [29] = DMACH_MSM_REQ3, 181 .peri_id = (u8)DMACH_I2S0_TX,
139 [30] = DMACH_MAX, 182 .rqtype = MEMTODEV,
140 [31] = DMACH_MAX, 183 }, {
184 .peri_id = (u8)DMACH_I2S0S_TX,
185 .rqtype = MEMTODEV,
186 }, {
187 .peri_id = (u8)DMACH_I2S1_RX,
188 .rqtype = DEVTOMEM,
189 }, {
190 .peri_id = (u8)DMACH_I2S1_TX,
191 .rqtype = MEMTODEV,
192 }, {
193 .peri_id = (u8)DMACH_I2S2_RX,
194 .rqtype = DEVTOMEM,
195 }, {
196 .peri_id = (u8)DMACH_I2S2_TX,
197 .rqtype = MEMTODEV,
198 }, {
199 .peri_id = (u8)DMACH_SPI0_RX,
200 .rqtype = DEVTOMEM,
201 }, {
202 .peri_id = (u8)DMACH_SPI0_TX,
203 .rqtype = MEMTODEV,
204 }, {
205 .peri_id = (u8)DMACH_SPI1_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_SPI1_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_SPI2_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_SPI2_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_PCM0_RX,
218 .rqtype = DEVTOMEM,
219 }, {
220 .peri_id = (u8)DMACH_PCM1_TX,
221 .rqtype = MEMTODEV,
222 }, {
223 .peri_id = (u8)DMACH_PCM1_RX,
224 .rqtype = DEVTOMEM,
225 }, {
226 .peri_id = (u8)DMACH_PCM1_TX,
227 .rqtype = MEMTODEV,
228 }, {
229 .peri_id = (u8)DMACH_MSM_REQ0,
230 }, {
231 .peri_id = (u8)DMACH_MSM_REQ1,
232 }, {
233 .peri_id = (u8)DMACH_MSM_REQ2,
234 }, {
235 .peri_id = (u8)DMACH_MSM_REQ3,
141 }, 236 },
142}; 237};
143 238
144static struct platform_device s5pc100_device_pdma1 = { 239struct dma_pl330_platdata s5pc100_pdma1_pdata = {
145 .name = "s3c-pl330", 240 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
146 .id = 1, 241 .peri = pdma1_peri,
147 .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource), 242};
148 .resource = s5pc100_pdma1_resource, 243
149 .dev = { 244struct amba_device s5pc100_device_pdma1 = {
245 .dev = {
246 .init_name = "dma-pl330.1",
150 .dma_mask = &dma_dmamask, 247 .dma_mask = &dma_dmamask,
151 .coherent_dma_mask = DMA_BIT_MASK(32), 248 .coherent_dma_mask = DMA_BIT_MASK(32),
152 .platform_data = &s5pc100_pdma1_pdata, 249 .platform_data = &s5pc100_pdma1_pdata,
153 }, 250 },
154}; 251 .res = {
155 252 .start = S5PC100_PA_PDMA1,
156static struct platform_device *s5pc100_dmacs[] __initdata = { 253 .end = S5PC100_PA_PDMA1 + SZ_4K,
157 &s5pc100_device_pdma0, 254 .flags = IORESOURCE_MEM,
158 &s5pc100_device_pdma1, 255 },
256 .irq = {IRQ_PDMA1, NO_IRQ},
257 .periphid = 0x00041330,
159}; 258};
160 259
161static int __init s5pc100_dma_init(void) 260static int __init s5pc100_dma_init(void)
162{ 261{
163 platform_add_devices(s5pc100_dmacs, ARRAY_SIZE(s5pc100_dmacs)); 262 amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
263 amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
164 264
165 return 0; 265 return 0;
166} 266}
diff --git a/arch/arm/mach-s5pc100/include/mach/clkdev.h b/arch/arm/mach-s5pc100/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/mach-s5pc100/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h
index 81209eb1409b..201842a3769e 100644
--- a/arch/arm/mach-s5pc100/include/mach/dma.h
+++ b/arch/arm/mach-s5pc100/include/mach/dma.h
@@ -20,7 +20,7 @@
20#ifndef __MACH_DMA_H 20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H 21#define __MACH_DMA_H
22 22
23/* This platform uses the common S3C DMA API driver for PL330 */ 23/* This platform uses the common DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h> 24#include <plat/dma-pl330.h>
25 25
26#endif /* __MACH_DMA_H */ 26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
deleted file mode 100644
index b34d2f7aae52..000000000000
--- a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - pwm clock and timer support
7 *
8 * Based on mach-s3c6400/include/mach/pwm-clock.h
9 */
10
11/**
12 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
13 * @tcfg: The timer TCFG1 register bits shifted down to 0.
14 *
15 * Return true if the given configuration from TCFG1 is a TCLK instead
16 * any of the TDIV clocks.
17 */
18static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
19{
20 return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
21}
22
23/**
24 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
25 * @tcfg1: The tcfg1 setting, shifted down.
26 *
27 * Get the divisor value for the given tcfg1 setting. We assume the
28 * caller has already checked to see if this is not a TCLK source.
29 */
30static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
31{
32 return 1 << tcfg1;
33}
34
35/**
36 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
37 *
38 * Return true if we have a /1 in the tdiv setting.
39 */
40static inline unsigned int pwm_tdiv_has_div1(void)
41{
42 return 1;
43}
44
45/**
46 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
47 * @div: The divisor to calculate the bit information for.
48 *
49 * Turn a divisor into the necessary bit field for TCFG1.
50 */
51static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
52{
53 return ilog2(div);
54}
55
56#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
index be25879bb2ee..6418c6e8a7b7 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci.c
@@ -11,17 +11,7 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12*/ 12*/
13 13
14#include <linux/kernel.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18#include <linux/io.h>
19
20#include <linux/mmc/card.h>
21#include <linux/mmc/host.h>
22
23#include <plat/regs-sdhci.h>
24#include <plat/sdhci.h>
25 15
26/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ 16/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
27 17
@@ -31,35 +21,3 @@ char *s5pc100_hsmmc_clksrcs[4] = {
31 [2] = "sclk_mmc", /* mmc_bus */ 21 [2] = "sclk_mmc", /* mmc_bus */
32 /* [3] = "48m", - note not successfully used yet */ 22 /* [3] = "48m", - note not successfully used yet */
33}; 23};
34
35
36void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
37 void __iomem *r,
38 struct mmc_ios *ios,
39 struct mmc_card *card)
40{
41 u32 ctrl2, ctrl3;
42
43 /* don't need to alter anything according to card-type */
44
45 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
46
47 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
48 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
49 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
50 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
51 S3C_SDHCI_CTRL2_ENFBCLKRX |
52 S3C_SDHCI_CTRL2_DFCNT_NONE |
53 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
54
55 if (ios->clock < 25 * 1000000)
56 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
57 S3C_SDHCI_CTRL3_FCSEL2 |
58 S3C_SDHCI_CTRL3_FCSEL1 |
59 S3C_SDHCI_CTRL3_FCSEL0);
60 else
61 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
62
63 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
64 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
65}
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index aaeb44a73716..646057ab2e4c 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -11,9 +11,11 @@ if ARCH_S5PV210
11 11
12config CPU_S5PV210 12config CPU_S5PV210
13 bool 13 bool
14 select S3C_PL330_DMA 14 select SAMSUNG_DMADEV
15 select S5P_EXT_INT 15 select S5P_EXT_INT
16 select S5P_HRT 16 select S5P_HRT
17 select S5P_PM if PM
18 select S5P_SLEEP if PM
17 help 19 help
18 Enable S5PV210 CPU support 20 Enable S5PV210 CPU support
19 21
@@ -93,11 +95,13 @@ config MACH_GONI
93 select S3C_DEV_USB_HSOTG 95 select S3C_DEV_USB_HSOTG
94 select S5P_DEV_ONENAND 96 select S5P_DEV_ONENAND
95 select SAMSUNG_DEV_KEYPAD 97 select SAMSUNG_DEV_KEYPAD
98 select S5P_DEV_TV
96 select S5PV210_SETUP_FB_24BPP 99 select S5PV210_SETUP_FB_24BPP
97 select S5PV210_SETUP_I2C1 100 select S5PV210_SETUP_I2C1
98 select S5PV210_SETUP_I2C2 101 select S5PV210_SETUP_I2C2
99 select S5PV210_SETUP_KEYPAD 102 select S5PV210_SETUP_KEYPAD
100 select S5PV210_SETUP_SDHCI 103 select S5PV210_SETUP_SDHCI
104 select S5PV210_SETUP_FIMC
101 help 105 help
102 Machine support for Samsung GONI board 106 Machine support for Samsung GONI board
103 S5PC110(MCP) is one of package option of S5PV210 107 S5PC110(MCP) is one of package option of S5PV210
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index ef7e4668d670..009fbe53df96 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,7 +14,7 @@ obj- :=
14 14
15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o 15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o
16obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o 16obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
17obj-$(CONFIG_PM) += pm.o sleep.o 17obj-$(CONFIG_PM) += pm.o
18 18
19# machine support 19# machine support
20 20
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index f5f8fa89679c..4c5ac7a69e9e 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -174,6 +174,16 @@ static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
174 return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable); 174 return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
175} 175}
176 176
177static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
178{
179 return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
180}
181
182static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
183{
184 return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
185}
186
177static struct clk clk_sclk_hdmi27m = { 187static struct clk clk_sclk_hdmi27m = {
178 .name = "sclk_hdmi27m", 188 .name = "sclk_hdmi27m",
179 .rate = 27000000, 189 .rate = 27000000,
@@ -203,6 +213,11 @@ static struct clk clk_pcmcdclk2 = {
203 .name = "pcmcdclk", 213 .name = "pcmcdclk",
204}; 214};
205 215
216static struct clk dummy_apb_pclk = {
217 .name = "apb_pclk",
218 .id = -1,
219};
220
206static struct clk *clkset_vpllsrc_list[] = { 221static struct clk *clkset_vpllsrc_list[] = {
207 [0] = &clk_fin_vpll, 222 [0] = &clk_fin_vpll,
208 [1] = &clk_sclk_hdmi27m, 223 [1] = &clk_sclk_hdmi27m,
@@ -289,14 +304,14 @@ static struct clk_ops clk_fout_apll_ops = {
289 304
290static struct clk init_clocks_off[] = { 305static struct clk init_clocks_off[] = {
291 { 306 {
292 .name = "pdma", 307 .name = "dma",
293 .devname = "s3c-pl330.0", 308 .devname = "dma-pl330.0",
294 .parent = &clk_hclk_psys.clk, 309 .parent = &clk_hclk_psys.clk,
295 .enable = s5pv210_clk_ip0_ctrl, 310 .enable = s5pv210_clk_ip0_ctrl,
296 .ctrlbit = (1 << 3), 311 .ctrlbit = (1 << 3),
297 }, { 312 }, {
298 .name = "pdma", 313 .name = "dma",
299 .devname = "s3c-pl330.1", 314 .devname = "dma-pl330.1",
300 .parent = &clk_hclk_psys.clk, 315 .parent = &clk_hclk_psys.clk,
301 .enable = s5pv210_clk_ip0_ctrl, 316 .enable = s5pv210_clk_ip0_ctrl,
302 .ctrlbit = (1 << 4), 317 .ctrlbit = (1 << 4),
@@ -330,6 +345,40 @@ static struct clk init_clocks_off[] = {
330 .enable = s5pv210_clk_ip0_ctrl, 345 .enable = s5pv210_clk_ip0_ctrl,
331 .ctrlbit = (1 << 16), 346 .ctrlbit = (1 << 16),
332 }, { 347 }, {
348 .name = "dac",
349 .devname = "s5p-sdo",
350 .parent = &clk_hclk_dsys.clk,
351 .enable = s5pv210_clk_ip1_ctrl,
352 .ctrlbit = (1 << 10),
353 }, {
354 .name = "mixer",
355 .devname = "s5p-mixer",
356 .parent = &clk_hclk_dsys.clk,
357 .enable = s5pv210_clk_ip1_ctrl,
358 .ctrlbit = (1 << 9),
359 }, {
360 .name = "vp",
361 .devname = "s5p-mixer",
362 .parent = &clk_hclk_dsys.clk,
363 .enable = s5pv210_clk_ip1_ctrl,
364 .ctrlbit = (1 << 8),
365 }, {
366 .name = "hdmi",
367 .devname = "s5pv210-hdmi",
368 .parent = &clk_hclk_dsys.clk,
369 .enable = s5pv210_clk_ip1_ctrl,
370 .ctrlbit = (1 << 11),
371 }, {
372 .name = "hdmiphy",
373 .devname = "s5pv210-hdmi",
374 .enable = exynos4_clk_hdmiphy_ctrl,
375 .ctrlbit = (1 << 0),
376 }, {
377 .name = "dacphy",
378 .devname = "s5p-sdo",
379 .enable = exynos4_clk_dac_ctrl,
380 .ctrlbit = (1 << 0),
381 }, {
333 .name = "otg", 382 .name = "otg",
334 .parent = &clk_hclk_psys.clk, 383 .parent = &clk_hclk_psys.clk,
335 .enable = s5pv210_clk_ip1_ctrl, 384 .enable = s5pv210_clk_ip1_ctrl,
@@ -407,6 +456,12 @@ static struct clk init_clocks_off[] = {
407 .enable = s5pv210_clk_ip3_ctrl, 456 .enable = s5pv210_clk_ip3_ctrl,
408 .ctrlbit = (1<<9), 457 .ctrlbit = (1<<9),
409 }, { 458 }, {
459 .name = "i2c",
460 .devname = "s3c2440-hdmiphy-i2c",
461 .parent = &clk_pclk_psys.clk,
462 .enable = s5pv210_clk_ip3_ctrl,
463 .ctrlbit = (1 << 11),
464 }, {
410 .name = "spi", 465 .name = "spi",
411 .devname = "s3c64xx-spi.0", 466 .devname = "s3c64xx-spi.0",
412 .parent = &clk_pclk_psys.clk, 467 .parent = &clk_pclk_psys.clk,
@@ -594,6 +649,23 @@ static struct clksrc_sources clkset_sclk_mixer = {
594 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), 649 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
595}; 650};
596 651
652static struct clksrc_clk clk_sclk_mixer = {
653 .clk = {
654 .name = "sclk_mixer",
655 .enable = s5pv210_clk_mask0_ctrl,
656 .ctrlbit = (1 << 1),
657 },
658 .sources = &clkset_sclk_mixer,
659 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
660};
661
662static struct clksrc_clk *sclk_tv[] = {
663 &clk_sclk_dac,
664 &clk_sclk_pixel,
665 &clk_sclk_hdmi,
666 &clk_sclk_mixer,
667};
668
597static struct clk *clkset_sclk_audio0_list[] = { 669static struct clk *clkset_sclk_audio0_list[] = {
598 [0] = &clk_ext_xtal_mux, 670 [0] = &clk_ext_xtal_mux,
599 [1] = &clk_pcmcdclk0, 671 [1] = &clk_pcmcdclk0,
@@ -777,14 +849,6 @@ static struct clksrc_clk clksrcs[] = {
777 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, 849 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
778 }, { 850 }, {
779 .clk = { 851 .clk = {
780 .name = "sclk_mixer",
781 .enable = s5pv210_clk_mask0_ctrl,
782 .ctrlbit = (1 << 1),
783 },
784 .sources = &clkset_sclk_mixer,
785 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
786 }, {
787 .clk = {
788 .name = "sclk_fimc", 852 .name = "sclk_fimc",
789 .devname = "s5pv210-fimc.0", 853 .devname = "s5pv210-fimc.0",
790 .enable = s5pv210_clk_mask1_ctrl, 854 .enable = s5pv210_clk_mask1_ctrl,
@@ -973,9 +1037,6 @@ static struct clksrc_clk *sysclks[] = {
973 &clk_pclk_psys, 1037 &clk_pclk_psys,
974 &clk_vpllsrc, 1038 &clk_vpllsrc,
975 &clk_sclk_vpll, 1039 &clk_sclk_vpll,
976 &clk_sclk_dac,
977 &clk_sclk_pixel,
978 &clk_sclk_hdmi,
979 &clk_mout_dmc0, 1040 &clk_mout_dmc0,
980 &clk_sclk_dmc0, 1041 &clk_sclk_dmc0,
981 &clk_sclk_audio0, 1042 &clk_sclk_audio0,
@@ -1060,6 +1121,61 @@ static struct clk_ops s5pv210_epll_ops = {
1060 .get_rate = s5p_epll_get_rate, 1121 .get_rate = s5p_epll_get_rate,
1061}; 1122};
1062 1123
1124static u32 vpll_div[][5] = {
1125 { 54000000, 3, 53, 3, 0 },
1126 { 108000000, 3, 53, 2, 0 },
1127};
1128
1129static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
1130{
1131 return clk->rate;
1132}
1133
1134static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
1135{
1136 unsigned int vpll_con;
1137 unsigned int i;
1138
1139 /* Return if nothing changed */
1140 if (clk->rate == rate)
1141 return 0;
1142
1143 vpll_con = __raw_readl(S5P_VPLL_CON);
1144 vpll_con &= ~(0x1 << 27 | \
1145 PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT | \
1146 PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT | \
1147 PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
1148
1149 for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1150 if (vpll_div[i][0] == rate) {
1151 vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
1152 vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
1153 vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
1154 vpll_con |= vpll_div[i][4] << 27;
1155 break;
1156 }
1157 }
1158
1159 if (i == ARRAY_SIZE(vpll_div)) {
1160 printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1161 __func__);
1162 return -EINVAL;
1163 }
1164
1165 __raw_writel(vpll_con, S5P_VPLL_CON);
1166
1167 /* Wait for VPLL lock */
1168 while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
1169 continue;
1170
1171 clk->rate = rate;
1172 return 0;
1173}
1174static struct clk_ops s5pv210_vpll_ops = {
1175 .get_rate = s5pv210_vpll_get_rate,
1176 .set_rate = s5pv210_vpll_set_rate,
1177};
1178
1063void __init_or_cpufreq s5pv210_setup_clocks(void) 1179void __init_or_cpufreq s5pv210_setup_clocks(void)
1064{ 1180{
1065 struct clk *xtal_clk; 1181 struct clk *xtal_clk;
@@ -1108,6 +1224,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
1108 clk_fout_apll.ops = &clk_fout_apll_ops; 1224 clk_fout_apll.ops = &clk_fout_apll_ops;
1109 clk_fout_mpll.rate = mpll; 1225 clk_fout_mpll.rate = mpll;
1110 clk_fout_epll.rate = epll; 1226 clk_fout_epll.rate = epll;
1227 clk_fout_vpll.ops = &s5pv210_vpll_ops;
1111 clk_fout_vpll.rate = vpll; 1228 clk_fout_vpll.rate = vpll;
1112 1229
1113 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", 1230 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
@@ -1153,11 +1270,15 @@ void __init s5pv210_register_clocks(void)
1153 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 1270 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1154 s3c_register_clksrc(sysclks[ptr], 1); 1271 s3c_register_clksrc(sysclks[ptr], 1);
1155 1272
1273 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1274 s3c_register_clksrc(sclk_tv[ptr], 1);
1275
1156 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1276 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1157 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1277 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1158 1278
1159 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1279 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1160 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1280 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1161 1281
1282 s3c24xx_register_clock(&dummy_apb_pclk);
1162 s3c_pwmclk_init(); 1283 s3c_pwmclk_init();
1163} 1284}
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 91145720822c..84ec74633232 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -42,6 +42,7 @@
42#include <plat/keypad-core.h> 42#include <plat/keypad-core.h>
43#include <plat/sdhci.h> 43#include <plat/sdhci.h>
44#include <plat/reset.h> 44#include <plat/reset.h>
45#include <plat/tv-core.h>
45 46
46/* Initial IO mappings */ 47/* Initial IO mappings */
47 48
@@ -145,6 +146,9 @@ void __init s5pv210_map_io(void)
145 146
146 /* Use s5pv210-keypad instead of samsung-keypad */ 147 /* Use s5pv210-keypad instead of samsung-keypad */
147 samsung_keypad_setname("s5pv210-keypad"); 148 samsung_keypad_setname("s5pv210-keypad");
149
150 /* setup TV devices */
151 s5p_hdmi_setname("s5pv210-hdmi");
148} 152}
149 153
150void __init s5pv210_init_clocks(int xtal) 154void __init s5pv210_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 497d3439a142..86b749c18b77 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -1,4 +1,8 @@
1/* 1/* linux/arch/arm/mach-s5pv210/dma.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd. 6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com> 7 * Jaswinder Singh <jassi.brar@samsung.com>
4 * 8 *
@@ -17,151 +21,240 @@
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */ 22 */
19 23
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h>
22 27
28#include <asm/irq.h>
23#include <plat/devs.h> 29#include <plat/devs.h>
24#include <plat/irqs.h> 30#include <plat/irqs.h>
25 31
26#include <mach/map.h> 32#include <mach/map.h>
27#include <mach/irqs.h> 33#include <mach/irqs.h>
28 34#include <mach/dma.h>
29#include <plat/s3c-pl330-pdata.h>
30 35
31static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
32 37
33static struct resource s5pv210_pdma0_resource[] = { 38struct dma_pl330_peri pdma0_peri[28] = {
34 [0] = { 39 {
35 .start = S5PV210_PA_PDMA0, 40 .peri_id = (u8)DMACH_UART0_RX,
36 .end = S5PV210_PA_PDMA0 + SZ_4K, 41 .rqtype = DEVTOMEM,
37 .flags = IORESOURCE_MEM, 42 }, {
38 }, 43 .peri_id = (u8)DMACH_UART0_TX,
39 [1] = { 44 .rqtype = MEMTODEV,
40 .start = IRQ_PDMA0, 45 }, {
41 .end = IRQ_PDMA0, 46 .peri_id = (u8)DMACH_UART1_RX,
42 .flags = IORESOURCE_IRQ, 47 .rqtype = DEVTOMEM,
48 }, {
49 .peri_id = (u8)DMACH_UART1_TX,
50 .rqtype = MEMTODEV,
51 }, {
52 .peri_id = (u8)DMACH_UART2_RX,
53 .rqtype = DEVTOMEM,
54 }, {
55 .peri_id = (u8)DMACH_UART2_TX,
56 .rqtype = MEMTODEV,
57 }, {
58 .peri_id = (u8)DMACH_UART3_RX,
59 .rqtype = DEVTOMEM,
60 }, {
61 .peri_id = (u8)DMACH_UART3_TX,
62 .rqtype = MEMTODEV,
63 }, {
64 .peri_id = DMACH_MAX,
65 }, {
66 .peri_id = (u8)DMACH_I2S0_RX,
67 .rqtype = DEVTOMEM,
68 }, {
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_MAX,
82 }, {
83 .peri_id = (u8)DMACH_MAX,
84 }, {
85 .peri_id = (u8)DMACH_SPI0_RX,
86 .rqtype = DEVTOMEM,
87 }, {
88 .peri_id = (u8)DMACH_SPI0_TX,
89 .rqtype = MEMTODEV,
90 }, {
91 .peri_id = (u8)DMACH_SPI1_RX,
92 .rqtype = DEVTOMEM,
93 }, {
94 .peri_id = (u8)DMACH_SPI1_TX,
95 .rqtype = MEMTODEV,
96 }, {
97 .peri_id = (u8)DMACH_MAX,
98 }, {
99 .peri_id = (u8)DMACH_MAX,
100 }, {
101 .peri_id = (u8)DMACH_AC97_MICIN,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_AC97_PCMIN,
105 .rqtype = DEVTOMEM,
106 }, {
107 .peri_id = (u8)DMACH_AC97_PCMOUT,
108 .rqtype = MEMTODEV,
109 }, {
110 .peri_id = (u8)DMACH_MAX,
111 }, {
112 .peri_id = (u8)DMACH_PWM,
113 }, {
114 .peri_id = (u8)DMACH_SPDIF,
115 .rqtype = MEMTODEV,
43 }, 116 },
44}; 117};
45 118
46static struct s3c_pl330_platdata s5pv210_pdma0_pdata = { 119struct dma_pl330_platdata s5pv210_pdma0_pdata = {
47 .peri = { 120 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
48 [0] = DMACH_UART0_RX, 121 .peri = pdma0_peri,
49 [1] = DMACH_UART0_TX,
50 [2] = DMACH_UART1_RX,
51 [3] = DMACH_UART1_TX,
52 [4] = DMACH_UART2_RX,
53 [5] = DMACH_UART2_TX,
54 [6] = DMACH_UART3_RX,
55 [7] = DMACH_UART3_TX,
56 [8] = DMACH_MAX,
57 [9] = DMACH_I2S0_RX,
58 [10] = DMACH_I2S0_TX,
59 [11] = DMACH_I2S0S_TX,
60 [12] = DMACH_I2S1_RX,
61 [13] = DMACH_I2S1_TX,
62 [14] = DMACH_MAX,
63 [15] = DMACH_MAX,
64 [16] = DMACH_SPI0_RX,
65 [17] = DMACH_SPI0_TX,
66 [18] = DMACH_SPI1_RX,
67 [19] = DMACH_SPI1_TX,
68 [20] = DMACH_MAX,
69 [21] = DMACH_MAX,
70 [22] = DMACH_AC97_MICIN,
71 [23] = DMACH_AC97_PCMIN,
72 [24] = DMACH_AC97_PCMOUT,
73 [25] = DMACH_MAX,
74 [26] = DMACH_PWM,
75 [27] = DMACH_SPDIF,
76 [28] = DMACH_MAX,
77 [29] = DMACH_MAX,
78 [30] = DMACH_MAX,
79 [31] = DMACH_MAX,
80 },
81}; 122};
82 123
83static struct platform_device s5pv210_device_pdma0 = { 124struct amba_device s5pv210_device_pdma0 = {
84 .name = "s3c-pl330", 125 .dev = {
85 .id = 0, 126 .init_name = "dma-pl330.0",
86 .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
87 .resource = s5pv210_pdma0_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask, 127 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32), 128 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5pv210_pdma0_pdata, 129 .platform_data = &s5pv210_pdma0_pdata,
92 }, 130 },
93}; 131 .res = {
94 132 .start = S5PV210_PA_PDMA0,
95static struct resource s5pv210_pdma1_resource[] = { 133 .end = S5PV210_PA_PDMA0 + SZ_4K,
96 [0] = {
97 .start = S5PV210_PA_PDMA1,
98 .end = S5PV210_PA_PDMA1 + SZ_4K,
99 .flags = IORESOURCE_MEM, 134 .flags = IORESOURCE_MEM,
100 }, 135 },
101 [1] = { 136 .irq = {IRQ_PDMA0, NO_IRQ},
102 .start = IRQ_PDMA1, 137 .periphid = 0x00041330,
103 .end = IRQ_PDMA1,
104 .flags = IORESOURCE_IRQ,
105 },
106}; 138};
107 139
108static struct s3c_pl330_platdata s5pv210_pdma1_pdata = { 140struct dma_pl330_peri pdma1_peri[32] = {
109 .peri = { 141 {
110 [0] = DMACH_UART0_RX, 142 .peri_id = (u8)DMACH_UART0_RX,
111 [1] = DMACH_UART0_TX, 143 .rqtype = DEVTOMEM,
112 [2] = DMACH_UART1_RX, 144 }, {
113 [3] = DMACH_UART1_TX, 145 .peri_id = (u8)DMACH_UART0_TX,
114 [4] = DMACH_UART2_RX, 146 .rqtype = MEMTODEV,
115 [5] = DMACH_UART2_TX, 147 }, {
116 [6] = DMACH_UART3_RX, 148 .peri_id = (u8)DMACH_UART1_RX,
117 [7] = DMACH_UART3_TX, 149 .rqtype = DEVTOMEM,
118 [8] = DMACH_MAX, 150 }, {
119 [9] = DMACH_I2S0_RX, 151 .peri_id = (u8)DMACH_UART1_TX,
120 [10] = DMACH_I2S0_TX, 152 .rqtype = MEMTODEV,
121 [11] = DMACH_I2S0S_TX, 153 }, {
122 [12] = DMACH_I2S1_RX, 154 .peri_id = (u8)DMACH_UART2_RX,
123 [13] = DMACH_I2S1_TX, 155 .rqtype = DEVTOMEM,
124 [14] = DMACH_I2S2_RX, 156 }, {
125 [15] = DMACH_I2S2_TX, 157 .peri_id = (u8)DMACH_UART2_TX,
126 [16] = DMACH_SPI0_RX, 158 .rqtype = MEMTODEV,
127 [17] = DMACH_SPI0_TX, 159 }, {
128 [18] = DMACH_SPI1_RX, 160 .peri_id = (u8)DMACH_UART3_RX,
129 [19] = DMACH_SPI1_TX, 161 .rqtype = DEVTOMEM,
130 [20] = DMACH_MAX, 162 }, {
131 [21] = DMACH_MAX, 163 .peri_id = (u8)DMACH_UART3_TX,
132 [22] = DMACH_PCM0_RX, 164 .rqtype = MEMTODEV,
133 [23] = DMACH_PCM0_TX, 165 }, {
134 [24] = DMACH_PCM1_RX, 166 .peri_id = DMACH_MAX,
135 [25] = DMACH_PCM1_TX, 167 }, {
136 [26] = DMACH_MSM_REQ0, 168 .peri_id = (u8)DMACH_I2S0_RX,
137 [27] = DMACH_MSM_REQ1, 169 .rqtype = DEVTOMEM,
138 [28] = DMACH_MSM_REQ2, 170 }, {
139 [29] = DMACH_MSM_REQ3, 171 .peri_id = (u8)DMACH_I2S0_TX,
140 [30] = DMACH_PCM2_RX, 172 .rqtype = MEMTODEV,
141 [31] = DMACH_PCM2_TX, 173 }, {
174 .peri_id = (u8)DMACH_I2S0S_TX,
175 .rqtype = MEMTODEV,
176 }, {
177 .peri_id = (u8)DMACH_I2S1_RX,
178 .rqtype = DEVTOMEM,
179 }, {
180 .peri_id = (u8)DMACH_I2S1_TX,
181 .rqtype = MEMTODEV,
182 }, {
183 .peri_id = (u8)DMACH_I2S2_RX,
184 .rqtype = DEVTOMEM,
185 }, {
186 .peri_id = (u8)DMACH_I2S2_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_SPI0_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_SPI0_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_SPI1_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_SPI1_TX,
199 .rqtype = MEMTODEV,
200 }, {
201 .peri_id = (u8)DMACH_MAX,
202 }, {
203 .peri_id = (u8)DMACH_MAX,
204 }, {
205 .peri_id = (u8)DMACH_PCM0_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_PCM0_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_PCM1_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_PCM1_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_MSM_REQ0,
218 }, {
219 .peri_id = (u8)DMACH_MSM_REQ1,
220 }, {
221 .peri_id = (u8)DMACH_MSM_REQ2,
222 }, {
223 .peri_id = (u8)DMACH_MSM_REQ3,
224 }, {
225 .peri_id = (u8)DMACH_PCM2_RX,
226 .rqtype = DEVTOMEM,
227 }, {
228 .peri_id = (u8)DMACH_PCM2_TX,
229 .rqtype = MEMTODEV,
142 }, 230 },
143}; 231};
144 232
145static struct platform_device s5pv210_device_pdma1 = { 233struct dma_pl330_platdata s5pv210_pdma1_pdata = {
146 .name = "s3c-pl330", 234 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
147 .id = 1, 235 .peri = pdma1_peri,
148 .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), 236};
149 .resource = s5pv210_pdma1_resource, 237
150 .dev = { 238struct amba_device s5pv210_device_pdma1 = {
239 .dev = {
240 .init_name = "dma-pl330.1",
151 .dma_mask = &dma_dmamask, 241 .dma_mask = &dma_dmamask,
152 .coherent_dma_mask = DMA_BIT_MASK(32), 242 .coherent_dma_mask = DMA_BIT_MASK(32),
153 .platform_data = &s5pv210_pdma1_pdata, 243 .platform_data = &s5pv210_pdma1_pdata,
154 }, 244 },
155}; 245 .res = {
156 246 .start = S5PV210_PA_PDMA1,
157static struct platform_device *s5pv210_dmacs[] __initdata = { 247 .end = S5PV210_PA_PDMA1 + SZ_4K,
158 &s5pv210_device_pdma0, 248 .flags = IORESOURCE_MEM,
159 &s5pv210_device_pdma1, 249 },
250 .irq = {IRQ_PDMA1, NO_IRQ},
251 .periphid = 0x00041330,
160}; 252};
161 253
162static int __init s5pv210_dma_init(void) 254static int __init s5pv210_dma_init(void)
163{ 255{
164 platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs)); 256 amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
257 amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
165 258
166 return 0; 259 return 0;
167} 260}
diff --git a/arch/arm/mach-s5pv210/include/mach/clkdev.h b/arch/arm/mach-s5pv210/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/mach-s5pv210/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
index 81209eb1409b..201842a3769e 100644
--- a/arch/arm/mach-s5pv210/include/mach/dma.h
+++ b/arch/arm/mach-s5pv210/include/mach/dma.h
@@ -20,7 +20,7 @@
20#ifndef __MACH_DMA_H 20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H 21#define __MACH_DMA_H
22 22
23/* This platform uses the common S3C DMA API driver for PL330 */ 23/* This platform uses the common DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h> 24#include <plat/dma-pl330.h>
25 25
26#endif /* __MACH_DMA_H */ 26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index b9f9ec33384d..5e0de3a31f3d 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -56,7 +56,7 @@
56#define IRQ_SPI2 S5P_IRQ_VIC1(17) 56#define IRQ_SPI2 S5P_IRQ_VIC1(17)
57#define IRQ_IRDA S5P_IRQ_VIC1(18) 57#define IRQ_IRDA S5P_IRQ_VIC1(18)
58#define IRQ_IIC2 S5P_IRQ_VIC1(19) 58#define IRQ_IIC2 S5P_IRQ_VIC1(19)
59#define IRQ_IIC3 S5P_IRQ_VIC1(20) 59#define IRQ_IIC_HDMIPHY S5P_IRQ_VIC1(20)
60#define IRQ_HSIRX S5P_IRQ_VIC1(21) 60#define IRQ_HSIRX S5P_IRQ_VIC1(21)
61#define IRQ_HSITX S5P_IRQ_VIC1(22) 61#define IRQ_HSITX S5P_IRQ_VIC1(22)
62#define IRQ_UHOST S5P_IRQ_VIC1(23) 62#define IRQ_UHOST S5P_IRQ_VIC1(23)
@@ -86,7 +86,7 @@
86#define IRQ_HDMI S5P_IRQ_VIC2(12) 86#define IRQ_HDMI S5P_IRQ_VIC2(12)
87#define IRQ_IIC1 S5P_IRQ_VIC2(13) 87#define IRQ_IIC1 S5P_IRQ_VIC2(13)
88#define IRQ_MFC S5P_IRQ_VIC2(14) 88#define IRQ_MFC S5P_IRQ_VIC2(14)
89#define IRQ_TVENC S5P_IRQ_VIC2(15) 89#define IRQ_SDO S5P_IRQ_VIC2(15)
90#define IRQ_I2S0 S5P_IRQ_VIC2(16) 90#define IRQ_I2S0 S5P_IRQ_VIC2(16)
91#define IRQ_I2S1 S5P_IRQ_VIC2(17) 91#define IRQ_I2S1 S5P_IRQ_VIC2(17)
92#define IRQ_I2S2 S5P_IRQ_VIC2(18) 92#define IRQ_I2S2 S5P_IRQ_VIC2(18)
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index aac343c180b2..7ff609f1568b 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -90,6 +90,12 @@
90#define S5PV210_PA_FIMC1 0xFB300000 90#define S5PV210_PA_FIMC1 0xFB300000
91#define S5PV210_PA_FIMC2 0xFB400000 91#define S5PV210_PA_FIMC2 0xFB400000
92 92
93#define S5PV210_PA_SDO 0xF9000000
94#define S5PV210_PA_VP 0xF9100000
95#define S5PV210_PA_MIXER 0xF9200000
96#define S5PV210_PA_HDMI 0xFA100000
97#define S5PV210_PA_IIC_HDMIPHY 0xFA900000
98
93/* Compatibiltiy Defines */ 99/* Compatibiltiy Defines */
94 100
95#define S3C_PA_FB S5PV210_PA_FB 101#define S3C_PA_FB S5PV210_PA_FB
@@ -110,6 +116,13 @@
110#define S5P_PA_FIMC2 S5PV210_PA_FIMC2 116#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
111#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS 117#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
112#define S5P_PA_MFC S5PV210_PA_MFC 118#define S5P_PA_MFC S5PV210_PA_MFC
119#define S5P_PA_IIC_HDMIPHY S5PV210_PA_IIC_HDMIPHY
120
121#define S5P_PA_SDO S5PV210_PA_SDO
122#define S5P_PA_VP S5PV210_PA_VP
123#define S5P_PA_MIXER S5PV210_PA_MIXER
124#define S5P_PA_HDMI S5PV210_PA_HDMI
125
113#define S5P_PA_ONENAND S5PC110_PA_ONENAND 126#define S5P_PA_ONENAND S5PC110_PA_ONENAND
114#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA 127#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA
115#define S5P_PA_SDRAM S5PV210_PA_SDRAM 128#define S5P_PA_SDRAM S5PV210_PA_SDRAM
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
index 3e22109e1b7b..eba8aea63ed8 100644
--- a/arch/arm/mach-s5pv210/include/mach/pm-core.h
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -43,4 +43,4 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
43} 43}
44 44
45static inline void s3c_pm_restored_gpios(void) { } 45static inline void s3c_pm_restored_gpios(void) { }
46static inline void s3c_pm_saved_gpios(void) { } 46static inline void samsung_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
deleted file mode 100644
index f8a9f1b330e0..000000000000
--- a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
+++ /dev/null
@@ -1,70 +0,0 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008 Openmoko, Inc.
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
12 *
13 * S5PV210 - pwm clock and timer support
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18*/
19
20#ifndef __ASM_ARCH_PWMCLK_H
21#define __ASM_ARCH_PWMCLK_H __FILE__
22
23/**
24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
25 * @tcfg: The timer TCFG1 register bits shifted down to 0.
26 *
27 * Return true if the given configuration from TCFG1 is a TCLK instead
28 * any of the TDIV clocks.
29 */
30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
31{
32 return tcfg == S3C64XX_TCFG1_MUX_TCLK;
33}
34
35/**
36 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
37 * @tcfg1: The tcfg1 setting, shifted down.
38 *
39 * Get the divisor value for the given tcfg1 setting. We assume the
40 * caller has already checked to see if this is not a TCLK source.
41 */
42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
43{
44 return 1 << tcfg1;
45}
46
47/**
48 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
49 *
50 * Return true if we have a /1 in the tdiv setting.
51 */
52static inline unsigned int pwm_tdiv_has_div1(void)
53{
54 return 1;
55}
56
57/**
58 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
59 * @div: The divisor to calculate the bit information for.
60 *
61 * Turn a divisor into the necessary bit field for TCFG1.
62 */
63static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
64{
65 return ilog2(div);
66}
67
68#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
69
70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 78925c516346..032de66fb8be 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -144,8 +144,9 @@
144 144
145#define S5P_OTHERS S5P_CLKREG(0xE000) 145#define S5P_OTHERS S5P_CLKREG(0xE000)
146#define S5P_OM_STAT S5P_CLKREG(0xE100) 146#define S5P_OM_STAT S5P_CLKREG(0xE100)
147#define S5P_HDMI_PHY_CONTROL S5P_CLKREG(0xE804)
147#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C) 148#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
148#define S5P_DAC_CONTROL S5P_CLKREG(0xE810) 149#define S5P_DAC_PHY_CONTROL S5P_CLKREG(0xE810)
149#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814) 150#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
150#define S5P_MIPI_DPHY_ENABLE (1 << 0) 151#define S5P_MIPI_DPHY_ENABLE (1 << 0)
151#define S5P_MIPI_DPHY_SRESETN (1 << 1) 152#define S5P_MIPI_DPHY_SRESETN (1 << 1)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 061cc7e4f48c..15edcae448b9 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -48,6 +48,11 @@
48#include <plat/s5p-time.h> 48#include <plat/s5p-time.h>
49#include <plat/mfc.h> 49#include <plat/mfc.h>
50#include <plat/regs-fb-v4.h> 50#include <plat/regs-fb-v4.h>
51#include <plat/camport.h>
52
53#include <media/v4l2-mediabus.h>
54#include <media/s5p_fimc.h>
55#include <media/noon010pc30.h>
51 56
52/* Following are default values for UCON, ULCON and UFCON UART registers */ 57/* Following are default values for UCON, ULCON and UFCON UART registers */
53#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 58#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -272,6 +277,14 @@ static void __init goni_tsp_init(void)
272 i2c2_devs[0].irq = gpio_to_irq(gpio); 277 i2c2_devs[0].irq = gpio_to_irq(gpio);
273} 278}
274 279
280static void goni_camera_init(void)
281{
282 s5pv210_fimc_setup_gpio(S5P_CAMPORT_A);
283
284 /* Set max driver strength on CAM_A_CLKOUT pin. */
285 s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4);
286}
287
275/* MAX8998 regulators */ 288/* MAX8998 regulators */
276#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) 289#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
277 290
@@ -285,6 +298,7 @@ static struct regulator_consumer_supply goni_ldo5_consumers[] = {
285 298
286static struct regulator_consumer_supply goni_ldo8_consumers[] = { 299static struct regulator_consumer_supply goni_ldo8_consumers[] = {
287 REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"), 300 REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"),
301 REGULATOR_SUPPLY("vdd33a_dac", "s5p-sdo"),
288}; 302};
289 303
290static struct regulator_consumer_supply goni_ldo11_consumers[] = { 304static struct regulator_consumer_supply goni_ldo11_consumers[] = {
@@ -475,6 +489,10 @@ static struct regulator_consumer_supply buck1_consumer =
475static struct regulator_consumer_supply buck2_consumer = 489static struct regulator_consumer_supply buck2_consumer =
476 REGULATOR_SUPPLY("vddint", NULL); 490 REGULATOR_SUPPLY("vddint", NULL);
477 491
492static struct regulator_consumer_supply buck3_consumer =
493 REGULATOR_SUPPLY("vdet", "s5p-sdo");
494
495
478static struct regulator_init_data goni_buck1_data = { 496static struct regulator_init_data goni_buck1_data = {
479 .constraints = { 497 .constraints = {
480 .name = "VARM_1.2V", 498 .name = "VARM_1.2V",
@@ -511,6 +529,8 @@ static struct regulator_init_data goni_buck3_data = {
511 .enabled = 1, 529 .enabled = 1,
512 }, 530 },
513 }, 531 },
532 .num_consumer_supplies = 1,
533 .consumer_supplies = &buck3_consumer,
514}; 534};
515 535
516static struct regulator_init_data goni_buck4_data = { 536static struct regulator_init_data goni_buck4_data = {
@@ -801,6 +821,34 @@ static void goni_setup_sdhci(void)
801 s3c_sdhci2_set_platdata(&goni_hsmmc2_data); 821 s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
802}; 822};
803 823
824static struct noon010pc30_platform_data noon010pc30_pldata = {
825 .clk_rate = 16000000UL,
826 .gpio_nreset = S5PV210_GPB(2), /* CAM_CIF_NRST */
827 .gpio_nstby = S5PV210_GPB(0), /* CAM_CIF_NSTBY */
828};
829
830static struct i2c_board_info noon010pc30_board_info = {
831 I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1),
832 .platform_data = &noon010pc30_pldata,
833};
834
835static struct s5p_fimc_isp_info goni_camera_sensors[] = {
836 {
837 .mux_id = 0,
838 .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
839 V4L2_MBUS_VSYNC_ACTIVE_LOW,
840 .bus_type = FIMC_ITU_601,
841 .board_info = &noon010pc30_board_info,
842 .i2c_bus_num = 0,
843 .clk_frequency = 16000000UL,
844 },
845};
846
847struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
848 .isp_info = goni_camera_sensors,
849 .num_clients = ARRAY_SIZE(goni_camera_sensors),
850};
851
804static struct platform_device *goni_devices[] __initdata = { 852static struct platform_device *goni_devices[] __initdata = {
805 &s3c_device_fb, 853 &s3c_device_fb,
806 &s5p_device_onenand, 854 &s5p_device_onenand,
@@ -812,10 +860,13 @@ static struct platform_device *goni_devices[] __initdata = {
812 &s5p_device_mfc, 860 &s5p_device_mfc,
813 &s5p_device_mfc_l, 861 &s5p_device_mfc_l,
814 &s5p_device_mfc_r, 862 &s5p_device_mfc_r,
863 &s5p_device_mixer,
864 &s5p_device_sdo,
815 &s3c_device_i2c0, 865 &s3c_device_i2c0,
816 &s5p_device_fimc0, 866 &s5p_device_fimc0,
817 &s5p_device_fimc1, 867 &s5p_device_fimc1,
818 &s5p_device_fimc2, 868 &s5p_device_fimc2,
869 &s5p_device_fimc_md,
819 &s3c_device_hsmmc0, 870 &s3c_device_hsmmc0,
820 &s3c_device_hsmmc1, 871 &s3c_device_hsmmc1,
821 &s3c_device_hsmmc2, 872 &s3c_device_hsmmc2,
@@ -884,6 +935,12 @@ static void __init goni_machine_init(void)
884 /* FB */ 935 /* FB */
885 s3c_fb_set_platdata(&goni_lcd_pdata); 936 s3c_fb_set_platdata(&goni_lcd_pdata);
886 937
938 /* FIMC */
939 s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata),
940 &s5p_device_fimc_md);
941
942 goni_camera_init();
943
887 /* SPI */ 944 /* SPI */
888 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 945 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
889 946
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
index a83b6c909f6b..6b8ccc4d35fd 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci.c
@@ -10,17 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#include <linux/kernel.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
21
22#include <plat/regs-sdhci.h>
23#include <plat/sdhci.h>
24 14
25/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ 15/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
26 16
@@ -30,34 +20,3 @@ char *s5pv210_hsmmc_clksrcs[4] = {
30 [2] = "sclk_mmc", /* mmc_bus */ 20 [2] = "sclk_mmc", /* mmc_bus */
31 /* [3] = NULL, - reserved */ 21 /* [3] = NULL, - reserved */
32}; 22};
33
34void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
35 void __iomem *r,
36 struct mmc_ios *ios,
37 struct mmc_card *card)
38{
39 u32 ctrl2, ctrl3;
40
41 /* don't need to alter anything according to card-type */
42
43 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
44
45 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
46 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
47 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
48 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
49 S3C_SDHCI_CTRL2_ENFBCLKRX |
50 S3C_SDHCI_CTRL2_DFCNT_NONE |
51 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
52
53 if (ios->clock < 25 * 1000000)
54 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
55 S3C_SDHCI_CTRL3_FCSEL2 |
56 S3C_SDHCI_CTRL3_FCSEL1 |
57 S3C_SDHCI_CTRL3_FCSEL0);
58 else
59 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
60
61 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
62 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
63}
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
deleted file mode 100644
index e3452ccd4b08..000000000000
--- a/arch/arm/mach-s5pv210/sleep.S
+++ /dev/null
@@ -1,52 +0,0 @@
1/* linux/arch/arm/plat-s5p/sleep.S
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV210 power Manager (Suspend-To-RAM) support
7 * Based on S3C2410 sleep code by:
8 * Ben Dooks, (c) 2004 Simtec Electronics
9 *
10 * Based on PXA/SA1100 sleep code by:
11 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
12 * Cliff Brake, (c) 2001
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/linkage.h>
30#include <asm/assembler.h>
31#include <asm/memory.h>
32
33 .text
34
35 /* sleep magic, to allow the bootloader to check for an valid
36 * image to resume to. Must be the first word before the
37 * s3c_cpu_resume entry.
38 */
39
40 .word 0x2bedf00d
41
42 /* s3c_cpu_resume
43 *
44 * resume code entry for bootloader to call
45 *
46 * we must put this code here in the data segment as we have no
47 * other way of restoring the stack pointer after sleep, and we
48 * must not write to the code segment (code is read-only)
49 */
50
51ENTRY(s3c_cpu_resume)
52 b cpu_resume
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 7283d6913fbf..a3aa0f6df964 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -933,7 +933,7 @@ static struct platform_device ap4evb_camera = {
933static struct sh_csi2_client_config csi2_clients[] = { 933static struct sh_csi2_client_config csi2_clients[] = {
934 { 934 {
935 .phy = SH_CSI2_PHY_MAIN, 935 .phy = SH_CSI2_PHY_MAIN,
936 .lanes = 3, 936 .lanes = 0, /* default: 2 lanes */
937 .channel = 0, 937 .channel = 0,
938 .pdev = &ap4evb_camera, 938 .pdev = &ap4evb_camera,
939 }, 939 },
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 6c621c2ce0bc..9c5e598e0e3d 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1223,9 +1223,10 @@ static struct soc_camera_platform_info camera_info = {
1223 .width = 640, 1223 .width = 640,
1224 .height = 480, 1224 .height = 480,
1225 }, 1225 },
1226 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | 1226 .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1227 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 | 1227 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1228 SOCAM_DATA_ACTIVE_HIGH, 1228 V4L2_MBUS_DATA_ACTIVE_HIGH,
1229 .mbus_type = V4L2_MBUS_PARALLEL,
1229 .set_capture = camera_set_capture, 1230 .set_capture = camera_set_capture,
1230}; 1231};
1231 1232
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 8c5b3029b39f..d8973ac46bc4 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,7 +9,6 @@ config PLAT_S3C24XX
9 select NO_IOPORT 9 select NO_IOPORT
10 select ARCH_REQUIRE_GPIOLIB 10 select ARCH_REQUIRE_GPIOLIB
11 select S3C_DEV_NAND 11 select S3C_DEV_NAND
12 select S3C_GPIO_CFG_S3C24XX
13 help 12 help
14 Base platform code for any Samsung S3C24XX device 13 Base platform code for any Samsung S3C24XX device
15 14
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 0291bd6e236e..b2b01125de66 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -14,9 +14,7 @@ obj- :=
14 14
15obj-y += cpu.o 15obj-y += cpu.o
16obj-y += irq.o 16obj-y += irq.o
17obj-y += devs.o 17obj-y += dev-uart.o
18obj-y += gpio.o
19obj-y += gpiolib.o
20obj-y += clock.o 18obj-y += clock.o
21obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o 19obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o
22 20
diff --git a/arch/arm/plat-s3c24xx/dev-uart.c b/arch/arm/plat-s3c24xx/dev-uart.c
new file mode 100644
index 000000000000..9ab22e662fff
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/dev-uart.c
@@ -0,0 +1,100 @@
1/* linux/arch/arm/plat-s3c24xx/dev-uart.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Base S3C24XX UART resource and platform device definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/serial_core.h>
18#include <linux/platform_device.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach/map.h>
22#include <asm/mach/irq.h>
23#include <mach/hardware.h>
24#include <mach/map.h>
25
26#include <plat/devs.h>
27#include <plat/regs-serial.h>
28
29/* Serial port registrations */
30
31static struct resource s3c2410_uart0_resource[] = {
32 [0] = {
33 .start = S3C2410_PA_UART0,
34 .end = S3C2410_PA_UART0 + 0x3fff,
35 .flags = IORESOURCE_MEM,
36 },
37 [1] = {
38 .start = IRQ_S3CUART_RX0,
39 .end = IRQ_S3CUART_ERR0,
40 .flags = IORESOURCE_IRQ,
41 }
42};
43
44static struct resource s3c2410_uart1_resource[] = {
45 [0] = {
46 .start = S3C2410_PA_UART1,
47 .end = S3C2410_PA_UART1 + 0x3fff,
48 .flags = IORESOURCE_MEM,
49 },
50 [1] = {
51 .start = IRQ_S3CUART_RX1,
52 .end = IRQ_S3CUART_ERR1,
53 .flags = IORESOURCE_IRQ,
54 }
55};
56
57static struct resource s3c2410_uart2_resource[] = {
58 [0] = {
59 .start = S3C2410_PA_UART2,
60 .end = S3C2410_PA_UART2 + 0x3fff,
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64 .start = IRQ_S3CUART_RX2,
65 .end = IRQ_S3CUART_ERR2,
66 .flags = IORESOURCE_IRQ,
67 }
68};
69
70static struct resource s3c2410_uart3_resource[] = {
71 [0] = {
72 .start = S3C2443_PA_UART3,
73 .end = S3C2443_PA_UART3 + 0x3fff,
74 .flags = IORESOURCE_MEM,
75 },
76 [1] = {
77 .start = IRQ_S3CUART_RX3,
78 .end = IRQ_S3CUART_ERR3,
79 .flags = IORESOURCE_IRQ,
80 },
81};
82
83struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
84 [0] = {
85 .resources = s3c2410_uart0_resource,
86 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
87 },
88 [1] = {
89 .resources = s3c2410_uart1_resource,
90 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
91 },
92 [2] = {
93 .resources = s3c2410_uart2_resource,
94 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
95 },
96 [3] = {
97 .resources = s3c2410_uart3_resource,
98 .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
99 },
100};
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
deleted file mode 100644
index a76bf2df3333..000000000000
--- a/arch/arm/plat-s3c24xx/devs.c
+++ /dev/null
@@ -1,528 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/devs.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Base S3C24XX platform device definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/serial_core.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/dma-mapping.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30#include <mach/fb.h>
31#include <mach/hardware.h>
32#include <mach/dma.h>
33#include <mach/irqs.h>
34#include <asm/irq.h>
35
36#include <plat/regs-serial.h>
37#include <plat/udc.h>
38#include <plat/mci.h>
39
40#include <plat/devs.h>
41#include <plat/cpu.h>
42#include <plat/regs-spi.h>
43#include <plat/ts.h>
44
45/* Serial port registrations */
46
47static struct resource s3c2410_uart0_resource[] = {
48 [0] = {
49 .start = S3C2410_PA_UART0,
50 .end = S3C2410_PA_UART0 + 0x3fff,
51 .flags = IORESOURCE_MEM,
52 },
53 [1] = {
54 .start = IRQ_S3CUART_RX0,
55 .end = IRQ_S3CUART_ERR0,
56 .flags = IORESOURCE_IRQ,
57 }
58};
59
60static struct resource s3c2410_uart1_resource[] = {
61 [0] = {
62 .start = S3C2410_PA_UART1,
63 .end = S3C2410_PA_UART1 + 0x3fff,
64 .flags = IORESOURCE_MEM,
65 },
66 [1] = {
67 .start = IRQ_S3CUART_RX1,
68 .end = IRQ_S3CUART_ERR1,
69 .flags = IORESOURCE_IRQ,
70 }
71};
72
73static struct resource s3c2410_uart2_resource[] = {
74 [0] = {
75 .start = S3C2410_PA_UART2,
76 .end = S3C2410_PA_UART2 + 0x3fff,
77 .flags = IORESOURCE_MEM,
78 },
79 [1] = {
80 .start = IRQ_S3CUART_RX2,
81 .end = IRQ_S3CUART_ERR2,
82 .flags = IORESOURCE_IRQ,
83 }
84};
85
86static struct resource s3c2410_uart3_resource[] = {
87 [0] = {
88 .start = S3C2443_PA_UART3,
89 .end = S3C2443_PA_UART3 + 0x3fff,
90 .flags = IORESOURCE_MEM,
91 },
92 [1] = {
93 .start = IRQ_S3CUART_RX3,
94 .end = IRQ_S3CUART_ERR3,
95 .flags = IORESOURCE_IRQ,
96 },
97};
98
99struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
100 [0] = {
101 .resources = s3c2410_uart0_resource,
102 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
103 },
104 [1] = {
105 .resources = s3c2410_uart1_resource,
106 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
107 },
108 [2] = {
109 .resources = s3c2410_uart2_resource,
110 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
111 },
112 [3] = {
113 .resources = s3c2410_uart3_resource,
114 .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
115 },
116};
117
118/* LCD Controller */
119
120static struct resource s3c_lcd_resource[] = {
121 [0] = {
122 .start = S3C24XX_PA_LCD,
123 .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
124 .flags = IORESOURCE_MEM,
125 },
126 [1] = {
127 .start = IRQ_LCD,
128 .end = IRQ_LCD,
129 .flags = IORESOURCE_IRQ,
130 }
131
132};
133
134static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
135
136struct platform_device s3c_device_lcd = {
137 .name = "s3c2410-lcd",
138 .id = -1,
139 .num_resources = ARRAY_SIZE(s3c_lcd_resource),
140 .resource = s3c_lcd_resource,
141 .dev = {
142 .dma_mask = &s3c_device_lcd_dmamask,
143 .coherent_dma_mask = 0xffffffffUL
144 }
145};
146
147EXPORT_SYMBOL(s3c_device_lcd);
148
149void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
150{
151 struct s3c2410fb_mach_info *npd;
152
153 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
154 if (npd) {
155 npd->displays = kmemdup(pd->displays,
156 sizeof(struct s3c2410fb_display) * npd->num_displays,
157 GFP_KERNEL);
158 if (!npd->displays)
159 printk(KERN_ERR "no memory for LCD display data\n");
160 } else {
161 printk(KERN_ERR "no memory for LCD platform data\n");
162 }
163}
164
165/* Touchscreen */
166
167static struct resource s3c_ts_resource[] = {
168 [0] = {
169 .start = S3C24XX_PA_ADC,
170 .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
171 .flags = IORESOURCE_MEM,
172 },
173 [1] = {
174 .start = IRQ_TC,
175 .end = IRQ_TC,
176 .flags = IORESOURCE_IRQ,
177 },
178
179};
180
181struct platform_device s3c_device_ts = {
182 .name = "s3c2410-ts",
183 .id = -1,
184 .dev.parent = &s3c_device_adc.dev,
185 .num_resources = ARRAY_SIZE(s3c_ts_resource),
186 .resource = s3c_ts_resource,
187};
188EXPORT_SYMBOL(s3c_device_ts);
189
190void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
191{
192 s3c_set_platdata(hard_s3c2410ts_info,
193 sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
194}
195
196/* USB Device (Gadget)*/
197
198static struct resource s3c_usbgadget_resource[] = {
199 [0] = {
200 .start = S3C24XX_PA_USBDEV,
201 .end = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
202 .flags = IORESOURCE_MEM,
203 },
204 [1] = {
205 .start = IRQ_USBD,
206 .end = IRQ_USBD,
207 .flags = IORESOURCE_IRQ,
208 }
209
210};
211
212struct platform_device s3c_device_usbgadget = {
213 .name = "s3c2410-usbgadget",
214 .id = -1,
215 .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
216 .resource = s3c_usbgadget_resource,
217};
218
219EXPORT_SYMBOL(s3c_device_usbgadget);
220
221void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
222{
223 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
224}
225
226/* USB High Speed 2.0 Device (Gadget) */
227static struct resource s3c_hsudc_resource[] = {
228 [0] = {
229 .start = S3C2416_PA_HSUDC,
230 .end = S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,
231 .flags = IORESOURCE_MEM,
232 },
233 [1] = {
234 .start = IRQ_USBD,
235 .end = IRQ_USBD,
236 .flags = IORESOURCE_IRQ,
237 }
238};
239
240static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);
241
242struct platform_device s3c_device_usb_hsudc = {
243 .name = "s3c-hsudc",
244 .id = -1,
245 .num_resources = ARRAY_SIZE(s3c_hsudc_resource),
246 .resource = s3c_hsudc_resource,
247 .dev = {
248 .dma_mask = &s3c_hsudc_dmamask,
249 .coherent_dma_mask = DMA_BIT_MASK(32),
250 },
251};
252
253void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
254{
255 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
256}
257
258/* IIS */
259
260static struct resource s3c_iis_resource[] = {
261 [0] = {
262 .start = S3C24XX_PA_IIS,
263 .end = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
264 .flags = IORESOURCE_MEM,
265 }
266};
267
268static u64 s3c_device_iis_dmamask = 0xffffffffUL;
269
270struct platform_device s3c_device_iis = {
271 .name = "s3c24xx-iis",
272 .id = -1,
273 .num_resources = ARRAY_SIZE(s3c_iis_resource),
274 .resource = s3c_iis_resource,
275 .dev = {
276 .dma_mask = &s3c_device_iis_dmamask,
277 .coherent_dma_mask = 0xffffffffUL
278 }
279};
280
281EXPORT_SYMBOL(s3c_device_iis);
282
283/* RTC */
284
285static struct resource s3c_rtc_resource[] = {
286 [0] = {
287 .start = S3C24XX_PA_RTC,
288 .end = S3C24XX_PA_RTC + 0xff,
289 .flags = IORESOURCE_MEM,
290 },
291 [1] = {
292 .start = IRQ_RTC,
293 .end = IRQ_RTC,
294 .flags = IORESOURCE_IRQ,
295 },
296 [2] = {
297 .start = IRQ_TICK,
298 .end = IRQ_TICK,
299 .flags = IORESOURCE_IRQ
300 }
301};
302
303struct platform_device s3c_device_rtc = {
304 .name = "s3c2410-rtc",
305 .id = -1,
306 .num_resources = ARRAY_SIZE(s3c_rtc_resource),
307 .resource = s3c_rtc_resource,
308};
309
310EXPORT_SYMBOL(s3c_device_rtc);
311
312/* ADC */
313
314static struct resource s3c_adc_resource[] = {
315 [0] = {
316 .start = S3C24XX_PA_ADC,
317 .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
318 .flags = IORESOURCE_MEM,
319 },
320 [1] = {
321 .start = IRQ_TC,
322 .end = IRQ_TC,
323 .flags = IORESOURCE_IRQ,
324 },
325 [2] = {
326 .start = IRQ_ADC,
327 .end = IRQ_ADC,
328 .flags = IORESOURCE_IRQ,
329 }
330
331};
332
333struct platform_device s3c_device_adc = {
334 .name = "s3c24xx-adc",
335 .id = -1,
336 .num_resources = ARRAY_SIZE(s3c_adc_resource),
337 .resource = s3c_adc_resource,
338};
339
340/* SDI */
341
342static struct resource s3c_sdi_resource[] = {
343 [0] = {
344 .start = S3C24XX_PA_SDI,
345 .end = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1,
346 .flags = IORESOURCE_MEM,
347 },
348 [1] = {
349 .start = IRQ_SDI,
350 .end = IRQ_SDI,
351 .flags = IORESOURCE_IRQ,
352 }
353
354};
355
356struct platform_device s3c_device_sdi = {
357 .name = "s3c2410-sdi",
358 .id = -1,
359 .num_resources = ARRAY_SIZE(s3c_sdi_resource),
360 .resource = s3c_sdi_resource,
361};
362
363EXPORT_SYMBOL(s3c_device_sdi);
364
365void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
366{
367 s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
368 &s3c_device_sdi);
369}
370
371
372/* SPI (0) */
373
374static struct resource s3c_spi0_resource[] = {
375 [0] = {
376 .start = S3C24XX_PA_SPI,
377 .end = S3C24XX_PA_SPI + 0x1f,
378 .flags = IORESOURCE_MEM,
379 },
380 [1] = {
381 .start = IRQ_SPI0,
382 .end = IRQ_SPI0,
383 .flags = IORESOURCE_IRQ,
384 }
385
386};
387
388static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
389
390struct platform_device s3c_device_spi0 = {
391 .name = "s3c2410-spi",
392 .id = 0,
393 .num_resources = ARRAY_SIZE(s3c_spi0_resource),
394 .resource = s3c_spi0_resource,
395 .dev = {
396 .dma_mask = &s3c_device_spi0_dmamask,
397 .coherent_dma_mask = 0xffffffffUL
398 }
399};
400
401EXPORT_SYMBOL(s3c_device_spi0);
402
403/* SPI (1) */
404
405static struct resource s3c_spi1_resource[] = {
406 [0] = {
407 .start = S3C24XX_PA_SPI + S3C2410_SPI1,
408 .end = S3C24XX_PA_SPI + S3C2410_SPI1 + 0x1f,
409 .flags = IORESOURCE_MEM,
410 },
411 [1] = {
412 .start = IRQ_SPI1,
413 .end = IRQ_SPI1,
414 .flags = IORESOURCE_IRQ,
415 }
416
417};
418
419static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
420
421struct platform_device s3c_device_spi1 = {
422 .name = "s3c2410-spi",
423 .id = 1,
424 .num_resources = ARRAY_SIZE(s3c_spi1_resource),
425 .resource = s3c_spi1_resource,
426 .dev = {
427 .dma_mask = &s3c_device_spi1_dmamask,
428 .coherent_dma_mask = 0xffffffffUL
429 }
430};
431
432EXPORT_SYMBOL(s3c_device_spi1);
433
434#ifdef CONFIG_CPU_S3C2440
435
436/* Camif Controller */
437
438static struct resource s3c_camif_resource[] = {
439 [0] = {
440 .start = S3C2440_PA_CAMIF,
441 .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
442 .flags = IORESOURCE_MEM,
443 },
444 [1] = {
445 .start = IRQ_CAM,
446 .end = IRQ_CAM,
447 .flags = IORESOURCE_IRQ,
448 }
449
450};
451
452static u64 s3c_device_camif_dmamask = 0xffffffffUL;
453
454struct platform_device s3c_device_camif = {
455 .name = "s3c2440-camif",
456 .id = -1,
457 .num_resources = ARRAY_SIZE(s3c_camif_resource),
458 .resource = s3c_camif_resource,
459 .dev = {
460 .dma_mask = &s3c_device_camif_dmamask,
461 .coherent_dma_mask = 0xffffffffUL
462 }
463};
464
465EXPORT_SYMBOL(s3c_device_camif);
466
467/* AC97 */
468
469static struct resource s3c_ac97_resource[] = {
470 [0] = {
471 .start = S3C2440_PA_AC97,
472 .end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
473 .flags = IORESOURCE_MEM,
474 },
475 [1] = {
476 .start = IRQ_S3C244x_AC97,
477 .end = IRQ_S3C244x_AC97,
478 .flags = IORESOURCE_IRQ,
479 },
480 [2] = {
481 .name = "PCM out",
482 .start = DMACH_PCM_OUT,
483 .end = DMACH_PCM_OUT,
484 .flags = IORESOURCE_DMA,
485 },
486 [3] = {
487 .name = "PCM in",
488 .start = DMACH_PCM_IN,
489 .end = DMACH_PCM_IN,
490 .flags = IORESOURCE_DMA,
491 },
492 [4] = {
493 .name = "Mic in",
494 .start = DMACH_MIC_IN,
495 .end = DMACH_MIC_IN,
496 .flags = IORESOURCE_DMA,
497 },
498};
499
500static u64 s3c_device_audio_dmamask = 0xffffffffUL;
501
502struct platform_device s3c_device_ac97 = {
503 .name = "samsung-ac97",
504 .id = -1,
505 .num_resources = ARRAY_SIZE(s3c_ac97_resource),
506 .resource = s3c_ac97_resource,
507 .dev = {
508 .dma_mask = &s3c_device_audio_dmamask,
509 .coherent_dma_mask = 0xffffffffUL
510 }
511};
512
513EXPORT_SYMBOL(s3c_device_ac97);
514
515/* ASoC I2S */
516
517struct platform_device s3c2412_device_iis = {
518 .name = "s3c2412-iis",
519 .id = -1,
520 .dev = {
521 .dma_mask = &s3c_device_audio_dmamask,
522 .coherent_dma_mask = 0xffffffffUL
523 }
524};
525
526EXPORT_SYMBOL(s3c2412_device_iis);
527
528#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 539bd0e3defd..53754bcf15a7 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config);
1094 * 1094 *
1095 * configure the dma source/destination hardware type and address 1095 * configure the dma source/destination hardware type and address
1096 * 1096 *
1097 * source: S3C2410_DMASRC_HW: source is hardware 1097 * source: DMA_FROM_DEVICE: source is hardware
1098 * S3C2410_DMASRC_MEM: source is memory 1098 * DMA_TO_DEVICE: source is memory
1099 * 1099 *
1100 * devaddr: physical address of the source 1100 * devaddr: physical address of the source
1101*/ 1101*/
1102 1102
1103int s3c2410_dma_devconfig(enum dma_ch channel, 1103int s3c2410_dma_devconfig(enum dma_ch channel,
1104 enum s3c2410_dmasrc source, 1104 enum dma_data_direction source,
1105 unsigned long devaddr) 1105 unsigned long devaddr)
1106{ 1106{
1107 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); 1107 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
1131 hwcfg |= S3C2410_DISRCC_INC; 1131 hwcfg |= S3C2410_DISRCC_INC;
1132 1132
1133 switch (source) { 1133 switch (source) {
1134 case S3C2410_DMASRC_HW: 1134 case DMA_FROM_DEVICE:
1135 /* source is hardware */ 1135 /* source is hardware */
1136 pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n", 1136 pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
1137 __func__, devaddr, hwcfg); 1137 __func__, devaddr, hwcfg);
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel,
1142 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); 1142 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1143 break; 1143 break;
1144 1144
1145 case S3C2410_DMASRC_MEM: 1145 case DMA_TO_DEVICE:
1146 /* source is memory */ 1146 /* source is memory */
1147 pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n", 1147 pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
1148 __func__, devaddr, hwcfg); 1148 __func__, devaddr, hwcfg);
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
deleted file mode 100644
index 2f3d7c089dfa..000000000000
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ /dev/null
@@ -1,96 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/gpio.c
2 *
3 * Copyright (c) 2004-2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX GPIO support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28#include <linux/gpio.h>
29#include <linux/io.h>
30
31#include <mach/hardware.h>
32#include <mach/gpio-fns.h>
33#include <asm/irq.h>
34
35#include <mach/regs-gpio.h>
36
37#include <plat/gpio-core.h>
38
39/* gpiolib wrappers until these are totally eliminated */
40
41void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
42{
43 int ret;
44
45 WARN_ON(to); /* should be none of these left */
46
47 if (!to) {
48 /* if pull is enabled, try first with up, and if that
49 * fails, try using down */
50
51 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
52 if (ret)
53 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
54 } else {
55 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
56 }
57}
58EXPORT_SYMBOL(s3c2410_gpio_pullup);
59
60void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
61{
62 /* do this via gpiolib until all users removed */
63
64 gpio_request(pin, "temporary");
65 gpio_set_value(pin, to);
66 gpio_free(pin);
67}
68
69EXPORT_SYMBOL(s3c2410_gpio_setpin);
70
71unsigned int s3c2410_gpio_getpin(unsigned int pin)
72{
73 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
74 unsigned long offs = pin - chip->chip.base;
75
76 return __raw_readl(chip->base + 0x04) & (1<< offs);
77}
78
79EXPORT_SYMBOL(s3c2410_gpio_getpin);
80
81unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
82{
83 unsigned long flags;
84 unsigned long misccr;
85
86 local_irq_save(flags);
87 misccr = __raw_readl(S3C24XX_MISCCR);
88 misccr &= ~clear;
89 misccr ^= change;
90 __raw_writel(misccr, S3C24XX_MISCCR);
91 local_irq_restore(flags);
92
93 return misccr;
94}
95
96EXPORT_SYMBOL(s3c2410_modify_misccr);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
deleted file mode 100644
index 243b6411050d..000000000000
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ /dev/null
@@ -1,229 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/gpiolib.c
2 *
3 * Copyright (c) 2008-2010 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX GPIOlib support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License.
12*/
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/interrupt.h>
18#include <linux/sysdev.h>
19#include <linux/ioport.h>
20#include <linux/io.h>
21#include <linux/gpio.h>
22
23#include <plat/gpio-core.h>
24#include <plat/gpio-cfg.h>
25#include <plat/gpio-cfg-helpers.h>
26#include <mach/hardware.h>
27#include <asm/irq.h>
28#include <plat/pm.h>
29
30#include <mach/regs-gpio.h>
31
32static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
33{
34 return -EINVAL;
35}
36
37static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
38 unsigned offset, int value)
39{
40 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
41 void __iomem *base = ourchip->base;
42 unsigned long flags;
43 unsigned long dat;
44 unsigned long con;
45
46 local_irq_save(flags);
47
48 con = __raw_readl(base + 0x00);
49 dat = __raw_readl(base + 0x04);
50
51 dat &= ~(1 << offset);
52 if (value)
53 dat |= 1 << offset;
54
55 __raw_writel(dat, base + 0x04);
56
57 con &= ~(1 << offset);
58
59 __raw_writel(con, base + 0x00);
60 __raw_writel(dat, base + 0x04);
61
62 local_irq_restore(flags);
63 return 0;
64}
65
66static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
67{
68 if (offset < 4)
69 return IRQ_EINT0 + offset;
70
71 if (offset < 8)
72 return IRQ_EINT4 + offset - 4;
73
74 return -EINVAL;
75}
76
77static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
78 .set_config = s3c_gpio_setcfg_s3c24xx_a,
79 .get_config = s3c_gpio_getcfg_s3c24xx_a,
80};
81
82struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
83 .set_config = s3c_gpio_setcfg_s3c24xx,
84 .get_config = s3c_gpio_getcfg_s3c24xx,
85};
86
87struct s3c_gpio_chip s3c24xx_gpios[] = {
88 [0] = {
89 .base = S3C2410_GPACON,
90 .pm = __gpio_pm(&s3c_gpio_pm_1bit),
91 .config = &s3c24xx_gpiocfg_banka,
92 .chip = {
93 .base = S3C2410_GPA(0),
94 .owner = THIS_MODULE,
95 .label = "GPIOA",
96 .ngpio = 24,
97 .direction_input = s3c24xx_gpiolib_banka_input,
98 .direction_output = s3c24xx_gpiolib_banka_output,
99 },
100 },
101 [1] = {
102 .base = S3C2410_GPBCON,
103 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
104 .chip = {
105 .base = S3C2410_GPB(0),
106 .owner = THIS_MODULE,
107 .label = "GPIOB",
108 .ngpio = 16,
109 },
110 },
111 [2] = {
112 .base = S3C2410_GPCCON,
113 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
114 .chip = {
115 .base = S3C2410_GPC(0),
116 .owner = THIS_MODULE,
117 .label = "GPIOC",
118 .ngpio = 16,
119 },
120 },
121 [3] = {
122 .base = S3C2410_GPDCON,
123 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
124 .chip = {
125 .base = S3C2410_GPD(0),
126 .owner = THIS_MODULE,
127 .label = "GPIOD",
128 .ngpio = 16,
129 },
130 },
131 [4] = {
132 .base = S3C2410_GPECON,
133 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
134 .chip = {
135 .base = S3C2410_GPE(0),
136 .label = "GPIOE",
137 .owner = THIS_MODULE,
138 .ngpio = 16,
139 },
140 },
141 [5] = {
142 .base = S3C2410_GPFCON,
143 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
144 .chip = {
145 .base = S3C2410_GPF(0),
146 .owner = THIS_MODULE,
147 .label = "GPIOF",
148 .ngpio = 8,
149 .to_irq = s3c24xx_gpiolib_bankf_toirq,
150 },
151 },
152 [6] = {
153 .base = S3C2410_GPGCON,
154 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
155 .irq_base = IRQ_EINT8,
156 .chip = {
157 .base = S3C2410_GPG(0),
158 .owner = THIS_MODULE,
159 .label = "GPIOG",
160 .ngpio = 16,
161 .to_irq = samsung_gpiolib_to_irq,
162 },
163 }, {
164 .base = S3C2410_GPHCON,
165 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
166 .chip = {
167 .base = S3C2410_GPH(0),
168 .owner = THIS_MODULE,
169 .label = "GPIOH",
170 .ngpio = 11,
171 },
172 },
173 /* GPIOS for the S3C2443 and later devices. */
174 {
175 .base = S3C2440_GPJCON,
176 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
177 .chip = {
178 .base = S3C2410_GPJ(0),
179 .owner = THIS_MODULE,
180 .label = "GPIOJ",
181 .ngpio = 16,
182 },
183 }, {
184 .base = S3C2443_GPKCON,
185 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
186 .chip = {
187 .base = S3C2410_GPK(0),
188 .owner = THIS_MODULE,
189 .label = "GPIOK",
190 .ngpio = 16,
191 },
192 }, {
193 .base = S3C2443_GPLCON,
194 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
195 .chip = {
196 .base = S3C2410_GPL(0),
197 .owner = THIS_MODULE,
198 .label = "GPIOL",
199 .ngpio = 15,
200 },
201 }, {
202 .base = S3C2443_GPMCON,
203 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
204 .chip = {
205 .base = S3C2410_GPM(0),
206 .owner = THIS_MODULE,
207 .label = "GPIOM",
208 .ngpio = 2,
209 },
210 },
211};
212
213
214static __init int s3c24xx_gpiolib_init(void)
215{
216 struct s3c_gpio_chip *chip = s3c24xx_gpios;
217 int gpn;
218
219 for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
220 if (!chip->config)
221 chip->config = &s3c24xx_gpiocfg_default;
222
223 s3c_gpiolib_add(chip);
224 }
225
226 return 0;
227}
228
229core_initcall(s3c24xx_gpiolib_init);
diff --git a/arch/arm/plat-s3c24xx/include/mach/clkdev.h b/arch/arm/plat-s3c24xx/include/mach/clkdev.h
deleted file mode 100644
index 7dffa83d23ff..000000000000
--- a/arch/arm/plat-s3c24xx/include/mach/clkdev.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __MACH_CLKDEV_H__
2#define __MACH_CLKDEV_H__
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do {} while (0)
6
7#endif
diff --git a/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h b/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
deleted file mode 100644
index a087de21bc20..000000000000
--- a/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C24xx - pwm clock and timer support
8 */
9
10/**
11 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
12 * @cfg: The timer TCFG1 register bits shifted down to 0.
13 *
14 * Return true if the given configuration from TCFG1 is a TCLK instead
15 * any of the TDIV clocks.
16 */
17static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
18{
19 return tcfg == S3C2410_TCFG1_MUX_TCLK;
20}
21
22/**
23 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
24 * @tcfg1: The tcfg1 setting, shifted down.
25 *
26 * Get the divisor value for the given tcfg1 setting. We assume the
27 * caller has already checked to see if this is not a TCLK source.
28 */
29static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
30{
31 return 1 << (1 + tcfg1);
32}
33
34/**
35 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
36 *
37 * Return true if we have a /1 in the tdiv setting.
38 */
39static inline unsigned int pwm_tdiv_has_div1(void)
40{
41 return 0;
42}
43
44/**
45 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
46 * @div: The divisor to calculate the bit information for.
47 *
48 * Turn a divisor into the necessary bit field for TCFG1.
49 */
50static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
51{
52 return ilog2(div) - 1;
53}
54
55#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
deleted file mode 100644
index 005729a1077a..000000000000
--- a/arch/arm/plat-s3c24xx/include/plat/pll.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C24xx - common pll registers and code
8 */
9
10#define S3C24XX_PLLCON_MDIVSHIFT 12
11#define S3C24XX_PLLCON_PDIVSHIFT 4
12#define S3C24XX_PLLCON_SDIVSHIFT 0
13#define S3C24XX_PLLCON_MDIVMASK ((1<<(1+(19-12)))-1)
14#define S3C24XX_PLLCON_PDIVMASK ((1<<5)-1)
15#define S3C24XX_PLLCON_SDIVMASK 3
16
17#include <asm/div64.h>
18
19static inline unsigned int
20s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
21{
22 unsigned int mdiv, pdiv, sdiv;
23 uint64_t fvco;
24
25 mdiv = pllval >> S3C24XX_PLLCON_MDIVSHIFT;
26 pdiv = pllval >> S3C24XX_PLLCON_PDIVSHIFT;
27 sdiv = pllval >> S3C24XX_PLLCON_SDIVSHIFT;
28
29 mdiv &= S3C24XX_PLLCON_MDIVMASK;
30 pdiv &= S3C24XX_PLLCON_PDIVMASK;
31 sdiv &= S3C24XX_PLLCON_SDIVMASK;
32
33 fvco = (uint64_t)baseclk * (mdiv + 8);
34 do_div(fvco, (pdiv + 2) << sdiv);
35
36 return (unsigned int)fvco;
37}
38
39#define S3C2416_PLL_M_SHIFT (14)
40#define S3C2416_PLL_P_SHIFT (5)
41#define S3C2416_PLL_S_MASK (7)
42#define S3C2416_PLL_M_MASK ((1 << 10) - 1)
43#define S3C2416_PLL_P_MASK (63)
44
45static inline unsigned int
46s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
47{
48 unsigned int m, p, s;
49 uint64_t fvco;
50
51 m = pllval >> S3C2416_PLL_M_SHIFT;
52 p = pllval >> S3C2416_PLL_P_SHIFT;
53
54 s = pllval & S3C2416_PLL_S_MASK;
55 m &= S3C2416_PLL_M_MASK;
56 p &= S3C2416_PLL_P_MASK;
57
58 fvco = (uint64_t)baseclk * m;
59 do_div(fvco, (p << s));
60
61 return (unsigned int)fvco;
62}
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-iis.h b/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
deleted file mode 100644
index cc44e0e931e9..000000000000
--- a/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
+++ /dev/null
@@ -1,68 +0,0 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-iis.h
2 *
3 * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
4 * http://www.simtec.co.uk/products/SWLINUX/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * S3C2410 IIS register definition
11*/
12
13#ifndef __ASM_ARCH_REGS_IIS_H
14#define __ASM_ARCH_REGS_IIS_H
15
16#define S3C2410_IISCON (0x00)
17
18#define S3C2410_IISCON_LRINDEX (1<<8)
19#define S3C2410_IISCON_TXFIFORDY (1<<7)
20#define S3C2410_IISCON_RXFIFORDY (1<<6)
21#define S3C2410_IISCON_TXDMAEN (1<<5)
22#define S3C2410_IISCON_RXDMAEN (1<<4)
23#define S3C2410_IISCON_TXIDLE (1<<3)
24#define S3C2410_IISCON_RXIDLE (1<<2)
25#define S3C2410_IISCON_PSCEN (1<<1)
26#define S3C2410_IISCON_IISEN (1<<0)
27
28#define S3C2410_IISMOD (0x04)
29
30#define S3C2440_IISMOD_MPLL (1<<9)
31#define S3C2410_IISMOD_SLAVE (1<<8)
32#define S3C2410_IISMOD_NOXFER (0<<6)
33#define S3C2410_IISMOD_RXMODE (1<<6)
34#define S3C2410_IISMOD_TXMODE (2<<6)
35#define S3C2410_IISMOD_TXRXMODE (3<<6)
36#define S3C2410_IISMOD_LR_LLOW (0<<5)
37#define S3C2410_IISMOD_LR_RLOW (1<<5)
38#define S3C2410_IISMOD_IIS (0<<4)
39#define S3C2410_IISMOD_MSB (1<<4)
40#define S3C2410_IISMOD_8BIT (0<<3)
41#define S3C2410_IISMOD_16BIT (1<<3)
42#define S3C2410_IISMOD_BITMASK (1<<3)
43#define S3C2410_IISMOD_256FS (0<<2)
44#define S3C2410_IISMOD_384FS (1<<2)
45#define S3C2410_IISMOD_16FS (0<<0)
46#define S3C2410_IISMOD_32FS (1<<0)
47#define S3C2410_IISMOD_48FS (2<<0)
48#define S3C2410_IISMOD_FS_MASK (3<<0)
49
50#define S3C2410_IISPSR (0x08)
51#define S3C2410_IISPSR_INTMASK (31<<5)
52#define S3C2410_IISPSR_INTSHIFT (5)
53#define S3C2410_IISPSR_EXTMASK (31<<0)
54#define S3C2410_IISPSR_EXTSHFIT (0)
55
56#define S3C2410_IISFCON (0x0c)
57
58#define S3C2410_IISFCON_TXDMA (1<<15)
59#define S3C2410_IISFCON_RXDMA (1<<14)
60#define S3C2410_IISFCON_TXENABLE (1<<13)
61#define S3C2410_IISFCON_RXENABLE (1<<12)
62#define S3C2410_IISFCON_TXMASK (0x3f << 6)
63#define S3C2410_IISFCON_TXSHIFT (6)
64#define S3C2410_IISFCON_RXMASK (0x3f)
65#define S3C2410_IISFCON_RXSHIFT (0)
66
67#define S3C2410_IISFIFO (0x10)
68#endif /* __ASM_ARCH_REGS_IIS_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-spi.h b/arch/arm/plat-s3c24xx/include/plat/regs-spi.h
deleted file mode 100644
index 892e2f680fca..000000000000
--- a/arch/arm/plat-s3c24xx/include/plat/regs-spi.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-spi.h
2 *
3 * Copyright (c) 2004 Fetron GmbH
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * S3C2410 SPI register definition
10*/
11
12#ifndef __ASM_ARCH_REGS_SPI_H
13#define __ASM_ARCH_REGS_SPI_H
14
15#define S3C2410_SPI1 (0x20)
16#define S3C2412_SPI1 (0x100)
17
18#define S3C2410_SPCON (0x00)
19
20#define S3C2412_SPCON_RXFIFO_RB2 (0<<14)
21#define S3C2412_SPCON_RXFIFO_RB4 (1<<14)
22#define S3C2412_SPCON_RXFIFO_RB12 (2<<14)
23#define S3C2412_SPCON_RXFIFO_RB14 (3<<14)
24#define S3C2412_SPCON_TXFIFO_RB2 (0<<12)
25#define S3C2412_SPCON_TXFIFO_RB4 (1<<12)
26#define S3C2412_SPCON_TXFIFO_RB12 (2<<12)
27#define S3C2412_SPCON_TXFIFO_RB14 (3<<12)
28#define S3C2412_SPCON_RXFIFO_RESET (1<<11) /* RxFIFO reset */
29#define S3C2412_SPCON_TXFIFO_RESET (1<<10) /* TxFIFO reset */
30#define S3C2412_SPCON_RXFIFO_EN (1<<9) /* RxFIFO Enable */
31#define S3C2412_SPCON_TXFIFO_EN (1<<8) /* TxFIFO Enable */
32
33#define S3C2412_SPCON_DIRC_RX (1<<7)
34
35#define S3C2410_SPCON_SMOD_DMA (2<<5) /* DMA mode */
36#define S3C2410_SPCON_SMOD_INT (1<<5) /* interrupt mode */
37#define S3C2410_SPCON_SMOD_POLL (0<<5) /* polling mode */
38#define S3C2410_SPCON_ENSCK (1<<4) /* Enable SCK */
39#define S3C2410_SPCON_MSTR (1<<3) /* Master/Slave select
40 0: slave, 1: master */
41#define S3C2410_SPCON_CPOL_HIGH (1<<2) /* Clock polarity select */
42#define S3C2410_SPCON_CPOL_LOW (0<<2) /* Clock polarity select */
43
44#define S3C2410_SPCON_CPHA_FMTB (1<<1) /* Clock Phase Select */
45#define S3C2410_SPCON_CPHA_FMTA (0<<1) /* Clock Phase Select */
46
47#define S3C2410_SPCON_TAGD (1<<0) /* Tx auto garbage data mode */
48
49
50#define S3C2410_SPSTA (0x04)
51
52#define S3C2412_SPSTA_RXFIFO_AE (1<<11)
53#define S3C2412_SPSTA_TXFIFO_AE (1<<10)
54#define S3C2412_SPSTA_RXFIFO_ERROR (1<<9)
55#define S3C2412_SPSTA_TXFIFO_ERROR (1<<8)
56#define S3C2412_SPSTA_RXFIFO_FIFO (1<<7)
57#define S3C2412_SPSTA_RXFIFO_EMPTY (1<<6)
58#define S3C2412_SPSTA_TXFIFO_NFULL (1<<5)
59#define S3C2412_SPSTA_TXFIFO_EMPTY (1<<4)
60
61#define S3C2410_SPSTA_DCOL (1<<2) /* Data Collision Error */
62#define S3C2410_SPSTA_MULD (1<<1) /* Multi Master Error */
63#define S3C2410_SPSTA_READY (1<<0) /* Data Tx/Rx ready */
64#define S3C2412_SPSTA_READY_ORG (1<<3)
65
66#define S3C2410_SPPIN (0x08)
67
68#define S3C2410_SPPIN_ENMUL (1<<2) /* Multi Master Error detect */
69#define S3C2410_SPPIN_RESERVED (1<<1)
70#define S3C2410_SPPIN_KEEP (1<<0) /* Master Out keep */
71
72#define S3C2410_SPPRE (0x0C)
73#define S3C2410_SPTDAT (0x10)
74#define S3C2410_SPRDAT (0x14)
75
76#define S3C2412_TXFIFO (0x18)
77#define S3C2412_RXFIFO (0x18)
78#define S3C2412_SPFIC (0x24)
79
80
81#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 59552c0ea5fb..5a21b15b2a97 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -160,6 +160,124 @@ static struct clk clk_prediv = {
160 }, 160 },
161}; 161};
162 162
163/* armdiv
164 *
165 * this clock is sourced from msysclk and can have a number of
166 * divider values applied to it to then be fed into armclk.
167*/
168
169static unsigned int *armdiv;
170static int nr_armdiv;
171static int armdivmask;
172
173static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
174 unsigned long rate)
175{
176 unsigned long parent = clk_get_rate(clk->parent);
177 unsigned long calc;
178 unsigned best = 256; /* bigger than any value */
179 unsigned div;
180 int ptr;
181
182 if (!nr_armdiv)
183 return -EINVAL;
184
185 for (ptr = 0; ptr < nr_armdiv; ptr++) {
186 div = armdiv[ptr];
187 if (div) {
188 /* cpufreq provides 266mhz as 266666000 not 266666666 */
189 calc = (parent / div / 1000) * 1000;
190 if (calc <= rate && div < best)
191 best = div;
192 }
193 }
194
195 return parent / best;
196}
197
198static unsigned long s3c2443_armclk_getrate(struct clk *clk)
199{
200 unsigned long rate = clk_get_rate(clk->parent);
201 unsigned long clkcon0;
202 int val;
203
204 if (!nr_armdiv || !armdivmask)
205 return -EINVAL;
206
207 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
208 clkcon0 &= armdivmask;
209 val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
210
211 return rate / armdiv[val];
212}
213
214static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
215{
216 unsigned long parent = clk_get_rate(clk->parent);
217 unsigned long calc;
218 unsigned div;
219 unsigned best = 256; /* bigger than any value */
220 int ptr;
221 int val = -1;
222
223 if (!nr_armdiv || !armdivmask)
224 return -EINVAL;
225
226 for (ptr = 0; ptr < nr_armdiv; ptr++) {
227 div = armdiv[ptr];
228 if (div) {
229 /* cpufreq provides 266mhz as 266666000 not 266666666 */
230 calc = (parent / div / 1000) * 1000;
231 if (calc <= rate && div < best) {
232 best = div;
233 val = ptr;
234 }
235 }
236 }
237
238 if (val >= 0) {
239 unsigned long clkcon0;
240
241 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
242 clkcon0 &= ~armdivmask;
243 clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
244 __raw_writel(clkcon0, S3C2443_CLKDIV0);
245 }
246
247 return (val == -1) ? -EINVAL : 0;
248}
249
250static struct clk clk_armdiv = {
251 .name = "armdiv",
252 .parent = &clk_msysclk.clk,
253 .ops = &(struct clk_ops) {
254 .round_rate = s3c2443_armclk_roundrate,
255 .get_rate = s3c2443_armclk_getrate,
256 .set_rate = s3c2443_armclk_setrate,
257 },
258};
259
260/* armclk
261 *
262 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
263 */
264
265static struct clk *clk_arm_sources[] = {
266 [0] = &clk_armdiv,
267 [1] = &clk_h,
268};
269
270static struct clksrc_clk clk_arm = {
271 .clk = {
272 .name = "armclk",
273 },
274 .sources = &(struct clksrc_sources) {
275 .sources = clk_arm_sources,
276 .nr_sources = ARRAY_SIZE(clk_arm_sources),
277 },
278 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
279};
280
163/* usbhost 281/* usbhost
164 * 282 *
165 * usb host bus-clock, usually 48MHz to provide USB bus clock timing 283 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
@@ -205,9 +323,64 @@ static struct clksrc_clk clksrc_clks[] = {
205 }, 323 },
206}; 324};
207 325
326static struct clk clk_i2s_ext = {
327 .name = "i2s-ext",
328};
329
330/* i2s_eplldiv
331 *
332 * This clock is the output from the I2S divisor of ESYSCLK, and is separate
333 * from the mux that comes after it (cannot merge into one single clock)
334*/
335
336static struct clksrc_clk clk_i2s_eplldiv = {
337 .clk = {
338 .name = "i2s-eplldiv",
339 .parent = &clk_esysclk.clk,
340 },
341 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
342};
343
344/* i2s-ref
345 *
346 * i2s bus reference clock, selectable from external, esysclk or epllref
347 *
348 * Note, this used to be two clocks, but was compressed into one.
349*/
350
351static struct clk *clk_i2s_srclist[] = {
352 [0] = &clk_i2s_eplldiv.clk,
353 [1] = &clk_i2s_ext,
354 [2] = &clk_epllref.clk,
355 [3] = &clk_epllref.clk,
356};
357
358static struct clksrc_clk clk_i2s = {
359 .clk = {
360 .name = "i2s-if",
361 .ctrlbit = S3C2443_SCLKCON_I2SCLK,
362 .enable = s3c2443_clkcon_enable_s,
363
364 },
365 .sources = &(struct clksrc_sources) {
366 .sources = clk_i2s_srclist,
367 .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
368 },
369 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
370};
208 371
209static struct clk init_clocks_off[] = { 372static struct clk init_clocks_off[] = {
210 { 373 {
374 .name = "iis",
375 .parent = &clk_p,
376 .enable = s3c2443_clkcon_enable_p,
377 .ctrlbit = S3C2443_PCLKCON_IIS,
378 }, {
379 .name = "hsspi",
380 .parent = &clk_p,
381 .enable = s3c2443_clkcon_enable_p,
382 .ctrlbit = S3C2443_PCLKCON_HSSPI,
383 }, {
211 .name = "adc", 384 .name = "adc",
212 .parent = &clk_p, 385 .parent = &clk_p,
213 .enable = s3c2443_clkcon_enable_p, 386 .enable = s3c2443_clkcon_enable_p,
@@ -253,6 +426,7 @@ static struct clk init_clocks[] = {
253 .ctrlbit = S3C2443_HCLKCON_DMA5, 426 .ctrlbit = S3C2443_HCLKCON_DMA5,
254 }, { 427 }, {
255 .name = "hsmmc", 428 .name = "hsmmc",
429 .devname = "s3c-sdhci.1",
256 .parent = &clk_h, 430 .parent = &clk_h,
257 .enable = s3c2443_clkcon_enable_h, 431 .enable = s3c2443_clkcon_enable_h,
258 .ctrlbit = S3C2443_HCLKCON_HSMMC, 432 .ctrlbit = S3C2443_HCLKCON_HSMMC,
@@ -347,8 +521,7 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
347 521
348/* EPLLCON compatible enough to get on/off information */ 522/* EPLLCON compatible enough to get on/off information */
349 523
350void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll, 524void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
351 fdiv_fn get_fdiv)
352{ 525{
353 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); 526 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
354 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); 527 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
@@ -368,7 +541,7 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
368 pll = get_mpll(mpllcon, xtal); 541 pll = get_mpll(mpllcon, xtal);
369 clk_msysclk.clk.rate = pll; 542 clk_msysclk.clk.rate = pll;
370 543
371 fclk = pll / get_fdiv(clkdiv0); 544 fclk = clk_get_rate(&clk_armdiv);
372 hclk = s3c2443_prediv_getrate(&clk_prediv); 545 hclk = s3c2443_prediv_getrate(&clk_prediv);
373 hclk /= s3c2443_get_hdiv(clkdiv0); 546 hclk /= s3c2443_get_hdiv(clkdiv0);
374 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); 547 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
@@ -403,20 +576,29 @@ static struct clk *clks[] __initdata = {
403 &clk_ext, 576 &clk_ext,
404 &clk_epll, 577 &clk_epll,
405 &clk_usb_bus, 578 &clk_usb_bus,
579 &clk_armdiv,
406}; 580};
407 581
408static struct clksrc_clk *clksrcs[] __initdata = { 582static struct clksrc_clk *clksrcs[] __initdata = {
583 &clk_i2s_eplldiv,
584 &clk_i2s,
409 &clk_usb_bus_host, 585 &clk_usb_bus_host,
410 &clk_epllref, 586 &clk_epllref,
411 &clk_esysclk, 587 &clk_esysclk,
412 &clk_msysclk, 588 &clk_msysclk,
589 &clk_arm,
413}; 590};
414 591
415void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 592void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
416 fdiv_fn get_fdiv) 593 unsigned int *divs, int nr_divs,
594 int divmask)
417{ 595{
418 int ptr; 596 int ptr;
419 597
598 armdiv = divs;
599 nr_armdiv = nr_divs;
600 armdivmask = divmask;
601
420 /* s3c2443 parents h and p clocks from prediv */ 602 /* s3c2443 parents h and p clocks from prediv */
421 clk_h.parent = &clk_prediv; 603 clk_h.parent = &clk_prediv;
422 clk_p.parent = &clk_prediv; 604 clk_p.parent = &clk_prediv;
@@ -437,5 +619,5 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
437 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 619 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
438 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 620 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
439 621
440 s3c2443_common_setup_clocks(get_mpll, get_fdiv); 622 s3c2443_common_setup_clocks(get_mpll);
441} 623}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 9a197e55f669..9b9968fa8695 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -7,7 +7,7 @@
7 7
8config PLAT_S5P 8config PLAT_S5P
9 bool 9 bool
10 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4) 10 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
11 default y 11 default y
12 select ARM_VIC if !ARCH_EXYNOS4 12 select ARM_VIC if !ARCH_EXYNOS4
13 select ARM_GIC if ARCH_EXYNOS4 13 select ARM_GIC if ARCH_EXYNOS4
@@ -16,9 +16,6 @@ config PLAT_S5P
16 select S3C_GPIO_TRACK 16 select S3C_GPIO_TRACK
17 select S5P_GPIO_DRVSTR 17 select S5P_GPIO_DRVSTR
18 select SAMSUNG_GPIOLIB_4BIT 18 select SAMSUNG_GPIOLIB_4BIT
19 select S3C_GPIO_CFG_S3C64XX
20 select S3C_GPIO_PULL_UPDOWN
21 select S3C_GPIO_CFG_S3C24XX
22 select PLAT_SAMSUNG 19 select PLAT_SAMSUNG
23 select SAMSUNG_CLKSRC 20 select SAMSUNG_CLKSRC
24 select SAMSUNG_IRQ_VIC_TIMER 21 select SAMSUNG_IRQ_VIC_TIMER
@@ -42,6 +39,12 @@ config S5P_HRT
42 help 39 help
43 Use the High Resolution timer support 40 Use the High Resolution timer support
44 41
42config S5P_PM
43 bool
44 help
45 Common code for power management support on S5P and newer SoCs
46 Note: Do not select this for S5P6440 and S5P6450.
47
45comment "System MMU" 48comment "System MMU"
46 49
47config S5P_SYSTEM_MMU 50config S5P_SYSTEM_MMU
@@ -50,6 +53,12 @@ config S5P_SYSTEM_MMU
50 help 53 help
51 Say Y here if you want to enable System MMU 54 Say Y here if you want to enable System MMU
52 55
56config S5P_SLEEP
57 bool
58 help
59 Internal config node to apply common S5P sleep management code.
60 Can be selected by S5P and newer SoCs with similar sleep procedure.
61
53config S5P_DEV_FIMC0 62config S5P_DEV_FIMC0
54 bool 63 bool
55 help 64 help
@@ -75,6 +84,11 @@ config S5P_DEV_FIMD0
75 help 84 help
76 Compile in platform device definitions for FIMD controller 0 85 Compile in platform device definitions for FIMD controller 0
77 86
87config S5P_DEV_I2C_HDMIPHY
88 bool
89 help
90 Compile in platform device definitions for I2C HDMIPHY controller
91
78config S5P_DEV_MFC 92config S5P_DEV_MFC
79 bool 93 bool
80 help 94 help
@@ -95,6 +109,11 @@ config S5P_DEV_CSIS1
95 help 109 help
96 Compile in platform device definitions for MIPI-CSIS channel 1 110 Compile in platform device definitions for MIPI-CSIS channel 1
97 111
112config S5P_DEV_TV
113 bool
114 help
115 Compile in platform device definition for TV interface
116
98config S5P_DEV_USB_EHCI 117config S5P_DEV_USB_EHCI
99 bool 118 bool
100 help 119 help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 4b53e04eeca4..876344038b8d 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -12,7 +12,6 @@ obj- :=
12 12
13# Core files 13# Core files
14 14
15obj-y += dev-pmu.o
16obj-y += dev-uart.o 15obj-y += dev-uart.o
17obj-y += cpu.o 16obj-y += cpu.o
18obj-y += clock.o 17obj-y += clock.o
@@ -20,19 +19,10 @@ obj-y += irq.o
20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o 19obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
21obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o 20obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
22obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o 21obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
23obj-$(CONFIG_PM) += pm.o 22obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o
24obj-$(CONFIG_PM) += irq-pm.o 23obj-$(CONFIG_S5P_SLEEP) += sleep.o
25obj-$(CONFIG_S5P_HRT) += s5p-time.o 24obj-$(CONFIG_S5P_HRT) += s5p-time.o
26 25
27# devices 26# devices
28obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o 27obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
29obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
30obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
31obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
32obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
33obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
34obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
35obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
36obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
37obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
38obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o 28obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index 7b0a28f73a68..a56959e83516 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -75,7 +75,7 @@ static struct cpu_table cpu_ids[] __initdata = {
75 .map_io = exynos4_map_io, 75 .map_io = exynos4_map_io,
76 .init_clocks = exynos4_init_clocks, 76 .init_clocks = exynos4_init_clocks,
77 .init_uarts = exynos4_init_uarts, 77 .init_uarts = exynos4_init_uarts,
78 .init = exynos4_init, 78 .init = exynos_init,
79 .name = name_exynos4210, 79 .name = name_exynos4210,
80 }, { 80 }, {
81 .idcode = EXYNOS4212_CPU_ID, 81 .idcode = EXYNOS4212_CPU_ID,
@@ -83,7 +83,7 @@ static struct cpu_table cpu_ids[] __initdata = {
83 .map_io = exynos4_map_io, 83 .map_io = exynos4_map_io,
84 .init_clocks = exynos4_init_clocks, 84 .init_clocks = exynos4_init_clocks,
85 .init_uarts = exynos4_init_uarts, 85 .init_uarts = exynos4_init_uarts,
86 .init = exynos4_init, 86 .init = exynos_init,
87 .name = name_exynos4212, 87 .name = name_exynos4212,
88 }, { 88 }, {
89 .idcode = EXYNOS4412_CPU_ID, 89 .idcode = EXYNOS4412_CPU_ID,
@@ -91,7 +91,7 @@ static struct cpu_table cpu_ids[] __initdata = {
91 .map_io = exynos4_map_io, 91 .map_io = exynos4_map_io,
92 .init_clocks = exynos4_init_clocks, 92 .init_clocks = exynos4_init_clocks,
93 .init_uarts = exynos4_init_uarts, 93 .init_uarts = exynos4_init_uarts,
94 .init = exynos4_init, 94 .init = exynos_init,
95 .name = name_exynos4412, 95 .name = name_exynos4412,
96 }, 96 },
97}; 97};
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
deleted file mode 100644
index e3aabef5e347..000000000000
--- a/arch/arm/plat-s5p/dev-csis0.c
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series device definition for MIPI-CSIS channel 0
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis0_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS0,
19 .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS0,
24 .end = IRQ_MIPI_CSIS0,
25 .flags = IORESOURCE_IRQ,
26 }
27};
28
29struct platform_device s5p_device_mipi_csis0 = {
30 .name = "s5p-mipi-csis",
31 .id = 0,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
33 .resource = s5p_mipi_csis0_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
deleted file mode 100644
index 08b91b580207..000000000000
--- a/arch/arm/plat-s5p/dev-csis1.c
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series device definition for MIPI-CSIS channel 1
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis1_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS1,
19 .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS1,
24 .end = IRQ_MIPI_CSIS1,
25 .flags = IORESOURCE_IRQ,
26 },
27};
28
29struct platform_device s5p_device_mipi_csis1 = {
30 .name = "s5p-mipi-csis",
31 .id = 1,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
33 .resource = s5p_mipi_csis1_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c
deleted file mode 100644
index 94080fff9e9b..000000000000
--- a/arch/arm/plat-s5p/dev-ehci.c
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/platform_device.h>
13#include <mach/irqs.h>
14#include <mach/map.h>
15#include <plat/devs.h>
16#include <plat/ehci.h>
17#include <plat/usb-phy.h>
18
19/* USB EHCI Host Controller registration */
20static struct resource s5p_ehci_resource[] = {
21 [0] = {
22 .start = S5P_PA_EHCI,
23 .end = S5P_PA_EHCI + SZ_256 - 1,
24 .flags = IORESOURCE_MEM,
25 },
26 [1] = {
27 .start = IRQ_USB_HOST,
28 .end = IRQ_USB_HOST,
29 .flags = IORESOURCE_IRQ,
30 }
31};
32
33static u64 s5p_device_ehci_dmamask = 0xffffffffUL;
34
35struct platform_device s5p_device_ehci = {
36 .name = "s5p-ehci",
37 .id = -1,
38 .num_resources = ARRAY_SIZE(s5p_ehci_resource),
39 .resource = s5p_ehci_resource,
40 .dev = {
41 .dma_mask = &s5p_device_ehci_dmamask,
42 .coherent_dma_mask = 0xffffffffUL
43 }
44};
45
46void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
47{
48 struct s5p_ehci_platdata *npd;
49
50 npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
51 &s5p_device_ehci);
52
53 if (!npd->phy_init)
54 npd->phy_init = s5p_usb_phy_init;
55 if (!npd->phy_exit)
56 npd->phy_exit = s5p_usb_phy_exit;
57}
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
deleted file mode 100644
index 608770fc1531..000000000000
--- a/arch/arm/plat-s5p/dev-fimc0.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-fimc0.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC0 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc0_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC0,
22 .end = S5P_PA_FIMC0 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC0,
27 .end = IRQ_FIMC0,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc0 = {
35 .name = "s5p-fimc",
36 .id = 0,
37 .num_resources = ARRAY_SIZE(s5p_fimc0_resource),
38 .resource = s5p_fimc0_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc0_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
deleted file mode 100644
index 76e3a97a87d3..000000000000
--- a/arch/arm/plat-s5p/dev-fimc1.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-fimc1.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC1 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc1_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC1,
22 .end = S5P_PA_FIMC1 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC1,
27 .end = IRQ_FIMC1,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc1 = {
35 .name = "s5p-fimc",
36 .id = 1,
37 .num_resources = ARRAY_SIZE(s5p_fimc1_resource),
38 .resource = s5p_fimc1_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc1_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
deleted file mode 100644
index 24d29816fa2c..000000000000
--- a/arch/arm/plat-s5p/dev-fimc2.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-fimc2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC2 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc2_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC2,
22 .end = S5P_PA_FIMC2 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC2,
27 .end = IRQ_FIMC2,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc2 = {
35 .name = "s5p-fimc",
36 .id = 2,
37 .num_resources = ARRAY_SIZE(s5p_fimc2_resource),
38 .resource = s5p_fimc2_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc2_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c
deleted file mode 100644
index ef31beca386c..000000000000
--- a/arch/arm/plat-s5p/dev-fimc3.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-fimc3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC3 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc3_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC3,
22 .end = S5P_PA_FIMC3 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC3,
27 .end = IRQ_FIMC3,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc3_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc3 = {
35 .name = "s5p-fimc",
36 .id = 3,
37 .num_resources = ARRAY_SIZE(s5p_fimc3_resource),
38 .resource = s5p_fimc3_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc3_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
deleted file mode 100644
index f728bb5abcef..000000000000
--- a/arch/arm/plat-s5p/dev-fimd0.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-fimd0.c
2 *
3 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Core file for Samsung Display Controller (FIMD) driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <linux/platform_device.h>
16#include <linux/fb.h>
17#include <linux/gfp.h>
18#include <linux/dma-mapping.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/fb.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s5p_fimd0_resource[] = {
28 [0] = {
29 .start = S5P_PA_FIMD0,
30 .end = S5P_PA_FIMD0 + SZ_32K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_FIMD0_VSYNC,
35 .end = IRQ_FIMD0_VSYNC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = IRQ_FIMD0_FIFO,
40 .end = IRQ_FIMD0_FIFO,
41 .flags = IORESOURCE_IRQ,
42 },
43 [3] = {
44 .start = IRQ_FIMD0_SYSTEM,
45 .end = IRQ_FIMD0_SYSTEM,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static u64 fimd0_dmamask = DMA_BIT_MASK(32);
51
52struct platform_device s5p_device_fimd0 = {
53 .name = "s5p-fb",
54 .id = 0,
55 .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
56 .resource = s5p_fimd0_resource,
57 .dev = {
58 .dma_mask = &fimd0_dmamask,
59 .coherent_dma_mask = DMA_BIT_MASK(32),
60 },
61};
62
63void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
64{
65 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
66 &s5p_device_fimd0);
67}
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c
index 94226a0010f7..a30d36b7f61b 100644
--- a/arch/arm/plat-s5p/dev-mfc.c
+++ b/arch/arm/plat-s5p/dev-mfc.c
@@ -22,56 +22,6 @@
22#include <plat/irqs.h> 22#include <plat/irqs.h>
23#include <plat/mfc.h> 23#include <plat/mfc.h>
24 24
25static struct resource s5p_mfc_resource[] = {
26 [0] = {
27 .start = S5P_PA_MFC,
28 .end = S5P_PA_MFC + SZ_64K - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_MFC,
33 .end = IRQ_MFC,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38struct platform_device s5p_device_mfc = {
39 .name = "s5p-mfc",
40 .id = -1,
41 .num_resources = ARRAY_SIZE(s5p_mfc_resource),
42 .resource = s5p_mfc_resource,
43};
44
45/*
46 * MFC hardware has 2 memory interfaces which are modelled as two separate
47 * platform devices to let dma-mapping distinguish between them.
48 *
49 * MFC parent device (s5p_device_mfc) must be registered before memory
50 * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
51 */
52
53static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
54
55struct platform_device s5p_device_mfc_l = {
56 .name = "s5p-mfc-l",
57 .id = -1,
58 .dev = {
59 .parent = &s5p_device_mfc.dev,
60 .dma_mask = &s5p_mfc_dma_mask,
61 .coherent_dma_mask = DMA_BIT_MASK(32),
62 },
63};
64
65struct platform_device s5p_device_mfc_r = {
66 .name = "s5p-mfc-r",
67 .id = -1,
68 .dev = {
69 .parent = &s5p_device_mfc.dev,
70 .dma_mask = &s5p_mfc_dma_mask,
71 .coherent_dma_mask = DMA_BIT_MASK(32),
72 },
73};
74
75struct s5p_mfc_reserved_mem { 25struct s5p_mfc_reserved_mem {
76 phys_addr_t base; 26 phys_addr_t base;
77 unsigned long size; 27 unsigned long size;
diff --git a/arch/arm/plat-s5p/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c
deleted file mode 100644
index 20336c8f2479..000000000000
--- a/arch/arm/plat-s5p/dev-onenand.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/* linux/arch/arm/plat-s5p/dev-onenand.c
2 *
3 * Copyright 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2008-2010 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * S5P series device definition for OneNAND devices
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22static struct resource s5p_onenand_resources[] = {
23 [0] = {
24 .start = S5P_PA_ONENAND,
25 .end = S5P_PA_ONENAND + SZ_128K - 1,
26 .flags = IORESOURCE_MEM,
27 },
28 [1] = {
29 .start = S5P_PA_ONENAND_DMA,
30 .end = S5P_PA_ONENAND_DMA + SZ_8K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [2] = {
34 .start = IRQ_ONENAND_AUDI,
35 .end = IRQ_ONENAND_AUDI,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s5p_device_onenand = {
41 .name = "s5pc110-onenand",
42 .id = -1,
43 .num_resources = ARRAY_SIZE(s5p_onenand_resources),
44 .resource = s5p_onenand_resources,
45};
diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c
deleted file mode 100644
index a08576da72b0..000000000000
--- a/arch/arm/plat-s5p/dev-pmu.c
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * linux/arch/arm/plat-s5p/dev-pmu.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include <asm/pmu.h>
16#include <mach/irqs.h>
17
18static struct resource s5p_pmu_resource = {
19 .start = IRQ_PMU,
20 .end = IRQ_PMU,
21 .flags = IORESOURCE_IRQ,
22};
23
24struct platform_device s5p_device_pmu = {
25 .name = "arm-pmu",
26 .id = ARM_PMU_DEVICE_CPU,
27 .num_resources = 1,
28 .resource = &s5p_pmu_resource,
29};
30
31static int __init s5p_pmu_init(void)
32{
33 platform_device_register(&s5p_device_pmu);
34 return 0;
35}
36arch_initcall(s5p_pmu_init);
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index c65eb791d1bb..1fdfaa4599ce 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -37,7 +37,7 @@ struct s5p_gpioint_bank {
37 int start; 37 int start;
38 int nr_groups; 38 int nr_groups;
39 int irq; 39 int irq;
40 struct s3c_gpio_chip **chips; 40 struct samsung_gpio_chip **chips;
41 void (*handler)(unsigned int, struct irq_desc *); 41 void (*handler)(unsigned int, struct irq_desc *);
42}; 42};
43 43
@@ -87,7 +87,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
87 chained_irq_enter(chip, desc); 87 chained_irq_enter(chip, desc);
88 88
89 for (group = 0; group < bank->nr_groups; group++) { 89 for (group = 0; group < bank->nr_groups; group++) {
90 struct s3c_gpio_chip *chip = bank->chips[group]; 90 struct samsung_gpio_chip *chip = bank->chips[group];
91 if (!chip) 91 if (!chip)
92 continue; 92 continue;
93 93
@@ -110,7 +110,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
110 chained_irq_exit(chip, desc); 110 chained_irq_exit(chip, desc);
111} 111}
112 112
113static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) 113static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip)
114{ 114{
115 static int used_gpioint_groups = 0; 115 static int used_gpioint_groups = 0;
116 int group = chip->group; 116 int group = chip->group;
@@ -131,7 +131,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
131 return -EINVAL; 131 return -EINVAL;
132 132
133 if (!bank->handler) { 133 if (!bank->handler) {
134 bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) * 134 bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) *
135 bank->nr_groups, GFP_KERNEL); 135 bank->nr_groups, GFP_KERNEL);
136 if (!bank->chips) 136 if (!bank->chips)
137 return -ENOMEM; 137 return -ENOMEM;
@@ -174,7 +174,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
174 174
175int __init s5p_register_gpio_interrupt(int pin) 175int __init s5p_register_gpio_interrupt(int pin)
176{ 176{
177 struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin); 177 struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin);
178 int offset, group; 178 int offset, group;
179 int ret; 179 int ret;
180 180
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/plat-s5p/sleep.S
index 0984078f1eba..0fd591bfc9fd 100644
--- a/arch/arm/mach-exynos4/sleep.S
+++ b/arch/arm/plat-s5p/sleep.S
@@ -1,15 +1,11 @@
1/* linux/arch/arm/mach-exynos4/sleep.S 1/* linux/arch/arm/plat-s5p/sleep.S
2 * 2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
5 * 5 *
6 * EXYNOS4210 power Manager (Suspend-To-RAM) support 6 * Common S5P Sleep Code
7 * Based on S3C2410 sleep code by: 7 * Based on S3C64XX sleep code by:
8 * Ben Dooks, (c) 2004 Simtec Electronics 8 * Ben Dooks, (c) 2008 Simtec Electronics
9 *
10 * Based on PXA/SA1100 sleep code by:
11 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
12 * Cliff Brake, (c) 2001
13 * 9 *
14 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -28,7 +24,6 @@
28 24
29#include <linux/linkage.h> 25#include <linux/linkage.h>
30#include <asm/assembler.h> 26#include <asm/assembler.h>
31#include <asm/memory.h>
32 27
33 .text 28 .text
34 29
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3895f9aff0dc..313eb26cfa62 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -74,39 +74,12 @@ config SAMSUNG_GPIOLIB_4BIT
74 configuration. GPIOlib shall be compiled only for S3C64XX and S5P 74 configuration. GPIOlib shall be compiled only for S3C64XX and S5P
75 series of processors. 75 series of processors.
76 76
77config S3C_GPIO_CFG_S3C24XX
78 bool
79 help
80 Internal configuration to enable S3C24XX style GPIO configuration
81 functions.
82
83config S3C_GPIO_CFG_S3C64XX 77config S3C_GPIO_CFG_S3C64XX
84 bool 78 bool
85 help 79 help
86 Internal configuration to enable S3C64XX style GPIO configuration 80 Internal configuration to enable S3C64XX style GPIO configuration
87 functions. 81 functions.
88 82
89config S3C_GPIO_PULL_UPDOWN
90 bool
91 help
92 Internal configuration to enable the correct GPIO pull helper
93
94config S3C_GPIO_PULL_S3C2443
95 bool
96 select S3C_GPIO_PULL_UPDOWN
97 help
98 Internal configuration to enable the correct GPIO pull helper for S3C2443-style GPIO
99
100config S3C_GPIO_PULL_DOWN
101 bool
102 help
103 Internal configuration to enable the correct GPIO pull helper
104
105config S3C_GPIO_PULL_UP
106 bool
107 help
108 Internal configuration to enable the correct GPIO pull helper
109
110config S5P_GPIO_DRVSTR 83config S5P_GPIO_DRVSTR
111 bool 84 bool
112 help 85 help
@@ -295,11 +268,14 @@ config S3C_DMA
295 help 268 help
296 Internal configuration for S3C DMA core 269 Internal configuration for S3C DMA core
297 270
298config S3C_PL330_DMA 271config SAMSUNG_DMADEV
299 bool 272 bool
300 select PL330 273 select DMADEVICES
274 select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
275 CPU_S5P6450 || CPU_S5P6440)
276 select ARM_AMBA
301 help 277 help
302 S3C DMA API Driver for PL330 DMAC. 278 Use DMA device engine for PL330 DMAC.
303 279
304comment "Power management" 280comment "Power management"
305 281
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 09adb84f2718..6012366f33cb 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -1,4 +1,4 @@
1# arch/arm/plat-s3c64xx/Makefile 1# arch/arm/plat-samsung/Makefile
2# 2#
3# Copyright 2009 Simtec Electronics 3# Copyright 2009 Simtec Electronics
4# 4#
@@ -15,9 +15,6 @@ obj-y += init.o cpu.o
15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o 15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
16obj-y += clock.o 16obj-y += clock.o
17obj-y += pwm-clock.o 17obj-y += pwm-clock.o
18obj-y += gpio.o
19obj-y += gpio-config.o
20obj-y += dev-asocdma.o
21 18
22obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o 19obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
23 20
@@ -31,40 +28,16 @@ obj-$(CONFIG_S3C_ADC) += adc.o
31 28
32obj-y += platformdata.o 29obj-y += platformdata.o
33 30
34obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o 31obj-y += devs.o
35obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
36obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
37obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
38obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
39obj-y += dev-i2c0.o
40obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
41obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o
42obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o
43obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o
44obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o
45obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o
46obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o
47obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
48obj-y += dev-uart.o 32obj-y += dev-uart.o
49obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o 33
50obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
51obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.o
52obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
53obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
54obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
55
56obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
57obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
58obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
59obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o
60obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o
61obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o 34obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
62 35
63# DMA support 36# DMA support
64 37
65obj-$(CONFIG_S3C_DMA) += dma.o 38obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
66 39
67obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o 40obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
68 41
69# PM support 42# PM support
70 43
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index ee8deef19481..33ecd0c9f0c3 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -41,6 +41,8 @@
41 41
42enum s3c_cpu_type { 42enum s3c_cpu_type {
43 TYPE_ADCV1, /* S3C24XX */ 43 TYPE_ADCV1, /* S3C24XX */
44 TYPE_ADCV11, /* S3C2443 */
45 TYPE_ADCV12, /* S3C2416, S3C2450 */
44 TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */ 46 TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */
45 TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */ 47 TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
46}; 48};
@@ -98,13 +100,17 @@ static inline void s3c_adc_select(struct adc_device *adc,
98 100
99 client->select_cb(client, 1); 101 client->select_cb(client, 1);
100 102
101 con &= ~S3C2410_ADCCON_MUXMASK; 103 if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2)
104 con &= ~S3C2410_ADCCON_MUXMASK;
102 con &= ~S3C2410_ADCCON_STDBM; 105 con &= ~S3C2410_ADCCON_STDBM;
103 con &= ~S3C2410_ADCCON_STARTMASK; 106 con &= ~S3C2410_ADCCON_STARTMASK;
104 107
105 if (!client->is_ts) { 108 if (!client->is_ts) {
106 if (cpu == TYPE_ADCV3) 109 if (cpu == TYPE_ADCV3)
107 writel(client->channel & 0xf, adc->regs + S5P_ADCMUX); 110 writel(client->channel & 0xf, adc->regs + S5P_ADCMUX);
111 else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12)
112 writel(client->channel & 0xf,
113 adc->regs + S3C2443_ADCMUX);
108 else 114 else
109 con |= S3C2410_ADCCON_SELMUX(client->channel); 115 con |= S3C2410_ADCCON_SELMUX(client->channel);
110 } 116 }
@@ -293,13 +299,13 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
293 299
294 client->nr_samples--; 300 client->nr_samples--;
295 301
296 if (cpu != TYPE_ADCV1) { 302 if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) {
297 /* S3C64XX/S5P ADC resolution is 12-bit */
298 data0 &= 0xfff;
299 data1 &= 0xfff;
300 } else {
301 data0 &= 0x3ff; 303 data0 &= 0x3ff;
302 data1 &= 0x3ff; 304 data1 &= 0x3ff;
305 } else {
306 /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */
307 data0 &= 0xfff;
308 data1 &= 0xfff;
303 } 309 }
304 310
305 if (client->convert_cb) 311 if (client->convert_cb)
@@ -320,7 +326,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
320 } 326 }
321 327
322exit: 328exit:
323 if (cpu != TYPE_ADCV1) { 329 if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) {
324 /* Clear ADC interrupt */ 330 /* Clear ADC interrupt */
325 writel(0, adc->regs + S3C64XX_ADCCLRINT); 331 writel(0, adc->regs + S3C64XX_ADCCLRINT);
326 } 332 }
@@ -332,6 +338,7 @@ static int s3c_adc_probe(struct platform_device *pdev)
332 struct device *dev = &pdev->dev; 338 struct device *dev = &pdev->dev;
333 struct adc_device *adc; 339 struct adc_device *adc;
334 struct resource *regs; 340 struct resource *regs;
341 enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
335 int ret; 342 int ret;
336 unsigned tmp; 343 unsigned tmp;
337 344
@@ -394,10 +401,13 @@ static int s3c_adc_probe(struct platform_device *pdev)
394 clk_enable(adc->clk); 401 clk_enable(adc->clk);
395 402
396 tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; 403 tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
397 if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) { 404
398 /* Enable 12-bit ADC resolution */ 405 /* Enable 12-bit ADC resolution */
406 if (cpu == TYPE_ADCV12)
407 tmp |= S3C2416_ADCCON_RESSEL;
408 if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
399 tmp |= S3C64XX_ADCCON_RESSEL; 409 tmp |= S3C64XX_ADCCON_RESSEL;
400 } 410
401 writel(tmp, adc->regs + S3C2410_ADCCON); 411 writel(tmp, adc->regs + S3C2410_ADCCON);
402 412
403 dev_info(dev, "attached adc driver\n"); 413 dev_info(dev, "attached adc driver\n");
@@ -464,6 +474,7 @@ static int s3c_adc_resume(struct device *dev)
464 struct platform_device *pdev = container_of(dev, 474 struct platform_device *pdev = container_of(dev,
465 struct platform_device, dev); 475 struct platform_device, dev);
466 struct adc_device *adc = platform_get_drvdata(pdev); 476 struct adc_device *adc = platform_get_drvdata(pdev);
477 enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
467 int ret; 478 int ret;
468 unsigned long tmp; 479 unsigned long tmp;
469 480
@@ -474,9 +485,13 @@ static int s3c_adc_resume(struct device *dev)
474 enable_irq(adc->irq); 485 enable_irq(adc->irq);
475 486
476 tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; 487 tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
488
477 /* Enable 12-bit ADC resolution */ 489 /* Enable 12-bit ADC resolution */
478 if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) 490 if (cpu == TYPE_ADCV12)
491 tmp |= S3C2416_ADCCON_RESSEL;
492 if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
479 tmp |= S3C64XX_ADCCON_RESSEL; 493 tmp |= S3C64XX_ADCCON_RESSEL;
494
480 writel(tmp, adc->regs + S3C2410_ADCCON); 495 writel(tmp, adc->regs + S3C2410_ADCCON);
481 496
482 return 0; 497 return 0;
@@ -492,6 +507,12 @@ static struct platform_device_id s3c_adc_driver_ids[] = {
492 .name = "s3c24xx-adc", 507 .name = "s3c24xx-adc",
493 .driver_data = TYPE_ADCV1, 508 .driver_data = TYPE_ADCV1,
494 }, { 509 }, {
510 .name = "s3c2443-adc",
511 .driver_data = TYPE_ADCV11,
512 }, {
513 .name = "s3c2416-adc",
514 .driver_data = TYPE_ADCV12,
515 }, {
495 .name = "s3c64xx-adc", 516 .name = "s3c64xx-adc",
496 .driver_data = TYPE_ADCV2, 517 .driver_data = TYPE_ADCV2,
497 }, { 518 }, {
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
deleted file mode 100644
index 9d903d4095ed..000000000000
--- a/arch/arm/plat-samsung/dev-adc.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-adc.c
2 *
3 * Copyright 2010 Maurus Cuelenaere
4 *
5 * S3C64xx series device definition for ADC device
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18
19#include <plat/adc.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23static struct resource s3c_adc_resource[] = {
24 [0] = {
25 .start = SAMSUNG_PA_ADC,
26 .end = SAMSUNG_PA_ADC + SZ_256 - 1,
27 .flags = IORESOURCE_MEM,
28 },
29 [1] = {
30 .start = IRQ_TC,
31 .end = IRQ_TC,
32 .flags = IORESOURCE_IRQ,
33 },
34 [2] = {
35 .start = IRQ_ADC,
36 .end = IRQ_ADC,
37 .flags = IORESOURCE_IRQ,
38 },
39};
40
41struct platform_device s3c_device_adc = {
42 .name = "samsung-adc",
43 .id = -1,
44 .num_resources = ARRAY_SIZE(s3c_adc_resource),
45 .resource = s3c_adc_resource,
46};
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
deleted file mode 100644
index 97e35d3c064d..000000000000
--- a/arch/arm/plat-samsung/dev-asocdma.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-asocdma.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co. Ltd
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <plat/devs.h>
14
15static u64 audio_dmamask = DMA_BIT_MASK(32);
16
17struct platform_device samsung_asoc_dma = {
18 .name = "samsung-audio",
19 .id = -1,
20 .dev = {
21 .dma_mask = &audio_dmamask,
22 .coherent_dma_mask = DMA_BIT_MASK(32),
23 }
24};
25EXPORT_SYMBOL(samsung_asoc_dma);
26
27struct platform_device samsung_asoc_idma = {
28 .name = "samsung-idma",
29 .id = -1,
30 .dev = {
31 .dma_mask = &audio_dmamask,
32 .coherent_dma_mask = DMA_BIT_MASK(32),
33 }
34};
35EXPORT_SYMBOL(samsung_asoc_idma);
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index 3cedd4c407af..2adbeaed4c04 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/pwm_backlight.h> 16#include <linux/pwm_backlight.h>
17#include <linux/slab.h>
17 18
18#include <plat/devs.h> 19#include <plat/devs.h>
19#include <plat/gpio-cfg.h> 20#include <plat/gpio-cfg.h>
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
deleted file mode 100644
index 49a1362fd25b..000000000000
--- a/arch/arm/plat-samsung/dev-fb.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-fb.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for framebuffer device
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17#include <linux/fb.h>
18#include <linux/gfp.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/fb.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_fb_resource[] = {
28 [0] = {
29 .start = S3C_PA_FB,
30 .end = S3C_PA_FB + SZ_16K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_LCD_VSYNC,
35 .end = IRQ_LCD_VSYNC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = IRQ_LCD_FIFO,
40 .end = IRQ_LCD_FIFO,
41 .flags = IORESOURCE_IRQ,
42 },
43 [3] = {
44 .start = IRQ_LCD_SYSTEM,
45 .end = IRQ_LCD_SYSTEM,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50struct platform_device s3c_device_fb = {
51 .name = "s3c-fb",
52 .id = -1,
53 .num_resources = ARRAY_SIZE(s3c_fb_resource),
54 .resource = s3c_fb_resource,
55 .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask,
56 .dev.coherent_dma_mask = 0xffffffffUL,
57};
58
59void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
60{
61 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
62 &s3c_device_fb);
63}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
deleted file mode 100644
index 06825c4276de..000000000000
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for hsmmc devices
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mmc/host.h>
17
18#include <mach/map.h>
19#include <plat/sdhci.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23#define S3C_SZ_HSMMC (0x1000)
24
25static struct resource s3c_hsmmc_resource[] = {
26 [0] = {
27 .start = S3C_PA_HSMMC0,
28 .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_HSMMC0,
33 .end = IRQ_HSMMC0,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
39
40struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
45};
46
47struct platform_device s3c_device_hsmmc0 = {
48 .name = "s3c-sdhci",
49 .id = 0,
50 .num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
51 .resource = s3c_hsmmc_resource,
52 .dev = {
53 .dma_mask = &s3c_device_hsmmc_dmamask,
54 .coherent_dma_mask = 0xffffffffUL,
55 .platform_data = &s3c_hsmmc0_def_platdata,
56 },
57};
58
59void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
60{
61 s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
62}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
deleted file mode 100644
index 4524ef440010..000000000000
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for hsmmc device 1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mmc/host.h>
17
18#include <mach/map.h>
19#include <plat/sdhci.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23#define S3C_SZ_HSMMC (0x1000)
24
25static struct resource s3c_hsmmc1_resource[] = {
26 [0] = {
27 .start = S3C_PA_HSMMC1,
28 .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_HSMMC1,
33 .end = IRQ_HSMMC1,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
39
40struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
45};
46
47struct platform_device s3c_device_hsmmc1 = {
48 .name = "s3c-sdhci",
49 .id = 1,
50 .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource),
51 .resource = s3c_hsmmc1_resource,
52 .dev = {
53 .dma_mask = &s3c_device_hsmmc1_dmamask,
54 .coherent_dma_mask = 0xffffffffUL,
55 .platform_data = &s3c_hsmmc1_def_platdata,
56 },
57};
58
59void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
60{
61 s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
62}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
deleted file mode 100644
index 9cede9615e48..000000000000
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
2 *
3 * Copyright (c) 2009 Samsung Electronics
4 * Copyright (c) 2009 Maurus Cuelenaere
5 *
6 * Based on arch/arm/plat-s3c/dev-hsmmc1.c
7 * original file Copyright (c) 2008 Simtec Electronics
8 *
9 * S3C series device definition for hsmmc device 2
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18#include <linux/mmc/host.h>
19
20#include <mach/map.h>
21#include <plat/sdhci.h>
22#include <plat/devs.h>
23
24#define S3C_SZ_HSMMC (0x1000)
25
26static struct resource s3c_hsmmc2_resource[] = {
27 [0] = {
28 .start = S3C_PA_HSMMC2,
29 .end = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_HSMMC2,
34 .end = IRQ_HSMMC2,
35 .flags = IORESOURCE_IRQ,
36 }
37};
38
39static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
40
41struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
42 .max_width = 4,
43 .host_caps = (MMC_CAP_4_BIT_DATA |
44 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
45 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
46};
47
48struct platform_device s3c_device_hsmmc2 = {
49 .name = "s3c-sdhci",
50 .id = 2,
51 .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource),
52 .resource = s3c_hsmmc2_resource,
53 .dev = {
54 .dma_mask = &s3c_device_hsmmc2_dmamask,
55 .coherent_dma_mask = 0xffffffffUL,
56 .platform_data = &s3c_hsmmc2_def_platdata,
57 },
58};
59
60void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
61{
62 s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
63}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
deleted file mode 100644
index 0358ef4a8f66..000000000000
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ /dev/null
@@ -1,66 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * Based on arch/arm/plat-samsung/dev-hsmmc1.c
11 *
12 * Samsung device definition for hsmmc device 3
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17*/
18
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/mmc/host.h>
22
23#include <mach/map.h>
24#include <plat/sdhci.h>
25#include <plat/devs.h>
26
27#define S3C_SZ_HSMMC (0x1000)
28
29static struct resource s3c_hsmmc3_resource[] = {
30 [0] = {
31 .start = S3C_PA_HSMMC3,
32 .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
33 .flags = IORESOURCE_MEM,
34 },
35 [1] = {
36 .start = IRQ_HSMMC3,
37 .end = IRQ_HSMMC3,
38 .flags = IORESOURCE_IRQ,
39 }
40};
41
42static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
43
44struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
45 .max_width = 4,
46 .host_caps = (MMC_CAP_4_BIT_DATA |
47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
48 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
49};
50
51struct platform_device s3c_device_hsmmc3 = {
52 .name = "s3c-sdhci",
53 .id = 3,
54 .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
55 .resource = s3c_hsmmc3_resource,
56 .dev = {
57 .dma_mask = &s3c_device_hsmmc3_dmamask,
58 .coherent_dma_mask = 0xffffffffUL,
59 .platform_data = &s3c_hsmmc3_def_platdata,
60 },
61};
62
63void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
64{
65 s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
66}
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
deleted file mode 100644
index c91a79ce8f39..000000000000
--- a/arch/arm/plat-samsung/dev-hwmon.c
+++ /dev/null
@@ -1,32 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-hwmon.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * Adapted for HWMON by Maurus Cuelenaere
8 *
9 * Samsung series device definition for HWMON
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <plat/devs.h>
20#include <plat/hwmon.h>
21
22struct platform_device s3c_device_hwmon = {
23 .name = "s3c-hwmon",
24 .id = -1,
25 .dev.parent = &s3c_device_adc.dev,
26};
27
28void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
29{
30 s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
31 &s3c_device_hwmon);
32}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
deleted file mode 100644
index f8251f5098bd..000000000000
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-i2c0.c
2 *
3 * Copyright 2008-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for i2c device 0
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/regs-iic.h>
23#include <plat/iic.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_i2c_resource[] = {
28 [0] = {
29 .start = S3C_PA_IIC,
30 .end = S3C_PA_IIC + SZ_4K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_IIC,
35 .end = IRQ_IIC,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s3c_device_i2c0 = {
41 .name = "s3c2410-i2c",
42#ifdef CONFIG_S3C_DEV_I2C1
43 .id = 0,
44#else
45 .id = -1,
46#endif
47 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
48 .resource = s3c_i2c_resource,
49};
50
51struct s3c2410_platform_i2c default_i2c_data __initdata = {
52 .flags = 0,
53 .slave_addr = 0x10,
54 .frequency = 100*1000,
55 .sda_delay = 100,
56};
57
58void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
59{
60 struct s3c2410_platform_i2c *npd;
61
62 if (!pd)
63 pd = &default_i2c_data;
64
65 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
66 &s3c_device_i2c0);
67
68 if (!npd->cfg_gpio)
69 npd->cfg_gpio = s3c_i2c0_cfg_gpio;
70}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
deleted file mode 100644
index 3b7c7bec1cf9..000000000000
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-i2c1.c
2 *
3 * Copyright 2008-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for i2c device 1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/regs-iic.h>
23#include <plat/iic.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_i2c_resource[] = {
28 [0] = {
29 .start = S3C_PA_IIC1,
30 .end = S3C_PA_IIC1 + SZ_4K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_IIC1,
35 .end = IRQ_IIC1,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s3c_device_i2c1 = {
41 .name = "s3c2410-i2c",
42 .id = 1,
43 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
44 .resource = s3c_i2c_resource,
45};
46
47void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
48{
49 struct s3c2410_platform_i2c *npd;
50
51 if (!pd) {
52 pd = &default_i2c_data;
53 pd->bus_num = 1;
54 }
55
56 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
57 &s3c_device_i2c1);
58
59 if (!npd->cfg_gpio)
60 npd->cfg_gpio = s3c_i2c1_cfg_gpio;
61}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
deleted file mode 100644
index 07e9fd0b1b8b..000000000000
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-i2c2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S3C series device definition for i2c device 2
7 *
8 * Based on plat-samsung/dev-i2c0.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/gfp.h>
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/regs-iic.h>
24#include <plat/iic.h>
25#include <plat/devs.h>
26#include <plat/cpu.h>
27
28static struct resource s3c_i2c_resource[] = {
29 [0] = {
30 .start = S3C_PA_IIC2,
31 .end = S3C_PA_IIC2 + SZ_4K - 1,
32 .flags = IORESOURCE_MEM,
33 },
34 [1] = {
35 .start = IRQ_IIC2,
36 .end = IRQ_IIC2,
37 .flags = IORESOURCE_IRQ,
38 },
39};
40
41struct platform_device s3c_device_i2c2 = {
42 .name = "s3c2410-i2c",
43 .id = 2,
44 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
45 .resource = s3c_i2c_resource,
46};
47
48void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
49{
50 struct s3c2410_platform_i2c *npd;
51
52 if (!pd) {
53 pd = &default_i2c_data;
54 pd->bus_num = 2;
55 }
56
57 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
58 &s3c_device_i2c2);
59
60 if (!npd->cfg_gpio)
61 npd->cfg_gpio = s3c_i2c2_cfg_gpio;
62}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
deleted file mode 100644
index d48efa93c6e7..000000000000
--- a/arch/arm/plat-samsung/dev-i2c3.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC3,
29 .end = S3C_PA_IIC3 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC3,
34 .end = IRQ_IIC3,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c3 = {
40 .name = "s3c2440-i2c",
41 .id = 3,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 3;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c3);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c3_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
deleted file mode 100644
index 07e26444efe6..000000000000
--- a/arch/arm/plat-samsung/dev-i2c4.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-i2c4.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC4,
29 .end = S3C_PA_IIC4 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC4,
34 .end = IRQ_IIC4,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c4 = {
40 .name = "s3c2440-i2c",
41 .id = 4,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 4;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c4);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c4_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
deleted file mode 100644
index f49655784563..000000000000
--- a/arch/arm/plat-samsung/dev-i2c5.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC5,
29 .end = S3C_PA_IIC5 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC5,
34 .end = IRQ_IIC5,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c5 = {
40 .name = "s3c2440-i2c",
41 .id = 5,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 5;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c5);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c5_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
deleted file mode 100644
index 141d799944e2..000000000000
--- a/arch/arm/plat-samsung/dev-i2c6.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-i2c6.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 6
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC6,
29 .end = S3C_PA_IIC6 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC6,
34 .end = IRQ_IIC6,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c6 = {
40 .name = "s3c2440-i2c",
41 .id = 6,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 6;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c6);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c6_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
deleted file mode 100644
index 9dddcd1665b5..000000000000
--- a/arch/arm/plat-samsung/dev-i2c7.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-i2c7.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 7
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC7,
29 .end = S3C_PA_IIC7 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC7,
34 .end = IRQ_IIC7,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c7 = {
40 .name = "s3c2440-i2c",
41 .id = 7,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 7;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c7);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c7_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
deleted file mode 100644
index b497982795a7..000000000000
--- a/arch/arm/plat-samsung/dev-ide.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-ide.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA device definition.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16
17#include <mach/map.h>
18#include <plat/ata.h>
19#include <plat/devs.h>
20
21static struct resource s3c_cfcon_resource[] = {
22 [0] = {
23 .start = SAMSUNG_PA_CFCON,
24 .end = SAMSUNG_PA_CFCON + SZ_16K - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_CFCON,
29 .end = IRQ_CFCON,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device s3c_device_cfcon = {
35 .id = 0,
36 .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
37 .resource = s3c_cfcon_resource,
38};
39
40void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
41{
42 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
43 &s3c_device_cfcon);
44}
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c
deleted file mode 100644
index 677c2d731b65..000000000000
--- a/arch/arm/plat-samsung/dev-keypad.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * linux/arch/arm/plat-samsung/dev-keypad.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include <mach/irqs.h>
16#include <mach/map.h>
17#include <plat/cpu.h>
18#include <plat/devs.h>
19#include <plat/keypad.h>
20
21static struct resource samsung_keypad_resources[] = {
22 [0] = {
23 .start = SAMSUNG_PA_KEYPAD,
24 .end = SAMSUNG_PA_KEYPAD + 0x20 - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_KEYPAD,
29 .end = IRQ_KEYPAD,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device samsung_device_keypad = {
35 .name = "samsung-keypad",
36 .id = -1,
37 .num_resources = ARRAY_SIZE(samsung_keypad_resources),
38 .resource = samsung_keypad_resources,
39};
40
41void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
42{
43 struct samsung_keypad_platdata *npd;
44
45 npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
46 &samsung_device_keypad);
47
48 if (!npd->cfg_gpio)
49 npd->cfg_gpio = samsung_keypad_cfg_gpio;
50}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
deleted file mode 100644
index b8e30ec6ac26..000000000000
--- a/arch/arm/plat-samsung/dev-nand.c
+++ /dev/null
@@ -1,125 +0,0 @@
1/*
2 * S3C series device definition for nand device
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7*/
8
9#include <linux/gfp.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12
13#include <linux/mtd/mtd.h>
14#include <linux/mtd/partitions.h>
15
16#include <mach/map.h>
17#include <plat/devs.h>
18#include <plat/nand.h>
19
20static struct resource s3c_nand_resource[] = {
21 [0] = {
22 .start = S3C_PA_NAND,
23 .end = S3C_PA_NAND + SZ_1M,
24 .flags = IORESOURCE_MEM,
25 }
26};
27
28struct platform_device s3c_device_nand = {
29 .name = "s3c2410-nand",
30 .id = -1,
31 .num_resources = ARRAY_SIZE(s3c_nand_resource),
32 .resource = s3c_nand_resource,
33};
34
35EXPORT_SYMBOL(s3c_device_nand);
36
37/**
38 * s3c_nand_copy_set() - copy nand set data
39 * @set: The new structure, directly copied from the old.
40 *
41 * Copy all the fields from the NAND set field from what is probably __initdata
42 * to new kernel memory. The code returns 0 if the copy happened correctly or
43 * an error code for the calling function to display.
44 *
45 * Note, we currently do not try and look to see if we've already copied the
46 * data in a previous set.
47 */
48static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
49{
50 void *ptr;
51 int size;
52
53 size = sizeof(struct mtd_partition) * set->nr_partitions;
54 if (size) {
55 ptr = kmemdup(set->partitions, size, GFP_KERNEL);
56 set->partitions = ptr;
57
58 if (!ptr)
59 return -ENOMEM;
60 }
61
62 if (set->nr_map && set->nr_chips) {
63 size = sizeof(int) * set->nr_chips;
64 ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
65 set->nr_map = ptr;
66
67 if (!ptr)
68 return -ENOMEM;
69 }
70
71 if (set->ecc_layout) {
72 ptr = kmemdup(set->ecc_layout,
73 sizeof(struct nand_ecclayout), GFP_KERNEL);
74 set->ecc_layout = ptr;
75
76 if (!ptr)
77 return -ENOMEM;
78 }
79
80 return 0;
81}
82
83void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
84{
85 struct s3c2410_platform_nand *npd;
86 int size;
87 int ret;
88
89 /* note, if we get a failure in allocation, we simply drop out of the
90 * function. If there is so little memory available at initialisation
91 * time then there is little chance the system is going to run.
92 */
93
94 npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
95 &s3c_device_nand);
96 if (!npd)
97 return;
98
99 /* now see if we need to copy any of the nand set data */
100
101 size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
102 if (size) {
103 struct s3c2410_nand_set *from = npd->sets;
104 struct s3c2410_nand_set *to;
105 int i;
106
107 to = kmemdup(from, size, GFP_KERNEL);
108 npd->sets = to; /* set, even if we failed */
109
110 if (!to) {
111 printk(KERN_ERR "%s: no memory for sets\n", __func__);
112 return;
113 }
114
115 for (i = 0; i < npd->nr_sets; i++) {
116 ret = s3c_nand_copy_set(to);
117 if (ret) {
118 printk(KERN_ERR "%s: failed to copy set %d\n",
119 __func__, i);
120 return;
121 }
122 to++;
123 }
124 }
125}
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c
deleted file mode 100644
index f54ae71f0cd2..000000000000
--- a/arch/arm/plat-samsung/dev-onenand.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * linux/arch/arm/plat-samsung/dev-onenand.c
3 *
4 * Copyright (c) 2008-2010 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * S3C64XX/S5PC100 series device definition for OneNAND devices
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16
17#include <mach/irqs.h>
18#include <mach/map.h>
19
20static struct resource s3c_onenand_resources[] = {
21 [0] = {
22 .start = S3C_PA_ONENAND,
23 .end = S3C_PA_ONENAND + 0x400 - 1,
24 .flags = IORESOURCE_MEM,
25 },
26 [1] = {
27 .start = S3C_PA_ONENAND_BUF,
28 .end = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [2] = {
32 .start = IRQ_ONENAND,
33 .end = IRQ_ONENAND,
34 .flags = IORESOURCE_IRQ,
35 },
36};
37
38struct platform_device s3c_device_onenand = {
39 .name = "samsung-onenand",
40 .id = 0,
41 .num_resources = ARRAY_SIZE(s3c_onenand_resources),
42 .resource = s3c_onenand_resources,
43};
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
deleted file mode 100644
index dab47b0e1900..000000000000
--- a/arch/arm/plat-samsung/dev-pwm.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-pwm.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2007 Ben Dooks
7 * Copyright (c) 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
9 *
10 * S3C series device definition for the PWM timer
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kernel.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21
22#include <plat/devs.h>
23
24#define TIMER_RESOURCE_SIZE (1)
25
26#define TIMER_RESOURCE(_tmr, _irq) \
27 (struct resource [TIMER_RESOURCE_SIZE]) { \
28 [0] = { \
29 .start = _irq, \
30 .end = _irq, \
31 .flags = IORESOURCE_IRQ \
32 } \
33 }
34
35#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
36 .name = "s3c24xx-pwm", \
37 .id = _tmr_no, \
38 .num_resources = TIMER_RESOURCE_SIZE, \
39 .resource = TIMER_RESOURCE(_tmr_no, _irq), \
40
41/*
42 * since we already have an static mapping for the timer,
43 * we do not bother setting any IO resource for the base.
44 */
45
46struct platform_device s3c_device_timer[] = {
47 [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
48 [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
49 [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
50 [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
51 [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
52};
53EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c
deleted file mode 100644
index bf4e2267333c..000000000000
--- a/arch/arm/plat-samsung/dev-rtc.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-rtc.c
2 *
3 * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/string.h>
12#include <linux/platform_device.h>
13
14#include <mach/irqs.h>
15#include <mach/map.h>
16
17#include <plat/devs.h>
18
19static struct resource s3c_rtc_resource[] = {
20 [0] = {
21 .start = S3C_PA_RTC,
22 .end = S3C_PA_RTC + 0xff,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_RTC_ALARM,
27 .end = IRQ_RTC_ALARM,
28 .flags = IORESOURCE_IRQ,
29 },
30 [2] = {
31 .start = IRQ_RTC_TIC,
32 .end = IRQ_RTC_TIC,
33 .flags = IORESOURCE_IRQ
34 }
35};
36
37struct platform_device s3c_device_rtc = {
38 .name = "s3c64xx-rtc",
39 .id = -1,
40 .num_resources = ARRAY_SIZE(s3c_rtc_resource),
41 .resource = s3c_rtc_resource,
42};
43EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
deleted file mode 100644
index 5f3d46a9bd88..000000000000
--- a/arch/arm/plat-samsung/dev-ts.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/* linux/arch/arm/mach-s3c64xx/dev-ts.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
6 *
7 * Adapted by Maurus Cuelenaere for s3c64xx
8 *
9 * S3C64XX series device definition for touchscreen device
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/devs.h>
24#include <plat/ts.h>
25
26static struct resource s3c_ts_resource[] = {
27 [0] = {
28 .start = SAMSUNG_PA_ADC,
29 .end = SAMSUNG_PA_ADC + SZ_256 - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_TC,
34 .end = IRQ_TC,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_ts = {
40 .name = "s3c64xx-ts",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(s3c_ts_resource),
43 .resource = s3c_ts_resource,
44};
45
46static struct s3c2410_ts_mach_info default_ts_data __initdata = {
47 .delay = 10000,
48 .presc = 49,
49 .oversampling_shift = 2,
50};
51
52void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
53{
54 if (!pd)
55 pd = &default_ts_data;
56
57 s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
58 &s3c_device_ts);
59}
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c
deleted file mode 100644
index 33a844ab6917..000000000000
--- a/arch/arm/plat-samsung/dev-usb-hsotg.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for USB high-speed UDC/OtG block
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17#include <linux/dma-mapping.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/devs.h>
23
24static struct resource s3c_usb_hsotg_resources[] = {
25 [0] = {
26 .start = S3C_PA_USB_HSOTG,
27 .end = S3C_PA_USB_HSOTG + 0x10000 - 1,
28 .flags = IORESOURCE_MEM,
29 },
30 [1] = {
31 .start = IRQ_OTG,
32 .end = IRQ_OTG,
33 .flags = IORESOURCE_IRQ,
34 },
35};
36
37static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
38
39struct platform_device s3c_device_usb_hsotg = {
40 .name = "s3c-hsotg",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
43 .resource = s3c_usb_hsotg_resources,
44 .dev = {
45 .dma_mask = &s3c_hsotg_dmamask,
46 .coherent_dma_mask = DMA_BIT_MASK(32),
47 },
48};
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
deleted file mode 100644
index 33fbaa967700..000000000000
--- a/arch/arm/plat-samsung/dev-usb.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/* linux/arch/arm/plat-s3c/dev-usb.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for USB host
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/devs.h>
23#include <plat/usb-control.h>
24
25static struct resource s3c_usb_resource[] = {
26 [0] = {
27 .start = S3C_PA_USBHOST,
28 .end = S3C_PA_USBHOST + 0x100 - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_USBH,
33 .end = IRQ_USBH,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_usb_dmamask = 0xffffffffUL;
39
40struct platform_device s3c_device_ohci = {
41 .name = "s3c2410-ohci",
42 .id = -1,
43 .num_resources = ARRAY_SIZE(s3c_usb_resource),
44 .resource = s3c_usb_resource,
45 .dev = {
46 .dma_mask = &s3c_device_usb_dmamask,
47 .coherent_dma_mask = 0xffffffffUL
48 }
49};
50
51EXPORT_SYMBOL(s3c_device_ohci);
52
53/**
54 * s3c_ohci_set_platdata - initialise OHCI device platform data
55 * @info: The platform data.
56 *
57 * This call copies the @info passed in and sets the device .platform_data
58 * field to that copy. The @info is copied so that the original can be marked
59 * __initdata.
60 */
61void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
62{
63 s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
64 &s3c_device_ohci);
65}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
deleted file mode 100644
index 019b5b8cf14c..000000000000
--- a/arch/arm/plat-samsung/dev-wdt.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/* linux/arch/arm/plat-samsung/dev-wdt.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C series device definition for the watchdog timer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18
19#include <plat/devs.h>
20
21static struct resource s3c_wdt_resource[] = {
22 [0] = {
23 .start = S3C_PA_WDT,
24 .end = S3C_PA_WDT + SZ_1K,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_WDT,
29 .end = IRQ_WDT,
30 .flags = IORESOURCE_IRQ,
31 }
32};
33
34struct platform_device s3c_device_wdt = {
35 .name = "s3c2410-wdt",
36 .id = -1,
37 .num_resources = ARRAY_SIZE(s3c_wdt_resource),
38 .resource = s3c_wdt_resource,
39};
40EXPORT_SYMBOL(s3c_device_wdt);
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
new file mode 100644
index 000000000000..4ca8b571f971
--- /dev/null
+++ b/arch/arm/plat-samsung/devs.c
@@ -0,0 +1,1463 @@
1/* linux/arch/arm/plat-samsung/devs.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Base SAMSUNG platform device definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/serial_core.h>
20#include <linux/platform_device.h>
21#include <linux/io.h>
22#include <linux/slab.h>
23#include <linux/string.h>
24#include <linux/dma-mapping.h>
25#include <linux/fb.h>
26#include <linux/gfp.h>
27#include <linux/mtd/mtd.h>
28#include <linux/mtd/onenand.h>
29#include <linux/mtd/partitions.h>
30#include <linux/mmc/host.h>
31#include <linux/ioport.h>
32
33#include <asm/irq.h>
34#include <asm/pmu.h>
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/irq.h>
38
39#include <mach/hardware.h>
40#include <mach/dma.h>
41#include <mach/irqs.h>
42#include <mach/map.h>
43
44#include <plat/cpu.h>
45#include <plat/devs.h>
46#include <plat/adc.h>
47#include <plat/ata.h>
48#include <plat/ehci.h>
49#include <plat/fb.h>
50#include <plat/fb-s3c2410.h>
51#include <plat/hwmon.h>
52#include <plat/iic.h>
53#include <plat/keypad.h>
54#include <plat/mci.h>
55#include <plat/nand.h>
56#include <plat/sdhci.h>
57#include <plat/ts.h>
58#include <plat/udc.h>
59#include <plat/usb-control.h>
60#include <plat/usb-phy.h>
61#include <plat/regs-iic.h>
62#include <plat/regs-serial.h>
63#include <plat/regs-spi.h>
64
65static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
66
67/* AC97 */
68#ifdef CONFIG_CPU_S3C2440
69static struct resource s3c_ac97_resource[] = {
70 [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
71 [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
72 [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
73 [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
74 [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
75};
76
77struct platform_device s3c_device_ac97 = {
78 .name = "samsung-ac97",
79 .id = -1,
80 .num_resources = ARRAY_SIZE(s3c_ac97_resource),
81 .resource = s3c_ac97_resource,
82 .dev = {
83 .dma_mask = &samsung_device_dma_mask,
84 .coherent_dma_mask = DMA_BIT_MASK(32),
85 }
86};
87#endif /* CONFIG_CPU_S3C2440 */
88
89/* ADC */
90
91#ifdef CONFIG_PLAT_S3C24XX
92static struct resource s3c_adc_resource[] = {
93 [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
94 [1] = DEFINE_RES_IRQ(IRQ_TC),
95 [2] = DEFINE_RES_IRQ(IRQ_ADC),
96};
97
98struct platform_device s3c_device_adc = {
99 .name = "s3c24xx-adc",
100 .id = -1,
101 .num_resources = ARRAY_SIZE(s3c_adc_resource),
102 .resource = s3c_adc_resource,
103};
104#endif /* CONFIG_PLAT_S3C24XX */
105
106#if defined(CONFIG_SAMSUNG_DEV_ADC)
107static struct resource s3c_adc_resource[] = {
108 [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
109 [1] = DEFINE_RES_IRQ(IRQ_TC),
110 [2] = DEFINE_RES_IRQ(IRQ_ADC),
111};
112
113struct platform_device s3c_device_adc = {
114 .name = "samsung-adc",
115 .id = -1,
116 .num_resources = ARRAY_SIZE(s3c_adc_resource),
117 .resource = s3c_adc_resource,
118};
119#endif /* CONFIG_SAMSUNG_DEV_ADC */
120
121/* Camif Controller */
122
123#ifdef CONFIG_CPU_S3C2440
124static struct resource s3c_camif_resource[] = {
125 [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF),
126 [1] = DEFINE_RES_IRQ(IRQ_CAM),
127};
128
129struct platform_device s3c_device_camif = {
130 .name = "s3c2440-camif",
131 .id = -1,
132 .num_resources = ARRAY_SIZE(s3c_camif_resource),
133 .resource = s3c_camif_resource,
134 .dev = {
135 .dma_mask = &samsung_device_dma_mask,
136 .coherent_dma_mask = DMA_BIT_MASK(32),
137 }
138};
139#endif /* CONFIG_CPU_S3C2440 */
140
141/* ASOC DMA */
142
143struct platform_device samsung_asoc_dma = {
144 .name = "samsung-audio",
145 .id = -1,
146 .dev = {
147 .dma_mask = &samsung_device_dma_mask,
148 .coherent_dma_mask = DMA_BIT_MASK(32),
149 }
150};
151
152struct platform_device samsung_asoc_idma = {
153 .name = "samsung-idma",
154 .id = -1,
155 .dev = {
156 .dma_mask = &samsung_device_dma_mask,
157 .coherent_dma_mask = DMA_BIT_MASK(32),
158 }
159};
160
161/* FB */
162
163#ifdef CONFIG_S3C_DEV_FB
164static struct resource s3c_fb_resource[] = {
165 [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),
166 [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC),
167 [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO),
168 [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),
169};
170
171struct platform_device s3c_device_fb = {
172 .name = "s3c-fb",
173 .id = -1,
174 .num_resources = ARRAY_SIZE(s3c_fb_resource),
175 .resource = s3c_fb_resource,
176 .dev = {
177 .dma_mask = &samsung_device_dma_mask,
178 .coherent_dma_mask = DMA_BIT_MASK(32),
179 },
180};
181
182void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
183{
184 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
185 &s3c_device_fb);
186}
187#endif /* CONFIG_S3C_DEV_FB */
188
189/* FIMC */
190
191#ifdef CONFIG_S5P_DEV_FIMC0
192static struct resource s5p_fimc0_resource[] = {
193 [0] = DEFINE_RES_MEM(S5P_PA_FIMC0, SZ_4K),
194 [1] = DEFINE_RES_IRQ(IRQ_FIMC0),
195};
196
197struct platform_device s5p_device_fimc0 = {
198 .name = "s5p-fimc",
199 .id = 0,
200 .num_resources = ARRAY_SIZE(s5p_fimc0_resource),
201 .resource = s5p_fimc0_resource,
202 .dev = {
203 .dma_mask = &samsung_device_dma_mask,
204 .coherent_dma_mask = DMA_BIT_MASK(32),
205 },
206};
207
208struct platform_device s5p_device_fimc_md = {
209 .name = "s5p-fimc-md",
210 .id = -1,
211};
212#endif /* CONFIG_S5P_DEV_FIMC0 */
213
214#ifdef CONFIG_S5P_DEV_FIMC1
215static struct resource s5p_fimc1_resource[] = {
216 [0] = DEFINE_RES_MEM(S5P_PA_FIMC1, SZ_4K),
217 [1] = DEFINE_RES_IRQ(IRQ_FIMC1),
218};
219
220struct platform_device s5p_device_fimc1 = {
221 .name = "s5p-fimc",
222 .id = 1,
223 .num_resources = ARRAY_SIZE(s5p_fimc1_resource),
224 .resource = s5p_fimc1_resource,
225 .dev = {
226 .dma_mask = &samsung_device_dma_mask,
227 .coherent_dma_mask = DMA_BIT_MASK(32),
228 },
229};
230#endif /* CONFIG_S5P_DEV_FIMC1 */
231
232#ifdef CONFIG_S5P_DEV_FIMC2
233static struct resource s5p_fimc2_resource[] = {
234 [0] = DEFINE_RES_MEM(S5P_PA_FIMC2, SZ_4K),
235 [1] = DEFINE_RES_IRQ(IRQ_FIMC2),
236};
237
238struct platform_device s5p_device_fimc2 = {
239 .name = "s5p-fimc",
240 .id = 2,
241 .num_resources = ARRAY_SIZE(s5p_fimc2_resource),
242 .resource = s5p_fimc2_resource,
243 .dev = {
244 .dma_mask = &samsung_device_dma_mask,
245 .coherent_dma_mask = DMA_BIT_MASK(32),
246 },
247};
248#endif /* CONFIG_S5P_DEV_FIMC2 */
249
250#ifdef CONFIG_S5P_DEV_FIMC3
251static struct resource s5p_fimc3_resource[] = {
252 [0] = DEFINE_RES_MEM(S5P_PA_FIMC3, SZ_4K),
253 [1] = DEFINE_RES_IRQ(IRQ_FIMC3),
254};
255
256struct platform_device s5p_device_fimc3 = {
257 .name = "s5p-fimc",
258 .id = 3,
259 .num_resources = ARRAY_SIZE(s5p_fimc3_resource),
260 .resource = s5p_fimc3_resource,
261 .dev = {
262 .dma_mask = &samsung_device_dma_mask,
263 .coherent_dma_mask = DMA_BIT_MASK(32),
264 },
265};
266#endif /* CONFIG_S5P_DEV_FIMC3 */
267
268/* FIMD0 */
269
270#ifdef CONFIG_S5P_DEV_FIMD0
271static struct resource s5p_fimd0_resource[] = {
272 [0] = DEFINE_RES_MEM(S5P_PA_FIMD0, SZ_32K),
273 [1] = DEFINE_RES_IRQ(IRQ_FIMD0_VSYNC),
274 [2] = DEFINE_RES_IRQ(IRQ_FIMD0_FIFO),
275 [3] = DEFINE_RES_IRQ(IRQ_FIMD0_SYSTEM),
276};
277
278struct platform_device s5p_device_fimd0 = {
279 .name = "s5p-fb",
280 .id = 0,
281 .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
282 .resource = s5p_fimd0_resource,
283 .dev = {
284 .dma_mask = &samsung_device_dma_mask,
285 .coherent_dma_mask = DMA_BIT_MASK(32),
286 },
287};
288
289void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
290{
291 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
292 &s5p_device_fimd0);
293}
294#endif /* CONFIG_S5P_DEV_FIMD0 */
295
296/* HWMON */
297
298#ifdef CONFIG_S3C_DEV_HWMON
299struct platform_device s3c_device_hwmon = {
300 .name = "s3c-hwmon",
301 .id = -1,
302 .dev.parent = &s3c_device_adc.dev,
303};
304
305void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
306{
307 s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
308 &s3c_device_hwmon);
309}
310#endif /* CONFIG_S3C_DEV_HWMON */
311
312/* HSMMC */
313
314#ifdef CONFIG_S3C_DEV_HSMMC
315static struct resource s3c_hsmmc_resource[] = {
316 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K),
317 [1] = DEFINE_RES_IRQ(IRQ_HSMMC0),
318};
319
320struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
321 .max_width = 4,
322 .host_caps = (MMC_CAP_4_BIT_DATA |
323 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
324 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
325};
326
327struct platform_device s3c_device_hsmmc0 = {
328 .name = "s3c-sdhci",
329 .id = 0,
330 .num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
331 .resource = s3c_hsmmc_resource,
332 .dev = {
333 .dma_mask = &samsung_device_dma_mask,
334 .coherent_dma_mask = DMA_BIT_MASK(32),
335 .platform_data = &s3c_hsmmc0_def_platdata,
336 },
337};
338
339void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
340{
341 s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
342}
343#endif /* CONFIG_S3C_DEV_HSMMC */
344
345#ifdef CONFIG_S3C_DEV_HSMMC1
346static struct resource s3c_hsmmc1_resource[] = {
347 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K),
348 [1] = DEFINE_RES_IRQ(IRQ_HSMMC1),
349};
350
351struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
352 .max_width = 4,
353 .host_caps = (MMC_CAP_4_BIT_DATA |
354 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
355 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
356};
357
358struct platform_device s3c_device_hsmmc1 = {
359 .name = "s3c-sdhci",
360 .id = 1,
361 .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource),
362 .resource = s3c_hsmmc1_resource,
363 .dev = {
364 .dma_mask = &samsung_device_dma_mask,
365 .coherent_dma_mask = DMA_BIT_MASK(32),
366 .platform_data = &s3c_hsmmc1_def_platdata,
367 },
368};
369
370void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
371{
372 s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
373}
374#endif /* CONFIG_S3C_DEV_HSMMC1 */
375
376/* HSMMC2 */
377
378#ifdef CONFIG_S3C_DEV_HSMMC2
379static struct resource s3c_hsmmc2_resource[] = {
380 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K),
381 [1] = DEFINE_RES_IRQ(IRQ_HSMMC2),
382};
383
384struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
385 .max_width = 4,
386 .host_caps = (MMC_CAP_4_BIT_DATA |
387 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
388 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
389};
390
391struct platform_device s3c_device_hsmmc2 = {
392 .name = "s3c-sdhci",
393 .id = 2,
394 .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource),
395 .resource = s3c_hsmmc2_resource,
396 .dev = {
397 .dma_mask = &samsung_device_dma_mask,
398 .coherent_dma_mask = DMA_BIT_MASK(32),
399 .platform_data = &s3c_hsmmc2_def_platdata,
400 },
401};
402
403void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
404{
405 s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
406}
407#endif /* CONFIG_S3C_DEV_HSMMC2 */
408
409#ifdef CONFIG_S3C_DEV_HSMMC3
410static struct resource s3c_hsmmc3_resource[] = {
411 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K),
412 [1] = DEFINE_RES_IRQ(IRQ_HSMMC3),
413};
414
415struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
416 .max_width = 4,
417 .host_caps = (MMC_CAP_4_BIT_DATA |
418 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
419 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
420};
421
422struct platform_device s3c_device_hsmmc3 = {
423 .name = "s3c-sdhci",
424 .id = 3,
425 .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
426 .resource = s3c_hsmmc3_resource,
427 .dev = {
428 .dma_mask = &samsung_device_dma_mask,
429 .coherent_dma_mask = DMA_BIT_MASK(32),
430 .platform_data = &s3c_hsmmc3_def_platdata,
431 },
432};
433
434void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
435{
436 s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
437}
438#endif /* CONFIG_S3C_DEV_HSMMC3 */
439
440/* I2C */
441
442static struct resource s3c_i2c0_resource[] = {
443 [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
444 [1] = DEFINE_RES_IRQ(IRQ_IIC),
445};
446
447struct platform_device s3c_device_i2c0 = {
448 .name = "s3c2410-i2c",
449#ifdef CONFIG_S3C_DEV_I2C1
450 .id = 0,
451#else
452 .id = -1,
453#endif
454 .num_resources = ARRAY_SIZE(s3c_i2c0_resource),
455 .resource = s3c_i2c0_resource,
456};
457
458struct s3c2410_platform_i2c default_i2c_data __initdata = {
459 .flags = 0,
460 .slave_addr = 0x10,
461 .frequency = 100*1000,
462 .sda_delay = 100,
463};
464
465void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
466{
467 struct s3c2410_platform_i2c *npd;
468
469 if (!pd)
470 pd = &default_i2c_data;
471
472 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
473 &s3c_device_i2c0);
474
475 if (!npd->cfg_gpio)
476 npd->cfg_gpio = s3c_i2c0_cfg_gpio;
477}
478
479#ifdef CONFIG_S3C_DEV_I2C1
480static struct resource s3c_i2c1_resource[] = {
481 [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K),
482 [1] = DEFINE_RES_IRQ(IRQ_IIC1),
483};
484
485struct platform_device s3c_device_i2c1 = {
486 .name = "s3c2410-i2c",
487 .id = 1,
488 .num_resources = ARRAY_SIZE(s3c_i2c1_resource),
489 .resource = s3c_i2c1_resource,
490};
491
492void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
493{
494 struct s3c2410_platform_i2c *npd;
495
496 if (!pd) {
497 pd = &default_i2c_data;
498 pd->bus_num = 1;
499 }
500
501 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
502 &s3c_device_i2c1);
503
504 if (!npd->cfg_gpio)
505 npd->cfg_gpio = s3c_i2c1_cfg_gpio;
506}
507#endif /* CONFIG_S3C_DEV_I2C1 */
508
509#ifdef CONFIG_S3C_DEV_I2C2
510static struct resource s3c_i2c2_resource[] = {
511 [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K),
512 [1] = DEFINE_RES_IRQ(IRQ_IIC2),
513};
514
515struct platform_device s3c_device_i2c2 = {
516 .name = "s3c2410-i2c",
517 .id = 2,
518 .num_resources = ARRAY_SIZE(s3c_i2c2_resource),
519 .resource = s3c_i2c2_resource,
520};
521
522void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
523{
524 struct s3c2410_platform_i2c *npd;
525
526 if (!pd) {
527 pd = &default_i2c_data;
528 pd->bus_num = 2;
529 }
530
531 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
532 &s3c_device_i2c2);
533
534 if (!npd->cfg_gpio)
535 npd->cfg_gpio = s3c_i2c2_cfg_gpio;
536}
537#endif /* CONFIG_S3C_DEV_I2C2 */
538
539#ifdef CONFIG_S3C_DEV_I2C3
540static struct resource s3c_i2c3_resource[] = {
541 [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K),
542 [1] = DEFINE_RES_IRQ(IRQ_IIC3),
543};
544
545struct platform_device s3c_device_i2c3 = {
546 .name = "s3c2440-i2c",
547 .id = 3,
548 .num_resources = ARRAY_SIZE(s3c_i2c3_resource),
549 .resource = s3c_i2c3_resource,
550};
551
552void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
553{
554 struct s3c2410_platform_i2c *npd;
555
556 if (!pd) {
557 pd = &default_i2c_data;
558 pd->bus_num = 3;
559 }
560
561 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
562 &s3c_device_i2c3);
563
564 if (!npd->cfg_gpio)
565 npd->cfg_gpio = s3c_i2c3_cfg_gpio;
566}
567#endif /*CONFIG_S3C_DEV_I2C3 */
568
569#ifdef CONFIG_S3C_DEV_I2C4
570static struct resource s3c_i2c4_resource[] = {
571 [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K),
572 [1] = DEFINE_RES_IRQ(IRQ_IIC4),
573};
574
575struct platform_device s3c_device_i2c4 = {
576 .name = "s3c2440-i2c",
577 .id = 4,
578 .num_resources = ARRAY_SIZE(s3c_i2c4_resource),
579 .resource = s3c_i2c4_resource,
580};
581
582void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
583{
584 struct s3c2410_platform_i2c *npd;
585
586 if (!pd) {
587 pd = &default_i2c_data;
588 pd->bus_num = 4;
589 }
590
591 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
592 &s3c_device_i2c4);
593
594 if (!npd->cfg_gpio)
595 npd->cfg_gpio = s3c_i2c4_cfg_gpio;
596}
597#endif /*CONFIG_S3C_DEV_I2C4 */
598
599#ifdef CONFIG_S3C_DEV_I2C5
600static struct resource s3c_i2c5_resource[] = {
601 [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K),
602 [1] = DEFINE_RES_IRQ(IRQ_IIC5),
603};
604
605struct platform_device s3c_device_i2c5 = {
606 .name = "s3c2440-i2c",
607 .id = 5,
608 .num_resources = ARRAY_SIZE(s3c_i2c5_resource),
609 .resource = s3c_i2c5_resource,
610};
611
612void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
613{
614 struct s3c2410_platform_i2c *npd;
615
616 if (!pd) {
617 pd = &default_i2c_data;
618 pd->bus_num = 5;
619 }
620
621 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
622 &s3c_device_i2c5);
623
624 if (!npd->cfg_gpio)
625 npd->cfg_gpio = s3c_i2c5_cfg_gpio;
626}
627#endif /*CONFIG_S3C_DEV_I2C5 */
628
629#ifdef CONFIG_S3C_DEV_I2C6
630static struct resource s3c_i2c6_resource[] = {
631 [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K),
632 [1] = DEFINE_RES_IRQ(IRQ_IIC6),
633};
634
635struct platform_device s3c_device_i2c6 = {
636 .name = "s3c2440-i2c",
637 .id = 6,
638 .num_resources = ARRAY_SIZE(s3c_i2c6_resource),
639 .resource = s3c_i2c6_resource,
640};
641
642void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
643{
644 struct s3c2410_platform_i2c *npd;
645
646 if (!pd) {
647 pd = &default_i2c_data;
648 pd->bus_num = 6;
649 }
650
651 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
652 &s3c_device_i2c6);
653
654 if (!npd->cfg_gpio)
655 npd->cfg_gpio = s3c_i2c6_cfg_gpio;
656}
657#endif /* CONFIG_S3C_DEV_I2C6 */
658
659#ifdef CONFIG_S3C_DEV_I2C7
660static struct resource s3c_i2c7_resource[] = {
661 [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K),
662 [1] = DEFINE_RES_IRQ(IRQ_IIC7),
663};
664
665struct platform_device s3c_device_i2c7 = {
666 .name = "s3c2440-i2c",
667 .id = 7,
668 .num_resources = ARRAY_SIZE(s3c_i2c7_resource),
669 .resource = s3c_i2c7_resource,
670};
671
672void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
673{
674 struct s3c2410_platform_i2c *npd;
675
676 if (!pd) {
677 pd = &default_i2c_data;
678 pd->bus_num = 7;
679 }
680
681 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
682 &s3c_device_i2c7);
683
684 if (!npd->cfg_gpio)
685 npd->cfg_gpio = s3c_i2c7_cfg_gpio;
686}
687#endif /* CONFIG_S3C_DEV_I2C7 */
688
689/* I2C HDMIPHY */
690
691#ifdef CONFIG_S5P_DEV_I2C_HDMIPHY
692static struct resource s5p_i2c_resource[] = {
693 [0] = DEFINE_RES_MEM(S5P_PA_IIC_HDMIPHY, SZ_4K),
694 [1] = DEFINE_RES_IRQ(IRQ_IIC_HDMIPHY),
695};
696
697struct platform_device s5p_device_i2c_hdmiphy = {
698 .name = "s3c2440-hdmiphy-i2c",
699 .id = -1,
700 .num_resources = ARRAY_SIZE(s5p_i2c_resource),
701 .resource = s5p_i2c_resource,
702};
703
704void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
705{
706 struct s3c2410_platform_i2c *npd;
707
708 if (!pd) {
709 pd = &default_i2c_data;
710
711 if (soc_is_exynos4210())
712 pd->bus_num = 8;
713 else if (soc_is_s5pv210())
714 pd->bus_num = 3;
715 else
716 pd->bus_num = 0;
717 }
718
719 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
720 &s5p_device_i2c_hdmiphy);
721}
722#endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */
723
724/* I2S */
725
726#ifdef CONFIG_PLAT_S3C24XX
727static struct resource s3c_iis_resource[] = {
728 [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
729};
730
731struct platform_device s3c_device_iis = {
732 .name = "s3c24xx-iis",
733 .id = -1,
734 .num_resources = ARRAY_SIZE(s3c_iis_resource),
735 .resource = s3c_iis_resource,
736 .dev = {
737 .dma_mask = &samsung_device_dma_mask,
738 .coherent_dma_mask = DMA_BIT_MASK(32),
739 }
740};
741#endif /* CONFIG_PLAT_S3C24XX */
742
743#ifdef CONFIG_CPU_S3C2440
744struct platform_device s3c2412_device_iis = {
745 .name = "s3c2412-iis",
746 .id = -1,
747 .dev = {
748 .dma_mask = &samsung_device_dma_mask,
749 .coherent_dma_mask = DMA_BIT_MASK(32),
750 }
751};
752#endif /* CONFIG_CPU_S3C2440 */
753
754/* IDE CFCON */
755
756#ifdef CONFIG_SAMSUNG_DEV_IDE
757static struct resource s3c_cfcon_resource[] = {
758 [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K),
759 [1] = DEFINE_RES_IRQ(IRQ_CFCON),
760};
761
762struct platform_device s3c_device_cfcon = {
763 .id = 0,
764 .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
765 .resource = s3c_cfcon_resource,
766};
767
768void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
769{
770 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
771 &s3c_device_cfcon);
772}
773#endif /* CONFIG_SAMSUNG_DEV_IDE */
774
775/* KEYPAD */
776
777#ifdef CONFIG_SAMSUNG_DEV_KEYPAD
778static struct resource samsung_keypad_resources[] = {
779 [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32),
780 [1] = DEFINE_RES_IRQ(IRQ_KEYPAD),
781};
782
783struct platform_device samsung_device_keypad = {
784 .name = "samsung-keypad",
785 .id = -1,
786 .num_resources = ARRAY_SIZE(samsung_keypad_resources),
787 .resource = samsung_keypad_resources,
788};
789
790void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
791{
792 struct samsung_keypad_platdata *npd;
793
794 npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
795 &samsung_device_keypad);
796
797 if (!npd->cfg_gpio)
798 npd->cfg_gpio = samsung_keypad_cfg_gpio;
799}
800#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */
801
802/* LCD Controller */
803
804#ifdef CONFIG_PLAT_S3C24XX
805static struct resource s3c_lcd_resource[] = {
806 [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),
807 [1] = DEFINE_RES_IRQ(IRQ_LCD),
808};
809
810struct platform_device s3c_device_lcd = {
811 .name = "s3c2410-lcd",
812 .id = -1,
813 .num_resources = ARRAY_SIZE(s3c_lcd_resource),
814 .resource = s3c_lcd_resource,
815 .dev = {
816 .dma_mask = &samsung_device_dma_mask,
817 .coherent_dma_mask = DMA_BIT_MASK(32),
818 }
819};
820
821void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
822{
823 struct s3c2410fb_mach_info *npd;
824
825 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
826 if (npd) {
827 npd->displays = kmemdup(pd->displays,
828 sizeof(struct s3c2410fb_display) * npd->num_displays,
829 GFP_KERNEL);
830 if (!npd->displays)
831 printk(KERN_ERR "no memory for LCD display data\n");
832 } else {
833 printk(KERN_ERR "no memory for LCD platform data\n");
834 }
835}
836#endif /* CONFIG_PLAT_S3C24XX */
837
838/* MFC */
839
840#ifdef CONFIG_S5P_DEV_MFC
841static struct resource s5p_mfc_resource[] = {
842 [0] = DEFINE_RES_MEM(S5P_PA_MFC, SZ_64K),
843 [1] = DEFINE_RES_IRQ(IRQ_MFC),
844};
845
846struct platform_device s5p_device_mfc = {
847 .name = "s5p-mfc",
848 .id = -1,
849 .num_resources = ARRAY_SIZE(s5p_mfc_resource),
850 .resource = s5p_mfc_resource,
851};
852
853/*
854 * MFC hardware has 2 memory interfaces which are modelled as two separate
855 * platform devices to let dma-mapping distinguish between them.
856 *
857 * MFC parent device (s5p_device_mfc) must be registered before memory
858 * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
859 */
860
861struct platform_device s5p_device_mfc_l = {
862 .name = "s5p-mfc-l",
863 .id = -1,
864 .dev = {
865 .parent = &s5p_device_mfc.dev,
866 .dma_mask = &samsung_device_dma_mask,
867 .coherent_dma_mask = DMA_BIT_MASK(32),
868 },
869};
870
871struct platform_device s5p_device_mfc_r = {
872 .name = "s5p-mfc-r",
873 .id = -1,
874 .dev = {
875 .parent = &s5p_device_mfc.dev,
876 .dma_mask = &samsung_device_dma_mask,
877 .coherent_dma_mask = DMA_BIT_MASK(32),
878 },
879};
880#endif /* CONFIG_S5P_DEV_MFC */
881
882/* MIPI CSIS */
883
884#ifdef CONFIG_S5P_DEV_CSIS0
885static struct resource s5p_mipi_csis0_resource[] = {
886 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K),
887 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
888};
889
890struct platform_device s5p_device_mipi_csis0 = {
891 .name = "s5p-mipi-csis",
892 .id = 0,
893 .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
894 .resource = s5p_mipi_csis0_resource,
895};
896#endif /* CONFIG_S5P_DEV_CSIS0 */
897
898#ifdef CONFIG_S5P_DEV_CSIS1
899static struct resource s5p_mipi_csis1_resource[] = {
900 [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K),
901 [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
902};
903
904struct platform_device s5p_device_mipi_csis1 = {
905 .name = "s5p-mipi-csis",
906 .id = 1,
907 .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
908 .resource = s5p_mipi_csis1_resource,
909};
910#endif
911
912/* NAND */
913
914#ifdef CONFIG_S3C_DEV_NAND
915static struct resource s3c_nand_resource[] = {
916 [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),
917};
918
919struct platform_device s3c_device_nand = {
920 .name = "s3c2410-nand",
921 .id = -1,
922 .num_resources = ARRAY_SIZE(s3c_nand_resource),
923 .resource = s3c_nand_resource,
924};
925
926/*
927 * s3c_nand_copy_set() - copy nand set data
928 * @set: The new structure, directly copied from the old.
929 *
930 * Copy all the fields from the NAND set field from what is probably __initdata
931 * to new kernel memory. The code returns 0 if the copy happened correctly or
932 * an error code for the calling function to display.
933 *
934 * Note, we currently do not try and look to see if we've already copied the
935 * data in a previous set.
936 */
937static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
938{
939 void *ptr;
940 int size;
941
942 size = sizeof(struct mtd_partition) * set->nr_partitions;
943 if (size) {
944 ptr = kmemdup(set->partitions, size, GFP_KERNEL);
945 set->partitions = ptr;
946
947 if (!ptr)
948 return -ENOMEM;
949 }
950
951 if (set->nr_map && set->nr_chips) {
952 size = sizeof(int) * set->nr_chips;
953 ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
954 set->nr_map = ptr;
955
956 if (!ptr)
957 return -ENOMEM;
958 }
959
960 if (set->ecc_layout) {
961 ptr = kmemdup(set->ecc_layout,
962 sizeof(struct nand_ecclayout), GFP_KERNEL);
963 set->ecc_layout = ptr;
964
965 if (!ptr)
966 return -ENOMEM;
967 }
968
969 return 0;
970}
971
972void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
973{
974 struct s3c2410_platform_nand *npd;
975 int size;
976 int ret;
977
978 /* note, if we get a failure in allocation, we simply drop out of the
979 * function. If there is so little memory available at initialisation
980 * time then there is little chance the system is going to run.
981 */
982
983 npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
984 &s3c_device_nand);
985 if (!npd)
986 return;
987
988 /* now see if we need to copy any of the nand set data */
989
990 size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
991 if (size) {
992 struct s3c2410_nand_set *from = npd->sets;
993 struct s3c2410_nand_set *to;
994 int i;
995
996 to = kmemdup(from, size, GFP_KERNEL);
997 npd->sets = to; /* set, even if we failed */
998
999 if (!to) {
1000 printk(KERN_ERR "%s: no memory for sets\n", __func__);
1001 return;
1002 }
1003
1004 for (i = 0; i < npd->nr_sets; i++) {
1005 ret = s3c_nand_copy_set(to);
1006 if (ret) {
1007 printk(KERN_ERR "%s: failed to copy set %d\n",
1008 __func__, i);
1009 return;
1010 }
1011 to++;
1012 }
1013 }
1014}
1015#endif /* CONFIG_S3C_DEV_NAND */
1016
1017/* ONENAND */
1018
1019#ifdef CONFIG_S3C_DEV_ONENAND
1020static struct resource s3c_onenand_resources[] = {
1021 [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K),
1022 [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF),
1023 [2] = DEFINE_RES_IRQ(IRQ_ONENAND),
1024};
1025
1026struct platform_device s3c_device_onenand = {
1027 .name = "samsung-onenand",
1028 .id = 0,
1029 .num_resources = ARRAY_SIZE(s3c_onenand_resources),
1030 .resource = s3c_onenand_resources,
1031};
1032#endif /* CONFIG_S3C_DEV_ONENAND */
1033
1034#ifdef CONFIG_S3C64XX_DEV_ONENAND1
1035static struct resource s3c64xx_onenand1_resources[] = {
1036 [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K),
1037 [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF),
1038 [2] = DEFINE_RES_IRQ(IRQ_ONENAND1),
1039};
1040
1041struct platform_device s3c64xx_device_onenand1 = {
1042 .name = "samsung-onenand",
1043 .id = 1,
1044 .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources),
1045 .resource = s3c64xx_onenand1_resources,
1046};
1047
1048void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
1049{
1050 s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
1051 &s3c64xx_device_onenand1);
1052}
1053#endif /* CONFIG_S3C64XX_DEV_ONENAND1 */
1054
1055#ifdef CONFIG_S5P_DEV_ONENAND
1056static struct resource s5p_onenand_resources[] = {
1057 [0] = DEFINE_RES_MEM(S5P_PA_ONENAND, SZ_128K),
1058 [1] = DEFINE_RES_MEM(S5P_PA_ONENAND_DMA, SZ_8K),
1059 [2] = DEFINE_RES_IRQ(IRQ_ONENAND_AUDI),
1060};
1061
1062struct platform_device s5p_device_onenand = {
1063 .name = "s5pc110-onenand",
1064 .id = -1,
1065 .num_resources = ARRAY_SIZE(s5p_onenand_resources),
1066 .resource = s5p_onenand_resources,
1067};
1068#endif /* CONFIG_S5P_DEV_ONENAND */
1069
1070/* PMU */
1071
1072#ifdef CONFIG_PLAT_S5P
1073static struct resource s5p_pmu_resource[] = {
1074 DEFINE_RES_IRQ(IRQ_PMU)
1075};
1076
1077struct platform_device s5p_device_pmu = {
1078 .name = "arm-pmu",
1079 .id = ARM_PMU_DEVICE_CPU,
1080 .num_resources = ARRAY_SIZE(s5p_pmu_resource),
1081 .resource = s5p_pmu_resource,
1082};
1083
1084static int __init s5p_pmu_init(void)
1085{
1086 platform_device_register(&s5p_device_pmu);
1087 return 0;
1088}
1089arch_initcall(s5p_pmu_init);
1090#endif /* CONFIG_PLAT_S5P */
1091
1092/* PWM Timer */
1093
1094#ifdef CONFIG_SAMSUNG_DEV_PWM
1095
1096#define TIMER_RESOURCE_SIZE (1)
1097
1098#define TIMER_RESOURCE(_tmr, _irq) \
1099 (struct resource [TIMER_RESOURCE_SIZE]) { \
1100 [0] = { \
1101 .start = _irq, \
1102 .end = _irq, \
1103 .flags = IORESOURCE_IRQ \
1104 } \
1105 }
1106
1107#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
1108 .name = "s3c24xx-pwm", \
1109 .id = _tmr_no, \
1110 .num_resources = TIMER_RESOURCE_SIZE, \
1111 .resource = TIMER_RESOURCE(_tmr_no, _irq), \
1112
1113/*
1114 * since we already have an static mapping for the timer,
1115 * we do not bother setting any IO resource for the base.
1116 */
1117
1118struct platform_device s3c_device_timer[] = {
1119 [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
1120 [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
1121 [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
1122 [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
1123 [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
1124};
1125#endif /* CONFIG_SAMSUNG_DEV_PWM */
1126
1127/* RTC */
1128
1129#ifdef CONFIG_PLAT_S3C24XX
1130static struct resource s3c_rtc_resource[] = {
1131 [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
1132 [1] = DEFINE_RES_IRQ(IRQ_RTC),
1133 [2] = DEFINE_RES_IRQ(IRQ_TICK),
1134};
1135
1136struct platform_device s3c_device_rtc = {
1137 .name = "s3c2410-rtc",
1138 .id = -1,
1139 .num_resources = ARRAY_SIZE(s3c_rtc_resource),
1140 .resource = s3c_rtc_resource,
1141};
1142#endif /* CONFIG_PLAT_S3C24XX */
1143
1144#ifdef CONFIG_S3C_DEV_RTC
1145static struct resource s3c_rtc_resource[] = {
1146 [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256),
1147 [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM),
1148 [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC),
1149};
1150
1151struct platform_device s3c_device_rtc = {
1152 .name = "s3c64xx-rtc",
1153 .id = -1,
1154 .num_resources = ARRAY_SIZE(s3c_rtc_resource),
1155 .resource = s3c_rtc_resource,
1156};
1157#endif /* CONFIG_S3C_DEV_RTC */
1158
1159/* SDI */
1160
1161#ifdef CONFIG_PLAT_S3C24XX
1162static struct resource s3c_sdi_resource[] = {
1163 [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI),
1164 [1] = DEFINE_RES_IRQ(IRQ_SDI),
1165};
1166
1167struct platform_device s3c_device_sdi = {
1168 .name = "s3c2410-sdi",
1169 .id = -1,
1170 .num_resources = ARRAY_SIZE(s3c_sdi_resource),
1171 .resource = s3c_sdi_resource,
1172};
1173
1174void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
1175{
1176 s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
1177 &s3c_device_sdi);
1178}
1179#endif /* CONFIG_PLAT_S3C24XX */
1180
1181/* SPI */
1182
1183#ifdef CONFIG_PLAT_S3C24XX
1184static struct resource s3c_spi0_resource[] = {
1185 [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
1186 [1] = DEFINE_RES_IRQ(IRQ_SPI0),
1187};
1188
1189struct platform_device s3c_device_spi0 = {
1190 .name = "s3c2410-spi",
1191 .id = 0,
1192 .num_resources = ARRAY_SIZE(s3c_spi0_resource),
1193 .resource = s3c_spi0_resource,
1194 .dev = {
1195 .dma_mask = &samsung_device_dma_mask,
1196 .coherent_dma_mask = DMA_BIT_MASK(32),
1197 }
1198};
1199
1200static struct resource s3c_spi1_resource[] = {
1201 [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32),
1202 [1] = DEFINE_RES_IRQ(IRQ_SPI1),
1203};
1204
1205struct platform_device s3c_device_spi1 = {
1206 .name = "s3c2410-spi",
1207 .id = 1,
1208 .num_resources = ARRAY_SIZE(s3c_spi1_resource),
1209 .resource = s3c_spi1_resource,
1210 .dev = {
1211 .dma_mask = &samsung_device_dma_mask,
1212 .coherent_dma_mask = DMA_BIT_MASK(32),
1213 }
1214};
1215#endif /* CONFIG_PLAT_S3C24XX */
1216
1217/* Touchscreen */
1218
1219#ifdef CONFIG_PLAT_S3C24XX
1220static struct resource s3c_ts_resource[] = {
1221 [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
1222 [1] = DEFINE_RES_IRQ(IRQ_TC),
1223};
1224
1225struct platform_device s3c_device_ts = {
1226 .name = "s3c2410-ts",
1227 .id = -1,
1228 .dev.parent = &s3c_device_adc.dev,
1229 .num_resources = ARRAY_SIZE(s3c_ts_resource),
1230 .resource = s3c_ts_resource,
1231};
1232
1233void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
1234{
1235 s3c_set_platdata(hard_s3c2410ts_info,
1236 sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
1237}
1238#endif /* CONFIG_PLAT_S3C24XX */
1239
1240#ifdef CONFIG_SAMSUNG_DEV_TS
1241static struct resource s3c_ts_resource[] = {
1242 [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
1243 [1] = DEFINE_RES_IRQ(IRQ_TC),
1244};
1245
1246static struct s3c2410_ts_mach_info default_ts_data __initdata = {
1247 .delay = 10000,
1248 .presc = 49,
1249 .oversampling_shift = 2,
1250};
1251
1252struct platform_device s3c_device_ts = {
1253 .name = "s3c64xx-ts",
1254 .id = -1,
1255 .num_resources = ARRAY_SIZE(s3c_ts_resource),
1256 .resource = s3c_ts_resource,
1257};
1258
1259void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
1260{
1261 if (!pd)
1262 pd = &default_ts_data;
1263
1264 s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
1265 &s3c_device_ts);
1266}
1267#endif /* CONFIG_SAMSUNG_DEV_TS */
1268
1269/* TV */
1270
1271#ifdef CONFIG_S5P_DEV_TV
1272
1273static struct resource s5p_hdmi_resources[] = {
1274 [0] = DEFINE_RES_MEM(S5P_PA_HDMI, SZ_1M),
1275 [1] = DEFINE_RES_IRQ(IRQ_HDMI),
1276};
1277
1278struct platform_device s5p_device_hdmi = {
1279 .name = "s5p-hdmi",
1280 .id = -1,
1281 .num_resources = ARRAY_SIZE(s5p_hdmi_resources),
1282 .resource = s5p_hdmi_resources,
1283};
1284
1285static struct resource s5p_sdo_resources[] = {
1286 [0] = DEFINE_RES_MEM(S5P_PA_SDO, SZ_64K),
1287 [1] = DEFINE_RES_IRQ(IRQ_SDO),
1288};
1289
1290struct platform_device s5p_device_sdo = {
1291 .name = "s5p-sdo",
1292 .id = -1,
1293 .num_resources = ARRAY_SIZE(s5p_sdo_resources),
1294 .resource = s5p_sdo_resources,
1295};
1296
1297static struct resource s5p_mixer_resources[] = {
1298 [0] = DEFINE_RES_MEM_NAMED(S5P_PA_MIXER, SZ_64K, "mxr"),
1299 [1] = DEFINE_RES_MEM_NAMED(S5P_PA_VP, SZ_64K, "vp"),
1300 [2] = DEFINE_RES_IRQ_NAMED(IRQ_MIXER, "irq"),
1301};
1302
1303struct platform_device s5p_device_mixer = {
1304 .name = "s5p-mixer",
1305 .id = -1,
1306 .num_resources = ARRAY_SIZE(s5p_mixer_resources),
1307 .resource = s5p_mixer_resources,
1308 .dev = {
1309 .dma_mask = &samsung_device_dma_mask,
1310 .coherent_dma_mask = DMA_BIT_MASK(32),
1311 }
1312};
1313#endif /* CONFIG_S5P_DEV_TV */
1314
1315/* USB */
1316
1317#ifdef CONFIG_S3C_DEV_USB_HOST
1318static struct resource s3c_usb_resource[] = {
1319 [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
1320 [1] = DEFINE_RES_IRQ(IRQ_USBH),
1321};
1322
1323struct platform_device s3c_device_ohci = {
1324 .name = "s3c2410-ohci",
1325 .id = -1,
1326 .num_resources = ARRAY_SIZE(s3c_usb_resource),
1327 .resource = s3c_usb_resource,
1328 .dev = {
1329 .dma_mask = &samsung_device_dma_mask,
1330 .coherent_dma_mask = DMA_BIT_MASK(32),
1331 }
1332};
1333
1334/*
1335 * s3c_ohci_set_platdata - initialise OHCI device platform data
1336 * @info: The platform data.
1337 *
1338 * This call copies the @info passed in and sets the device .platform_data
1339 * field to that copy. The @info is copied so that the original can be marked
1340 * __initdata.
1341 */
1342
1343void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
1344{
1345 s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
1346 &s3c_device_ohci);
1347}
1348#endif /* CONFIG_S3C_DEV_USB_HOST */
1349
1350/* USB Device (Gadget) */
1351
1352#ifdef CONFIG_PLAT_S3C24XX
1353static struct resource s3c_usbgadget_resource[] = {
1354 [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),
1355 [1] = DEFINE_RES_IRQ(IRQ_USBD),
1356};
1357
1358struct platform_device s3c_device_usbgadget = {
1359 .name = "s3c2410-usbgadget",
1360 .id = -1,
1361 .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
1362 .resource = s3c_usbgadget_resource,
1363};
1364
1365void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
1366{
1367 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
1368}
1369#endif /* CONFIG_PLAT_S3C24XX */
1370
1371/* USB EHCI Host Controller */
1372
1373#ifdef CONFIG_S5P_DEV_USB_EHCI
1374static struct resource s5p_ehci_resource[] = {
1375 [0] = DEFINE_RES_MEM(S5P_PA_EHCI, SZ_256),
1376 [1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
1377};
1378
1379struct platform_device s5p_device_ehci = {
1380 .name = "s5p-ehci",
1381 .id = -1,
1382 .num_resources = ARRAY_SIZE(s5p_ehci_resource),
1383 .resource = s5p_ehci_resource,
1384 .dev = {
1385 .dma_mask = &samsung_device_dma_mask,
1386 .coherent_dma_mask = DMA_BIT_MASK(32),
1387 }
1388};
1389
1390void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
1391{
1392 struct s5p_ehci_platdata *npd;
1393
1394 npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
1395 &s5p_device_ehci);
1396
1397 if (!npd->phy_init)
1398 npd->phy_init = s5p_usb_phy_init;
1399 if (!npd->phy_exit)
1400 npd->phy_exit = s5p_usb_phy_exit;
1401}
1402#endif /* CONFIG_S5P_DEV_USB_EHCI */
1403
1404/* USB HSOTG */
1405
1406#ifdef CONFIG_S3C_DEV_USB_HSOTG
1407static struct resource s3c_usb_hsotg_resources[] = {
1408 [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_16K),
1409 [1] = DEFINE_RES_IRQ(IRQ_OTG),
1410};
1411
1412struct platform_device s3c_device_usb_hsotg = {
1413 .name = "s3c-hsotg",
1414 .id = -1,
1415 .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
1416 .resource = s3c_usb_hsotg_resources,
1417 .dev = {
1418 .dma_mask = &samsung_device_dma_mask,
1419 .coherent_dma_mask = DMA_BIT_MASK(32),
1420 },
1421};
1422#endif /* CONFIG_S3C_DEV_USB_HSOTG */
1423
1424/* USB High Spped 2.0 Device (Gadget) */
1425
1426#ifdef CONFIG_PLAT_S3C24XX
1427static struct resource s3c_hsudc_resource[] = {
1428 [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
1429 [1] = DEFINE_RES_IRQ(IRQ_USBD),
1430};
1431
1432struct platform_device s3c_device_usb_hsudc = {
1433 .name = "s3c-hsudc",
1434 .id = -1,
1435 .num_resources = ARRAY_SIZE(s3c_hsudc_resource),
1436 .resource = s3c_hsudc_resource,
1437 .dev = {
1438 .dma_mask = &samsung_device_dma_mask,
1439 .coherent_dma_mask = DMA_BIT_MASK(32),
1440 },
1441};
1442
1443void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
1444{
1445 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
1446}
1447#endif /* CONFIG_PLAT_S3C24XX */
1448
1449/* WDT */
1450
1451#ifdef CONFIG_S3C_DEV_WDT
1452static struct resource s3c_wdt_resource[] = {
1453 [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K),
1454 [1] = DEFINE_RES_IRQ(IRQ_WDT),
1455};
1456
1457struct platform_device s3c_device_wdt = {
1458 .name = "s3c2410-wdt",
1459 .id = -1,
1460 .num_resources = ARRAY_SIZE(s3c_wdt_resource),
1461 .resource = s3c_wdt_resource,
1462};
1463#endif /* CONFIG_S3C_DEV_WDT */
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
new file mode 100644
index 000000000000..6e3d9abc9e2e
--- /dev/null
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -0,0 +1,131 @@
1/* linux/arch/arm/plat-samsung/dma-ops.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung DMA Operations
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/amba/pl330.h>
16#include <linux/scatterlist.h>
17
18#include <mach/dma.h>
19
20static inline bool pl330_filter(struct dma_chan *chan, void *param)
21{
22 struct dma_pl330_peri *peri = chan->private;
23 return peri->peri_id == (unsigned)param;
24}
25
26static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
27 struct samsung_dma_info *info)
28{
29 struct dma_chan *chan;
30 dma_cap_mask_t mask;
31 struct dma_slave_config slave_config;
32
33 dma_cap_zero(mask);
34 dma_cap_set(info->cap, mask);
35
36 chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
37
38 if (info->direction == DMA_FROM_DEVICE) {
39 memset(&slave_config, 0, sizeof(struct dma_slave_config));
40 slave_config.direction = info->direction;
41 slave_config.src_addr = info->fifo;
42 slave_config.src_addr_width = info->width;
43 slave_config.src_maxburst = 1;
44 dmaengine_slave_config(chan, &slave_config);
45 } else if (info->direction == DMA_TO_DEVICE) {
46 memset(&slave_config, 0, sizeof(struct dma_slave_config));
47 slave_config.direction = info->direction;
48 slave_config.dst_addr = info->fifo;
49 slave_config.dst_addr_width = info->width;
50 slave_config.dst_maxburst = 1;
51 dmaengine_slave_config(chan, &slave_config);
52 }
53
54 return (unsigned)chan;
55}
56
57static int samsung_dmadev_release(unsigned ch,
58 struct s3c2410_dma_client *client)
59{
60 dma_release_channel((struct dma_chan *)ch);
61
62 return 0;
63}
64
65static int samsung_dmadev_prepare(unsigned ch,
66 struct samsung_dma_prep_info *info)
67{
68 struct scatterlist sg;
69 struct dma_chan *chan = (struct dma_chan *)ch;
70 struct dma_async_tx_descriptor *desc;
71
72 switch (info->cap) {
73 case DMA_SLAVE:
74 sg_init_table(&sg, 1);
75 sg_dma_len(&sg) = info->len;
76 sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)),
77 info->len, offset_in_page(info->buf));
78 sg_dma_address(&sg) = info->buf;
79
80 desc = chan->device->device_prep_slave_sg(chan,
81 &sg, 1, info->direction, DMA_PREP_INTERRUPT);
82 break;
83 case DMA_CYCLIC:
84 desc = chan->device->device_prep_dma_cyclic(chan,
85 info->buf, info->len, info->period, info->direction);
86 break;
87 default:
88 dev_err(&chan->dev->device, "unsupported format\n");
89 return -EFAULT;
90 }
91
92 if (!desc) {
93 dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
94 return -EFAULT;
95 }
96
97 desc->callback = info->fp;
98 desc->callback_param = info->fp_param;
99
100 dmaengine_submit((struct dma_async_tx_descriptor *)desc);
101
102 return 0;
103}
104
105static inline int samsung_dmadev_trigger(unsigned ch)
106{
107 dma_async_issue_pending((struct dma_chan *)ch);
108
109 return 0;
110}
111
112static inline int samsung_dmadev_flush(unsigned ch)
113{
114 return dmaengine_terminate_all((struct dma_chan *)ch);
115}
116
117struct samsung_dma_ops dmadev_ops = {
118 .request = samsung_dmadev_request,
119 .release = samsung_dmadev_release,
120 .prepare = samsung_dmadev_prepare,
121 .trigger = samsung_dmadev_trigger,
122 .started = NULL,
123 .flush = samsung_dmadev_flush,
124 .stop = samsung_dmadev_flush,
125};
126
127void *samsung_dmadev_get_ops(void)
128{
129 return &dmadev_ops;
130}
131EXPORT_SYMBOL(samsung_dmadev_get_ops);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
deleted file mode 100644
index 1c0b0401594b..000000000000
--- a/arch/arm/plat-samsung/gpio-config.c
+++ /dev/null
@@ -1,431 +0,0 @@
1/* linux/arch/arm/plat-s3c/gpio-config.c
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008-2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C series GPIO configuration core
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/io.h>
19
20#include <plat/gpio-core.h>
21#include <plat/gpio-cfg.h>
22#include <plat/gpio-cfg-helpers.h>
23
24int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
25{
26 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
27 unsigned long flags;
28 int offset;
29 int ret;
30
31 if (!chip)
32 return -EINVAL;
33
34 offset = pin - chip->chip.base;
35
36 s3c_gpio_lock(chip, flags);
37 ret = s3c_gpio_do_setcfg(chip, offset, config);
38 s3c_gpio_unlock(chip, flags);
39
40 return ret;
41}
42EXPORT_SYMBOL(s3c_gpio_cfgpin);
43
44int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
45 unsigned int cfg)
46{
47 int ret;
48
49 for (; nr > 0; nr--, start++) {
50 ret = s3c_gpio_cfgpin(start, cfg);
51 if (ret != 0)
52 return ret;
53 }
54
55 return 0;
56}
57EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
58
59int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
60 unsigned int cfg, s3c_gpio_pull_t pull)
61{
62 int ret;
63
64 for (; nr > 0; nr--, start++) {
65 s3c_gpio_setpull(start, pull);
66 ret = s3c_gpio_cfgpin(start, cfg);
67 if (ret != 0)
68 return ret;
69 }
70
71 return 0;
72}
73EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
74
75unsigned s3c_gpio_getcfg(unsigned int pin)
76{
77 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
78 unsigned long flags;
79 unsigned ret = 0;
80 int offset;
81
82 if (chip) {
83 offset = pin - chip->chip.base;
84
85 s3c_gpio_lock(chip, flags);
86 ret = s3c_gpio_do_getcfg(chip, offset);
87 s3c_gpio_unlock(chip, flags);
88 }
89
90 return ret;
91}
92EXPORT_SYMBOL(s3c_gpio_getcfg);
93
94
95int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
96{
97 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
98 unsigned long flags;
99 int offset, ret;
100
101 if (!chip)
102 return -EINVAL;
103
104 offset = pin - chip->chip.base;
105
106 s3c_gpio_lock(chip, flags);
107 ret = s3c_gpio_do_setpull(chip, offset, pull);
108 s3c_gpio_unlock(chip, flags);
109
110 return ret;
111}
112EXPORT_SYMBOL(s3c_gpio_setpull);
113
114s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
115{
116 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
117 unsigned long flags;
118 int offset;
119 u32 pup = 0;
120
121 if (chip) {
122 offset = pin - chip->chip.base;
123
124 s3c_gpio_lock(chip, flags);
125 pup = s3c_gpio_do_getpull(chip, offset);
126 s3c_gpio_unlock(chip, flags);
127 }
128
129 return (__force s3c_gpio_pull_t)pup;
130}
131EXPORT_SYMBOL(s3c_gpio_getpull);
132
133#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
134int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
135 unsigned int off, unsigned int cfg)
136{
137 void __iomem *reg = chip->base;
138 unsigned int shift = off;
139 u32 con;
140
141 if (s3c_gpio_is_cfg_special(cfg)) {
142 cfg &= 0xf;
143
144 /* Map output to 0, and SFN2 to 1 */
145 cfg -= 1;
146 if (cfg > 1)
147 return -EINVAL;
148
149 cfg <<= shift;
150 }
151
152 con = __raw_readl(reg);
153 con &= ~(0x1 << shift);
154 con |= cfg;
155 __raw_writel(con, reg);
156
157 return 0;
158}
159
160unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
161 unsigned int off)
162{
163 u32 con;
164
165 con = __raw_readl(chip->base);
166 con >>= off;
167 con &= 1;
168 con++;
169
170 return S3C_GPIO_SFN(con);
171}
172
173int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
174 unsigned int off, unsigned int cfg)
175{
176 void __iomem *reg = chip->base;
177 unsigned int shift = off * 2;
178 u32 con;
179
180 if (s3c_gpio_is_cfg_special(cfg)) {
181 cfg &= 0xf;
182 if (cfg > 3)
183 return -EINVAL;
184
185 cfg <<= shift;
186 }
187
188 con = __raw_readl(reg);
189 con &= ~(0x3 << shift);
190 con |= cfg;
191 __raw_writel(con, reg);
192
193 return 0;
194}
195
196unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
197 unsigned int off)
198{
199 u32 con;
200
201 con = __raw_readl(chip->base);
202 con >>= off * 2;
203 con &= 3;
204
205 /* this conversion works for IN and OUT as well as special mode */
206 return S3C_GPIO_SPECIAL(con);
207}
208#endif
209
210#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
211int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
212 unsigned int off, unsigned int cfg)
213{
214 void __iomem *reg = chip->base;
215 unsigned int shift = (off & 7) * 4;
216 u32 con;
217
218 if (off < 8 && chip->chip.ngpio > 8)
219 reg -= 4;
220
221 if (s3c_gpio_is_cfg_special(cfg)) {
222 cfg &= 0xf;
223 cfg <<= shift;
224 }
225
226 con = __raw_readl(reg);
227 con &= ~(0xf << shift);
228 con |= cfg;
229 __raw_writel(con, reg);
230
231 return 0;
232}
233
234unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
235 unsigned int off)
236{
237 void __iomem *reg = chip->base;
238 unsigned int shift = (off & 7) * 4;
239 u32 con;
240
241 if (off < 8 && chip->chip.ngpio > 8)
242 reg -= 4;
243
244 con = __raw_readl(reg);
245 con >>= shift;
246 con &= 0xf;
247
248 /* this conversion works for IN and OUT as well as special mode */
249 return S3C_GPIO_SPECIAL(con);
250}
251
252#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
253
254#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
255int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
256 unsigned int off, s3c_gpio_pull_t pull)
257{
258 void __iomem *reg = chip->base + 0x08;
259 int shift = off * 2;
260 u32 pup;
261
262 pup = __raw_readl(reg);
263 pup &= ~(3 << shift);
264 pup |= pull << shift;
265 __raw_writel(pup, reg);
266
267 return 0;
268}
269
270s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
271 unsigned int off)
272{
273 void __iomem *reg = chip->base + 0x08;
274 int shift = off * 2;
275 u32 pup = __raw_readl(reg);
276
277 pup >>= shift;
278 pup &= 0x3;
279 return (__force s3c_gpio_pull_t)pup;
280}
281
282#ifdef CONFIG_S3C_GPIO_PULL_S3C2443
283int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
284 unsigned int off, s3c_gpio_pull_t pull)
285{
286 switch (pull) {
287 case S3C_GPIO_PULL_NONE:
288 pull = 0x01;
289 break;
290 case S3C_GPIO_PULL_UP:
291 pull = 0x00;
292 break;
293 case S3C_GPIO_PULL_DOWN:
294 pull = 0x02;
295 break;
296 }
297 return s3c_gpio_setpull_updown(chip, off, pull);
298}
299
300s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
301 unsigned int off)
302{
303 s3c_gpio_pull_t pull;
304
305 pull = s3c_gpio_getpull_updown(chip, off);
306
307 switch (pull) {
308 case 0x00:
309 pull = S3C_GPIO_PULL_UP;
310 break;
311 case 0x01:
312 case 0x03:
313 pull = S3C_GPIO_PULL_NONE;
314 break;
315 case 0x02:
316 pull = S3C_GPIO_PULL_DOWN;
317 break;
318 }
319
320 return pull;
321}
322#endif
323#endif
324
325#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
326static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
327 unsigned int off, s3c_gpio_pull_t pull,
328 s3c_gpio_pull_t updown)
329{
330 void __iomem *reg = chip->base + 0x08;
331 u32 pup = __raw_readl(reg);
332
333 if (pull == updown)
334 pup &= ~(1 << off);
335 else if (pull == S3C_GPIO_PULL_NONE)
336 pup |= (1 << off);
337 else
338 return -EINVAL;
339
340 __raw_writel(pup, reg);
341 return 0;
342}
343
344static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
345 unsigned int off, s3c_gpio_pull_t updown)
346{
347 void __iomem *reg = chip->base + 0x08;
348 u32 pup = __raw_readl(reg);
349
350 pup &= (1 << off);
351 return pup ? S3C_GPIO_PULL_NONE : updown;
352}
353#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
354
355#ifdef CONFIG_S3C_GPIO_PULL_UP
356s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
357 unsigned int off)
358{
359 return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
360}
361
362int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
363 unsigned int off, s3c_gpio_pull_t pull)
364{
365 return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
366}
367#endif /* CONFIG_S3C_GPIO_PULL_UP */
368
369#ifdef CONFIG_S3C_GPIO_PULL_DOWN
370s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
371 unsigned int off)
372{
373 return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
374}
375
376int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
377 unsigned int off, s3c_gpio_pull_t pull)
378{
379 return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
380}
381#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
382
383#ifdef CONFIG_S5P_GPIO_DRVSTR
384s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
385{
386 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
387 unsigned int off;
388 void __iomem *reg;
389 int shift;
390 u32 drvstr;
391
392 if (!chip)
393 return -EINVAL;
394
395 off = pin - chip->chip.base;
396 shift = off * 2;
397 reg = chip->base + 0x0C;
398
399 drvstr = __raw_readl(reg);
400 drvstr = drvstr >> shift;
401 drvstr &= 0x3;
402
403 return (__force s5p_gpio_drvstr_t)drvstr;
404}
405EXPORT_SYMBOL(s5p_gpio_get_drvstr);
406
407int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
408{
409 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
410 unsigned int off;
411 void __iomem *reg;
412 int shift;
413 u32 tmp;
414
415 if (!chip)
416 return -EINVAL;
417
418 off = pin - chip->chip.base;
419 shift = off * 2;
420 reg = chip->base + 0x0C;
421
422 tmp = __raw_readl(reg);
423 tmp &= ~(0x3 << shift);
424 tmp |= drvstr << shift;
425
426 __raw_writel(tmp, reg);
427
428 return 0;
429}
430EXPORT_SYMBOL(s5p_gpio_set_drvstr);
431#endif /* CONFIG_S5P_GPIO_DRVSTR */
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
deleted file mode 100644
index 7743c4b8b2fb..000000000000
--- a/arch/arm/plat-samsung/gpio.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/* linux/arch/arm/plat-s3c/gpio.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series GPIO core
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/gpio.h>
18#include <linux/spinlock.h>
19
20#include <plat/gpio-core.h>
21
22#ifdef CONFIG_S3C_GPIO_TRACK
23struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
24
25static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
26{
27 unsigned int gpn;
28 int i;
29
30 gpn = chip->chip.base;
31 for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
32 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
33 s3c_gpios[gpn] = chip;
34 }
35}
36#endif /* CONFIG_S3C_GPIO_TRACK */
37
38/* Default routines for controlling GPIO, based on the original S3C24XX
39 * GPIO functions which deal with the case where each gpio bank of the
40 * chip is as following:
41 *
42 * base + 0x00: Control register, 2 bits per gpio
43 * gpio n: 2 bits starting at (2*n)
44 * 00 = input, 01 = output, others mean special-function
45 * base + 0x04: Data register, 1 bit per gpio
46 * bit n: data bit n
47*/
48
49static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
50{
51 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
52 void __iomem *base = ourchip->base;
53 unsigned long flags;
54 unsigned long con;
55
56 s3c_gpio_lock(ourchip, flags);
57
58 con = __raw_readl(base + 0x00);
59 con &= ~(3 << (offset * 2));
60
61 __raw_writel(con, base + 0x00);
62
63 s3c_gpio_unlock(ourchip, flags);
64 return 0;
65}
66
67static int s3c_gpiolib_output(struct gpio_chip *chip,
68 unsigned offset, int value)
69{
70 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
71 void __iomem *base = ourchip->base;
72 unsigned long flags;
73 unsigned long dat;
74 unsigned long con;
75
76 s3c_gpio_lock(ourchip, flags);
77
78 dat = __raw_readl(base + 0x04);
79 dat &= ~(1 << offset);
80 if (value)
81 dat |= 1 << offset;
82 __raw_writel(dat, base + 0x04);
83
84 con = __raw_readl(base + 0x00);
85 con &= ~(3 << (offset * 2));
86 con |= 1 << (offset * 2);
87
88 __raw_writel(con, base + 0x00);
89 __raw_writel(dat, base + 0x04);
90
91 s3c_gpio_unlock(ourchip, flags);
92 return 0;
93}
94
95static void s3c_gpiolib_set(struct gpio_chip *chip,
96 unsigned offset, int value)
97{
98 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
99 void __iomem *base = ourchip->base;
100 unsigned long flags;
101 unsigned long dat;
102
103 s3c_gpio_lock(ourchip, flags);
104
105 dat = __raw_readl(base + 0x04);
106 dat &= ~(1 << offset);
107 if (value)
108 dat |= 1 << offset;
109 __raw_writel(dat, base + 0x04);
110
111 s3c_gpio_unlock(ourchip, flags);
112}
113
114static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
115{
116 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
117 unsigned long val;
118
119 val = __raw_readl(ourchip->base + 0x04);
120 val >>= offset;
121 val &= 1;
122
123 return val;
124}
125
126__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
127{
128 struct gpio_chip *gc = &chip->chip;
129 int ret;
130
131 BUG_ON(!chip->base);
132 BUG_ON(!gc->label);
133 BUG_ON(!gc->ngpio);
134
135 spin_lock_init(&chip->lock);
136
137 if (!gc->direction_input)
138 gc->direction_input = s3c_gpiolib_input;
139 if (!gc->direction_output)
140 gc->direction_output = s3c_gpiolib_output;
141 if (!gc->set)
142 gc->set = s3c_gpiolib_set;
143 if (!gc->get)
144 gc->get = s3c_gpiolib_get;
145
146#ifdef CONFIG_PM
147 if (chip->pm != NULL) {
148 if (!chip->pm->save || !chip->pm->resume)
149 printk(KERN_ERR "gpio: %s has missing PM functions\n",
150 gc->label);
151 } else
152 printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
153#endif
154
155 /* gpiochip_add() prints own failure message on error. */
156 ret = gpiochip_add(gc);
157 if (ret >= 0)
158 s3c_gpiolib_track(chip);
159}
160
161int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
162{
163 struct s3c_gpio_chip *s3c_chip = container_of(chip,
164 struct s3c_gpio_chip, chip);
165
166 return s3c_chip->irq_base + offset;
167}
diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h
index a281568d5856..a927bee55359 100644
--- a/arch/arm/plat-samsung/include/plat/adc-core.h
+++ b/arch/arm/plat-samsung/include/plat/adc-core.h
@@ -20,7 +20,7 @@
20/* re-define device name depending on support. */ 20/* re-define device name depending on support. */
21static inline void s3c_adc_setname(char *name) 21static inline void s3c_adc_setname(char *name)
22{ 22{
23#ifdef CONFIG_SAMSUNG_DEV_ADC 23#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX)
24 s3c_device_adc.name = name; 24 s3c_device_adc.name = name;
25#endif 25#endif
26} 26}
diff --git a/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h b/arch/arm/plat-samsung/include/plat/audio-simtec.h
index de5e88fdcb31..5345364e7420 100644
--- a/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
+++ b/arch/arm/plat-samsung/include/plat/audio-simtec.h
@@ -1,4 +1,4 @@
1/* arch/arm/plat-s3c24xx/include/plat/audio-simtec.h 1/* arch/arm/plat-samsung/include/plat/audio-simtec.h
2 * 2 *
3 * Copyright 2008 Simtec Electronics 3 * Copyright 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
diff --git a/arch/arm/plat-s5p/include/plat/camport.h b/arch/arm/plat-samsung/include/plat/camport.h
index 71688c8ba288..a5708bf84b3a 100644
--- a/arch/arm/plat-s5p/include/plat/camport.h
+++ b/arch/arm/plat-samsung/include/plat/camport.h
@@ -8,8 +8,8 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#ifndef PLAT_S5P_CAMPORT_H_ 11#ifndef __PLAT_SAMSUNG_CAMPORT_H_
12#define PLAT_S5P_CAMPORT_H_ __FILE__ 12#define __PLAT_SAMSUNG_CAMPORT_H_ __FILE__
13 13
14enum s5p_camport_id { 14enum s5p_camport_id {
15 S5P_CAMPORT_A, 15 S5P_CAMPORT_A,
@@ -25,4 +25,4 @@ enum s5p_camport_id {
25int s5pv210_fimc_setup_gpio(enum s5p_camport_id id); 25int s5pv210_fimc_setup_gpio(enum s5p_camport_id id);
26int exynos4_fimc_setup_gpio(enum s5p_camport_id id); 26int exynos4_fimc_setup_gpio(enum s5p_camport_id id);
27 27
28#endif 28#endif /* __PLAT_SAMSUNG_CAMPORT_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/common-smdk.h b/arch/arm/plat-samsung/include/plat/common-smdk.h
index 58d9094c935c..ba028f1ed30b 100644
--- a/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
+++ b/arch/arm/plat-samsung/include/plat/common-smdk.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h 1/* linux/arch/arm/plat-samsung/include/plat/common-smdk.h
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
index d623235ae961..dac4760c0f0a 100644
--- a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
@@ -1,4 +1,4 @@
1/* arch/arm/plat-s3c/include/plat/cpu-freq.h 1/* arch/arm/plat-samsung/include/plat/cpu-freq-core.h
2 * 2 *
3 * Copyright (c) 2006-2009 Simtec Electronics 3 * Copyright (c) 2006-2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
@@ -195,7 +195,8 @@ struct s3c_cpufreq_info {
195 195
196extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info); 196extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
197 197
198extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no); 198extern int s3c_plltab_register(struct cpufreq_frequency_table *plls,
199 unsigned int plls_no);
199 200
200/* exports and utilities for debugfs */ 201/* exports and utilities for debugfs */
201extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); 202extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 54f370f0fc07..40fd7b6b5e66 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -25,7 +25,6 @@ extern unsigned long samsung_cpu_id;
25 25
26#define S3C6400_CPU_ID 0x36400000 26#define S3C6400_CPU_ID 0x36400000
27#define S3C6410_CPU_ID 0x36410000 27#define S3C6410_CPU_ID 0x36410000
28#define S3C64XX_CPU_ID (S3C6400_CPU_ID & S3C6410_CPU_ID)
29#define S3C64XX_CPU_MASK 0xFFFFF000 28#define S3C64XX_CPU_MASK 0xFFFFF000
30 29
31#define S5P6440_CPU_ID 0x56440000 30#define S5P6440_CPU_ID 0x56440000
@@ -50,7 +49,8 @@ static inline int is_samsung_##name(void) \
50} 49}
51 50
52IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) 51IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
53IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK) 52IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
53IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK)
54IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK) 54IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
55IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK) 55IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
56IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK) 56IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
@@ -69,7 +69,7 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
69#endif 69#endif
70 70
71#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) 71#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
72# define soc_is_s3c64xx() is_samsung_s3c64xx() 72# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410())
73#else 73#else
74# define soc_is_s3c64xx() 0 74# define soc_is_s3c64xx() 0
75#endif 75#endif
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 24ebb1e1de41..ab633c9c2aec 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -30,30 +30,24 @@ extern struct s3c24xx_uart_resources s5p_uart_resources[];
30extern struct platform_device *s3c24xx_uart_devs[]; 30extern struct platform_device *s3c24xx_uart_devs[];
31extern struct platform_device *s3c24xx_uart_src[]; 31extern struct platform_device *s3c24xx_uart_src[];
32 32
33extern struct platform_device s3c_device_timer[]; 33extern struct platform_device s3c64xx_device_ac97;
34
35extern struct platform_device s3c64xx_device_iis0; 34extern struct platform_device s3c64xx_device_iis0;
36extern struct platform_device s3c64xx_device_iis1; 35extern struct platform_device s3c64xx_device_iis1;
37extern struct platform_device s3c64xx_device_iisv4; 36extern struct platform_device s3c64xx_device_iisv4;
38 37extern struct platform_device s3c64xx_device_onenand1;
39extern struct platform_device s3c64xx_device_spi0;
40extern struct platform_device s3c64xx_device_spi1;
41
42extern struct platform_device samsung_asoc_dma;
43extern struct platform_device samsung_asoc_idma;
44
45extern struct platform_device s3c64xx_device_pcm0; 38extern struct platform_device s3c64xx_device_pcm0;
46extern struct platform_device s3c64xx_device_pcm1; 39extern struct platform_device s3c64xx_device_pcm1;
40extern struct platform_device s3c64xx_device_spi0;
41extern struct platform_device s3c64xx_device_spi1;
47 42
48extern struct platform_device s3c64xx_device_ac97; 43extern struct platform_device s3c_device_adc;
49 44extern struct platform_device s3c_device_cfcon;
50extern struct platform_device s3c_device_ts;
51
52extern struct platform_device s3c_device_fb; 45extern struct platform_device s3c_device_fb;
53extern struct platform_device s5p_device_fimd0; 46extern struct platform_device s3c_device_hwmon;
54extern struct platform_device s3c_device_ohci; 47extern struct platform_device s3c_device_hsmmc0;
55extern struct platform_device s3c_device_lcd; 48extern struct platform_device s3c_device_hsmmc1;
56extern struct platform_device s3c_device_wdt; 49extern struct platform_device s3c_device_hsmmc2;
50extern struct platform_device s3c_device_hsmmc3;
57extern struct platform_device s3c_device_i2c0; 51extern struct platform_device s3c_device_i2c0;
58extern struct platform_device s3c_device_i2c1; 52extern struct platform_device s3c_device_i2c1;
59extern struct platform_device s3c_device_i2c2; 53extern struct platform_device s3c_device_i2c2;
@@ -62,93 +56,90 @@ extern struct platform_device s3c_device_i2c4;
62extern struct platform_device s3c_device_i2c5; 56extern struct platform_device s3c_device_i2c5;
63extern struct platform_device s3c_device_i2c6; 57extern struct platform_device s3c_device_i2c6;
64extern struct platform_device s3c_device_i2c7; 58extern struct platform_device s3c_device_i2c7;
59extern struct platform_device s3c_device_iis;
60extern struct platform_device s3c_device_lcd;
61extern struct platform_device s3c_device_nand;
62extern struct platform_device s3c_device_ohci;
63extern struct platform_device s3c_device_onenand;
65extern struct platform_device s3c_device_rtc; 64extern struct platform_device s3c_device_rtc;
66extern struct platform_device s3c_device_adc;
67extern struct platform_device s3c_device_sdi; 65extern struct platform_device s3c_device_sdi;
68extern struct platform_device s3c_device_iis;
69extern struct platform_device s3c_device_hwmon;
70extern struct platform_device s3c_device_hsmmc0;
71extern struct platform_device s3c_device_hsmmc1;
72extern struct platform_device s3c_device_hsmmc2;
73extern struct platform_device s3c_device_hsmmc3;
74extern struct platform_device s3c_device_cfcon;
75
76extern struct platform_device s3c_device_spi0; 66extern struct platform_device s3c_device_spi0;
77extern struct platform_device s3c_device_spi1; 67extern struct platform_device s3c_device_spi1;
78 68extern struct platform_device s3c_device_ts;
79extern struct platform_device s5pc100_device_spi0; 69extern struct platform_device s3c_device_timer[];
80extern struct platform_device s5pc100_device_spi1;
81extern struct platform_device s5pc100_device_spi2;
82extern struct platform_device s5pv210_device_spi0;
83extern struct platform_device s5pv210_device_spi1;
84extern struct platform_device s5p64x0_device_spi0;
85extern struct platform_device s5p64x0_device_spi1;
86
87extern struct platform_device s3c_device_hwmon;
88
89extern struct platform_device s3c_device_nand;
90extern struct platform_device s3c_device_onenand;
91extern struct platform_device s3c64xx_device_onenand1;
92extern struct platform_device s5p_device_onenand;
93
94extern struct platform_device s3c_device_usbgadget; 70extern struct platform_device s3c_device_usbgadget;
95extern struct platform_device s3c_device_usb_hsudc;
96extern struct platform_device s3c_device_usb_hsotg; 71extern struct platform_device s3c_device_usb_hsotg;
72extern struct platform_device s3c_device_usb_hsudc;
73extern struct platform_device s3c_device_wdt;
97 74
98extern struct platform_device s5pv210_device_ac97; 75extern struct platform_device s5p_device_ehci;
99extern struct platform_device s5pv210_device_pcm0; 76extern struct platform_device s5p_device_fimc0;
100extern struct platform_device s5pv210_device_pcm1; 77extern struct platform_device s5p_device_fimc1;
101extern struct platform_device s5pv210_device_pcm2; 78extern struct platform_device s5p_device_fimc2;
102extern struct platform_device s5pv210_device_iis0; 79extern struct platform_device s5p_device_fimc3;
103extern struct platform_device s5pv210_device_iis1; 80extern struct platform_device s5p_device_fimc_md;
104extern struct platform_device s5pv210_device_iis2; 81extern struct platform_device s5p_device_fimd0;
105extern struct platform_device s5pv210_device_spdif; 82extern struct platform_device s5p_device_hdmi;
106 83extern struct platform_device s5p_device_i2c_hdmiphy;
107extern struct platform_device exynos4_device_ac97; 84extern struct platform_device s5p_device_mfc;
108extern struct platform_device exynos4_device_pcm0; 85extern struct platform_device s5p_device_mfc_l;
109extern struct platform_device exynos4_device_pcm1; 86extern struct platform_device s5p_device_mfc_r;
110extern struct platform_device exynos4_device_pcm2; 87extern struct platform_device s5p_device_mipi_csis0;
111extern struct platform_device exynos4_device_i2s0; 88extern struct platform_device s5p_device_mipi_csis1;
112extern struct platform_device exynos4_device_i2s1; 89extern struct platform_device s5p_device_mixer;
113extern struct platform_device exynos4_device_i2s2; 90extern struct platform_device s5p_device_onenand;
114extern struct platform_device exynos4_device_spdif; 91extern struct platform_device s5p_device_sdo;
115extern struct platform_device exynos4_device_pd[];
116extern struct platform_device exynos4_device_ahci;
117extern struct platform_device exynos4_device_dwmci;
118 92
119extern struct platform_device s5p6440_device_pcm;
120extern struct platform_device s5p6440_device_iis; 93extern struct platform_device s5p6440_device_iis;
94extern struct platform_device s5p6440_device_pcm;
121 95
122extern struct platform_device s5p6450_device_iis0; 96extern struct platform_device s5p6450_device_iis0;
123extern struct platform_device s5p6450_device_iis1; 97extern struct platform_device s5p6450_device_iis1;
124extern struct platform_device s5p6450_device_iis2; 98extern struct platform_device s5p6450_device_iis2;
125extern struct platform_device s5p6450_device_pcm0; 99extern struct platform_device s5p6450_device_pcm0;
126 100
101extern struct platform_device s5p64x0_device_spi0;
102extern struct platform_device s5p64x0_device_spi1;
103
127extern struct platform_device s5pc100_device_ac97; 104extern struct platform_device s5pc100_device_ac97;
128extern struct platform_device s5pc100_device_pcm0;
129extern struct platform_device s5pc100_device_pcm1;
130extern struct platform_device s5pc100_device_iis0; 105extern struct platform_device s5pc100_device_iis0;
131extern struct platform_device s5pc100_device_iis1; 106extern struct platform_device s5pc100_device_iis1;
132extern struct platform_device s5pc100_device_iis2; 107extern struct platform_device s5pc100_device_iis2;
108extern struct platform_device s5pc100_device_pcm0;
109extern struct platform_device s5pc100_device_pcm1;
133extern struct platform_device s5pc100_device_spdif; 110extern struct platform_device s5pc100_device_spdif;
111extern struct platform_device s5pc100_device_spi0;
112extern struct platform_device s5pc100_device_spi1;
113extern struct platform_device s5pc100_device_spi2;
134 114
135extern struct platform_device samsung_device_keypad; 115extern struct platform_device s5pv210_device_ac97;
136 116extern struct platform_device s5pv210_device_iis0;
137extern struct platform_device s5p_device_fimc0; 117extern struct platform_device s5pv210_device_iis1;
138extern struct platform_device s5p_device_fimc1; 118extern struct platform_device s5pv210_device_iis2;
139extern struct platform_device s5p_device_fimc2; 119extern struct platform_device s5pv210_device_pcm0;
140extern struct platform_device s5p_device_fimc3; 120extern struct platform_device s5pv210_device_pcm1;
141 121extern struct platform_device s5pv210_device_pcm2;
142extern struct platform_device s5p_device_mfc; 122extern struct platform_device s5pv210_device_spdif;
143extern struct platform_device s5p_device_mfc_l; 123extern struct platform_device s5pv210_device_spi0;
144extern struct platform_device s5p_device_mfc_r; 124extern struct platform_device s5pv210_device_spi1;
145extern struct platform_device s5p_device_mipi_csis0;
146extern struct platform_device s5p_device_mipi_csis1;
147
148extern struct platform_device s5p_device_ehci;
149 125
126extern struct platform_device exynos4_device_ac97;
127extern struct platform_device exynos4_device_ahci;
128extern struct platform_device exynos4_device_dwmci;
129extern struct platform_device exynos4_device_i2s0;
130extern struct platform_device exynos4_device_i2s1;
131extern struct platform_device exynos4_device_i2s2;
132extern struct platform_device exynos4_device_pcm0;
133extern struct platform_device exynos4_device_pcm1;
134extern struct platform_device exynos4_device_pcm2;
135extern struct platform_device exynos4_device_pd[];
136extern struct platform_device exynos4_device_spdif;
150extern struct platform_device exynos4_device_sysmmu; 137extern struct platform_device exynos4_device_sysmmu;
151 138
139extern struct platform_device samsung_asoc_dma;
140extern struct platform_device samsung_asoc_idma;
141extern struct platform_device samsung_device_keypad;
142
152/* s3c2440 specific devices */ 143/* s3c2440 specific devices */
153 144
154#ifdef CONFIG_CPU_S3C2440 145#ifdef CONFIG_CPU_S3C2440
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
new file mode 100644
index 000000000000..4c1a363526cf
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -0,0 +1,63 @@
1/* arch/arm/plat-samsung/include/plat/dma-ops.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung DMA support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __SAMSUNG_DMA_OPS_H_
14#define __SAMSUNG_DMA_OPS_H_ __FILE__
15
16#include <linux/dmaengine.h>
17
18struct samsung_dma_prep_info {
19 enum dma_transaction_type cap;
20 enum dma_data_direction direction;
21 dma_addr_t buf;
22 unsigned long period;
23 unsigned long len;
24 void (*fp)(void *data);
25 void *fp_param;
26};
27
28struct samsung_dma_info {
29 enum dma_transaction_type cap;
30 enum dma_data_direction direction;
31 enum dma_slave_buswidth width;
32 dma_addr_t fifo;
33 struct s3c2410_dma_client *client;
34};
35
36struct samsung_dma_ops {
37 unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info);
38 int (*release)(unsigned ch, struct s3c2410_dma_client *client);
39 int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info);
40 int (*trigger)(unsigned ch);
41 int (*started)(unsigned ch);
42 int (*flush)(unsigned ch);
43 int (*stop)(unsigned ch);
44};
45
46extern void *samsung_dmadev_get_ops(void);
47extern void *s3c_dma_get_ops(void);
48
49static inline void *__samsung_dma_get_ops(void)
50{
51 if (samsung_dma_is_dmadev())
52 return samsung_dmadev_get_ops();
53 else
54 return s3c_dma_get_ops();
55}
56
57/*
58 * samsung_dma_get_ops
59 * get the set of samsung dma operations
60 */
61#define samsung_dma_get_ops() __samsung_dma_get_ops()
62
63#endif /* __SAMSUNG_DMA_OPS_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 810744213120..2e55e5958674 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -8,11 +8,8 @@
8 * (at your option) any later version. 8 * (at your option) any later version.
9 */ 9 */
10 10
11#ifndef __S3C_DMA_PL330_H_ 11#ifndef __DMA_PL330_H_
12#define __S3C_DMA_PL330_H_ 12#define __DMA_PL330_H_ __FILE__
13
14#define S3C2410_DMAF_AUTOSTART (1 << 0)
15#define S3C2410_DMAF_CIRCULAR (1 << 1)
16 13
17/* 14/*
18 * PL330 can assign any channel to communicate with 15 * PL330 can assign any channel to communicate with
@@ -20,7 +17,7 @@
20 * For the sake of consistency across client drivers, 17 * For the sake of consistency across client drivers,
21 * We keep the channel names unchanged and only add 18 * We keep the channel names unchanged and only add
22 * missing peripherals are added. 19 * missing peripherals are added.
23 * Order is not important since S3C PL330 API driver 20 * Order is not important since DMA PL330 API driver
24 * use these just as IDs. 21 * use these just as IDs.
25 */ 22 */
26enum dma_ch { 23enum dma_ch {
@@ -88,11 +85,20 @@ enum dma_ch {
88 DMACH_MAX, 85 DMACH_MAX,
89}; 86};
90 87
91static inline bool s3c_dma_has_circular(void) 88struct s3c2410_dma_client {
89 char *name;
90};
91
92static inline bool samsung_dma_has_circular(void)
93{
94 return true;
95}
96
97static inline bool samsung_dma_is_dmadev(void)
92{ 98{
93 return true; 99 return true;
94} 100}
95 101
96#include <plat/dma.h> 102#include <plat/dma-ops.h>
97 103
98#endif /* __S3C_DMA_PL330_H_ */ 104#endif /* __DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
index ab9bce637cbd..1c1ed5481253 100644
--- a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+++ b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
@@ -41,7 +41,7 @@ struct s3c24xx_dma_selection {
41 41
42 void (*direction)(struct s3c2410_dma_chan *chan, 42 void (*direction)(struct s3c2410_dma_chan *chan,
43 struct s3c24xx_dma_map *map, 43 struct s3c24xx_dma_map *map,
44 enum s3c2410_dmasrc dir); 44 enum dma_data_direction dir);
45}; 45};
46 46
47extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); 47extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7a6f56..b9061128abde 100644
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -10,17 +10,14 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#include <linux/dma-mapping.h>
14
13enum s3c2410_dma_buffresult { 15enum s3c2410_dma_buffresult {
14 S3C2410_RES_OK, 16 S3C2410_RES_OK,
15 S3C2410_RES_ERR, 17 S3C2410_RES_ERR,
16 S3C2410_RES_ABORT 18 S3C2410_RES_ABORT
17}; 19};
18 20
19enum s3c2410_dmasrc {
20 S3C2410_DMASRC_HW, /* source is memory */
21 S3C2410_DMASRC_MEM /* source is hardware */
22};
23
24/* enum s3c2410_chan_op 21/* enum s3c2410_chan_op
25 * 22 *
26 * operation codes passed to the DMA code by the user, and also used 23 * operation codes passed to the DMA code by the user, and also used
@@ -112,7 +109,7 @@ extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
112*/ 109*/
113 110
114extern int s3c2410_dma_devconfig(enum dma_ch channel, 111extern int s3c2410_dma_devconfig(enum dma_ch channel,
115 enum s3c2410_dmasrc source, unsigned long devaddr); 112 enum dma_data_direction source, unsigned long devaddr);
116 113
117/* s3c2410_dma_getposition 114/* s3c2410_dma_getposition
118 * 115 *
@@ -126,3 +123,4 @@ extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
126extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn); 123extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn);
127 124
128 125
126#include <plat/dma-ops.h>
diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-samsung/include/plat/ehci.h
index 6ae6810c7569..5f28cae18582 100644
--- a/arch/arm/plat-s5p/include/plat/ehci.h
+++ b/arch/arm/plat-samsung/include/plat/ehci.h
@@ -8,8 +8,8 @@
8 * option) any later version. 8 * option) any later version.
9 */ 9 */
10 10
11#ifndef __PLAT_S5P_EHCI_H 11#ifndef __PLAT_SAMSUNG_EHCI_H
12#define __PLAT_S5P_EHCI_H 12#define __PLAT_SAMSUNG_EHCI_H __FILE__
13 13
14struct s5p_ehci_platdata { 14struct s5p_ehci_platdata {
15 int (*phy_init)(struct platform_device *pdev, int type); 15 int (*phy_init)(struct platform_device *pdev, int type);
@@ -18,4 +18,4 @@ struct s5p_ehci_platdata {
18 18
19extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd); 19extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
20 20
21#endif /* __PLAT_S5P_EHCI_H */ 21#endif /* __PLAT_SAMSUNG_EHCI_H */
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-samsung/include/plat/exynos4.h
index f680a143e38c..f546e88ebc94 100644
--- a/arch/arm/plat-s5p/include/plat/exynos4.h
+++ b/arch/arm/plat-samsung/include/plat/exynos4.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/exynos4.h 1/* linux/arch/arm/plat-samsung/include/plat/exynos4.h
2 * 2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -18,8 +18,8 @@ extern void exynos4210_register_clocks(void);
18extern void exynos4212_register_clocks(void); 18extern void exynos4212_register_clocks(void);
19extern void exynos4_setup_clocks(void); 19extern void exynos4_setup_clocks(void);
20 20
21#ifdef CONFIG_ARCH_EXYNOS4 21#ifdef CONFIG_ARCH_EXYNOS
22extern int exynos4_init(void); 22extern int exynos_init(void);
23extern void exynos4_init_irq(void); 23extern void exynos4_init_irq(void);
24extern void exynos4_map_io(void); 24extern void exynos4_map_io(void);
25extern void exynos4_init_clocks(int xtal); 25extern void exynos4_init_clocks(int xtal);
@@ -31,5 +31,5 @@ extern struct sys_timer exynos4_timer;
31#define exynos4_init_clocks NULL 31#define exynos4_init_clocks NULL
32#define exynos4_init_uarts NULL 32#define exynos4_init_uarts NULL
33#define exynos4_map_io NULL 33#define exynos4_map_io NULL
34#define exynos4_init NULL 34#define exynos_init NULL
35#endif 35#endif
diff --git a/arch/arm/plat-samsung/include/plat/fb-s3c2410.h b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h
new file mode 100644
index 000000000000..4e5d9588b5ba
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h
@@ -0,0 +1,72 @@
1/* arch/arm/plat-samsung/include/plat/fb-s3c2410.h
2 *
3 * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
4 *
5 * Inspired by pxafb.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifndef __ASM_PLAT_FB_S3C2410_H
13#define __ASM_PLAT_FB_S3C2410_H __FILE__
14
15struct s3c2410fb_hw {
16 unsigned long lcdcon1;
17 unsigned long lcdcon2;
18 unsigned long lcdcon3;
19 unsigned long lcdcon4;
20 unsigned long lcdcon5;
21};
22
23/* LCD description */
24struct s3c2410fb_display {
25 /* LCD type */
26 unsigned type;
27
28 /* Screen size */
29 unsigned short width;
30 unsigned short height;
31
32 /* Screen info */
33 unsigned short xres;
34 unsigned short yres;
35 unsigned short bpp;
36
37 unsigned pixclock; /* pixclock in picoseconds */
38 unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
39 unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
40 unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
41 unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
42 unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
43 unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
44
45 /* lcd configuration registers */
46 unsigned long lcdcon5;
47};
48
49struct s3c2410fb_mach_info {
50
51 struct s3c2410fb_display *displays; /* attached diplays info */
52 unsigned num_displays; /* number of defined displays */
53 unsigned default_display;
54
55 /* GPIOs */
56
57 unsigned long gpcup;
58 unsigned long gpcup_mask;
59 unsigned long gpccon;
60 unsigned long gpccon_mask;
61 unsigned long gpdup;
62 unsigned long gpdup_mask;
63 unsigned long gpdcon;
64 unsigned long gpdcon_mask;
65
66 /* lpc3600 control register */
67 unsigned long lpcsel;
68};
69
70extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
71
72#endif /* __ASM_PLAT_FB_S3C2410_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index 01f10e4d00c7..0fedf47fa502 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -109,4 +109,11 @@ extern void s5pv210_fb_gpio_setup_24bpp(void);
109 */ 109 */
110extern void exynos4_fimd0_gpio_setup_24bpp(void); 110extern void exynos4_fimd0_gpio_setup_24bpp(void);
111 111
112/**
113 * s5p64x0_fb_gpio_setup_24bpp() - S5P6440/S5P6450 setup function for 24bpp LCD
114 *
115 * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
116 */
117extern void s5p64x0_fb_gpio_setup_24bpp(void);
118
112#endif /* __PLAT_S3C_FB_H */ 119#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-samsung/include/plat/fiq.h
index 8521b8372c5f..535d06a35628 100644
--- a/arch/arm/plat-s3c24xx/include/plat/fiq.h
+++ b/arch/arm/plat-samsung/include/plat/fiq.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/fiq.h 1/* linux/arch/arm/plat-samsung/include/plat/fiq.h
2 * 2 *
3 * Copyright (c) 2009 Simtec Electronics 3 * Copyright (c) 2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 9a4e53d52967..a181d7ce81cf 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -1,11 +1,11 @@
1/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h 1/* linux/arch/arm/plat-samsung/include/plat/gpio-cfg-helper.h
2 * 2 *
3 * Copyright 2008 Openmoko, Inc. 3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/ 5 * http://armlinux.simtec.co.uk/
6 * Ben Dooks <ben@simtec.co.uk> 6 * Ben Dooks <ben@simtec.co.uk>
7 * 7 *
8 * S3C Platform - GPIO pin configuration helper definitions 8 * Samsung Platform - GPIO pin configuration helper definitions
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -24,120 +24,30 @@
24 * by disabling interrupts. 24 * by disabling interrupts.
25*/ 25*/
26 26
27static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, 27static inline int samsung_gpio_do_setcfg(struct samsung_gpio_chip *chip,
28 unsigned int off, unsigned int config) 28 unsigned int off, unsigned int config)
29{ 29{
30 return (chip->config->set_config)(chip, off, config); 30 return (chip->config->set_config)(chip, off, config);
31} 31}
32 32
33static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip, 33static inline unsigned samsung_gpio_do_getcfg(struct samsung_gpio_chip *chip,
34 unsigned int off) 34 unsigned int off)
35{ 35{
36 return (chip->config->get_config)(chip, off); 36 return (chip->config->get_config)(chip, off);
37} 37}
38 38
39static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, 39static inline int samsung_gpio_do_setpull(struct samsung_gpio_chip *chip,
40 unsigned int off, s3c_gpio_pull_t pull) 40 unsigned int off, samsung_gpio_pull_t pull)
41{ 41{
42 return (chip->config->set_pull)(chip, off, pull); 42 return (chip->config->set_pull)(chip, off, pull);
43} 43}
44 44
45static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip, 45static inline samsung_gpio_pull_t samsung_gpio_do_getpull(struct samsung_gpio_chip *chip,
46 unsigned int off) 46 unsigned int off)
47{ 47{
48 return chip->config->get_pull(chip, off); 48 return chip->config->get_pull(chip, off);
49} 49}
50 50
51/**
52 * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
53 * @chip: The gpio chip that is being configured.
54 * @off: The offset for the GPIO being configured.
55 * @cfg: The configuration value to set.
56 *
57 * This helper deal with the GPIO cases where the control register
58 * has two bits of configuration per gpio, which have the following
59 * functions:
60 * 00 = input
61 * 01 = output
62 * 1x = special function
63*/
64extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
65 unsigned int off, unsigned int cfg);
66
67/**
68 * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
69 * @chip: The gpio chip that is being configured.
70 * @off: The offset for the GPIO being configured.
71 *
72 * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
73 * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
74 * S3C_GPIO_SPECIAL() macro.
75 */
76unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
77 unsigned int off);
78
79/**
80 * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
81 * @chip: The gpio chip that is being configured.
82 * @off: The offset for the GPIO being configured.
83 * @cfg: The configuration value to set.
84 *
85 * This helper deal with the GPIO cases where the control register
86 * has one bit of configuration for the gpio, where setting the bit
87 * means the pin is in special function mode and unset means output.
88*/
89extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
90 unsigned int off, unsigned int cfg);
91
92
93/**
94 * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
95 * @chip: The gpio chip that is being configured.
96 * @off: The offset for the GPIO being configured.
97 *
98 * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
99 * GPIO configuration value.
100 *
101 * @sa s3c_gpio_getcfg_s3c24xx
102 * @sa s3c_gpio_getcfg_s3c64xx_4bit
103 */
104extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
105 unsigned int off);
106
107/**
108 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
109 * @chip: The gpio chip that is being configured.
110 * @off: The offset for the GPIO being configured.
111 * @cfg: The configuration value to set.
112 *
113 * This helper deal with the GPIO cases where the control register has 4 bits
114 * of control per GPIO, generally in the form of:
115 * 0000 = Input
116 * 0001 = Output
117 * others = Special functions (dependent on bank)
118 *
119 * Note, since the code to deal with the case where there are two control
120 * registers instead of one, we do not have a separate set of functions for
121 * each case.
122*/
123extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
124 unsigned int off, unsigned int cfg);
125
126
127/**
128 * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
129 * @chip: The gpio chip that is being configured.
130 * @off: The offset for the GPIO being configured.
131 *
132 * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
133 * register setting into a value the software can use, such as could be passed
134 * to s3c_gpio_setcfg_s3c64xx_4bit().
135 *
136 * @sa s3c_gpio_getcfg_s3c24xx
137 */
138extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
139 unsigned int off);
140
141/* Pull-{up,down} resistor controls. 51/* Pull-{up,down} resistor controls.
142 * 52 *
143 * S3C2410,S3C2440 = Pull-UP, 53 * S3C2410,S3C2440 = Pull-UP,
@@ -147,7 +57,7 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
147 */ 57 */
148 58
149/** 59/**
150 * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none. 60 * s3c24xx_gpio_setpull_1up() - Pull configuration for choice of up or none.
151 * @chip: The gpio chip that is being configured. 61 * @chip: The gpio chip that is being configured.
152 * @off: The offset for the GPIO being configured. 62 * @off: The offset for the GPIO being configured.
153 * @param: pull: The pull mode being requested. 63 * @param: pull: The pull mode being requested.
@@ -155,11 +65,11 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
155 * This is a helper function for the case where we have GPIOs with one 65 * This is a helper function for the case where we have GPIOs with one
156 * bit configuring the presence of a pull-up resistor. 66 * bit configuring the presence of a pull-up resistor.
157 */ 67 */
158extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, 68extern int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
159 unsigned int off, s3c_gpio_pull_t pull); 69 unsigned int off, samsung_gpio_pull_t pull);
160 70
161/** 71/**
162 * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none 72 * s3c24xx_gpio_setpull_1down() - Pull configuration for choice of down or none
163 * @chip: The gpio chip that is being configured 73 * @chip: The gpio chip that is being configured
164 * @off: The offset for the GPIO being configured 74 * @off: The offset for the GPIO being configured
165 * @param: pull: The pull mode being requested 75 * @param: pull: The pull mode being requested
@@ -167,11 +77,13 @@ extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
167 * This is a helper function for the case where we have GPIOs with one 77 * This is a helper function for the case where we have GPIOs with one
168 * bit configuring the presence of a pull-down resistor. 78 * bit configuring the presence of a pull-down resistor.
169 */ 79 */
170extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, 80extern int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
171 unsigned int off, s3c_gpio_pull_t pull); 81 unsigned int off, samsung_gpio_pull_t pull);
172 82
173/** 83/**
174 * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none 84 * samsung_gpio_setpull_upown() - Pull configuration for choice of up,
85 * down or none
86 *
175 * @chip: The gpio chip that is being configured. 87 * @chip: The gpio chip that is being configured.
176 * @off: The offset for the GPIO being configured. 88 * @off: The offset for the GPIO being configured.
177 * @param: pull: The pull mode being requested. 89 * @param: pull: The pull mode being requested.
@@ -183,45 +95,46 @@ extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
183 * 01 = Pull-up resistor connected 95 * 01 = Pull-up resistor connected
184 * 10 = Pull-down resistor connected 96 * 10 = Pull-down resistor connected
185 */ 97 */
186extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, 98extern int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
187 unsigned int off, s3c_gpio_pull_t pull); 99 unsigned int off, samsung_gpio_pull_t pull);
188
189 100
190/** 101/**
191 * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none 102 * samsung_gpio_getpull_updown() - Get configuration for choice of up,
103 * down or none
104 *
192 * @chip: The gpio chip that the GPIO pin belongs to 105 * @chip: The gpio chip that the GPIO pin belongs to
193 * @off: The offset to the pin to get the configuration of. 106 * @off: The offset to the pin to get the configuration of.
194 * 107 *
195 * This helper function reads the state of the pull-{up,down} resistor for the 108 * This helper function reads the state of the pull-{up,down} resistor
196 * given GPIO in the same case as s3c_gpio_setpull_upown. 109 * for the given GPIO in the same case as samsung_gpio_setpull_upown.
197*/ 110*/
198extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, 111extern samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
199 unsigned int off); 112 unsigned int off);
200 113
201/** 114/**
202 * s3c_gpio_getpull_1up() - Get configuration for choice of up or none 115 * s3c24xx_gpio_getpull_1up() - Get configuration for choice of up or none
203 * @chip: The gpio chip that the GPIO pin belongs to 116 * @chip: The gpio chip that the GPIO pin belongs to
204 * @off: The offset to the pin to get the configuration of. 117 * @off: The offset to the pin to get the configuration of.
205 * 118 *
206 * This helper function reads the state of the pull-up resistor for the 119 * This helper function reads the state of the pull-up resistor for the
207 * given GPIO in the same case as s3c_gpio_setpull_1up. 120 * given GPIO in the same case as s3c24xx_gpio_setpull_1up.
208*/ 121*/
209extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, 122extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
210 unsigned int off); 123 unsigned int off);
211 124
212/** 125/**
213 * s3c_gpio_getpull_1down() - Get configuration for choice of down or none 126 * s3c24xx_gpio_getpull_1down() - Get configuration for choice of down or none
214 * @chip: The gpio chip that the GPIO pin belongs to 127 * @chip: The gpio chip that the GPIO pin belongs to
215 * @off: The offset to the pin to get the configuration of. 128 * @off: The offset to the pin to get the configuration of.
216 * 129 *
217 * This helper function reads the state of the pull-down resistor for the 130 * This helper function reads the state of the pull-down resistor for the
218 * given GPIO in the same case as s3c_gpio_setpull_1down. 131 * given GPIO in the same case as s3c24xx_gpio_setpull_1down.
219*/ 132*/
220extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, 133extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
221 unsigned int off); 134 unsigned int off);
222 135
223/** 136/**
224 * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. 137 * s3c2443_gpio_setpull() - Pull configuration for s3c2443.
225 * @chip: The gpio chip that is being configured. 138 * @chip: The gpio chip that is being configured.
226 * @off: The offset for the GPIO being configured. 139 * @off: The offset for the GPIO being configured.
227 * @param: pull: The pull mode being requested. 140 * @param: pull: The pull mode being requested.
@@ -233,19 +146,18 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
233 * 10 = Pull-down resistor connected 146 * 10 = Pull-down resistor connected
234 * x1 = No pull up resistor 147 * x1 = No pull up resistor
235 */ 148 */
236extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, 149extern int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
237 unsigned int off, s3c_gpio_pull_t pull); 150 unsigned int off, samsung_gpio_pull_t pull);
238 151
239/** 152/**
240 * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors 153 * s3c2443_gpio_getpull() - Get configuration for s3c2443 pull resistors
241 * @chip: The gpio chip that the GPIO pin belongs to. 154 * @chip: The gpio chip that the GPIO pin belongs to.
242 * @off: The offset to the pin to get the configuration of. 155 * @off: The offset to the pin to get the configuration of.
243 * 156 *
244 * This helper function reads the state of the pull-{up,down} resistor for the 157 * This helper function reads the state of the pull-{up,down} resistor for the
245 * given GPIO in the same case as s3c_gpio_setpull_upown. 158 * given GPIO in the same case as samsung_gpio_setpull_upown.
246*/ 159*/
247extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip, 160extern samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
248 unsigned int off); 161 unsigned int off);
249 162
250#endif /* __PLAT_GPIO_CFG_HELPERS_H */ 163#endif /* __PLAT_GPIO_CFG_HELPERS_H */
251
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb4cb9e..d48245bb02b3 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -24,14 +24,14 @@
24#ifndef __PLAT_GPIO_CFG_H 24#ifndef __PLAT_GPIO_CFG_H
25#define __PLAT_GPIO_CFG_H __FILE__ 25#define __PLAT_GPIO_CFG_H __FILE__
26 26
27typedef unsigned int __bitwise__ s3c_gpio_pull_t; 27typedef unsigned int __bitwise__ samsung_gpio_pull_t;
28typedef unsigned int __bitwise__ s5p_gpio_drvstr_t; 28typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
29 29
30/* forward declaration if gpio-core.h hasn't been included */ 30/* forward declaration if gpio-core.h hasn't been included */
31struct s3c_gpio_chip; 31struct samsung_gpio_chip;
32 32
33/** 33/**
34 * struct s3c_gpio_cfg GPIO configuration 34 * struct samsung_gpio_cfg GPIO configuration
35 * @cfg_eint: Configuration setting when used for external interrupt source 35 * @cfg_eint: Configuration setting when used for external interrupt source
36 * @get_pull: Read the current pull configuration for the GPIO 36 * @get_pull: Read the current pull configuration for the GPIO
37 * @set_pull: Set the current pull configuraiton for the GPIO 37 * @set_pull: Set the current pull configuraiton for the GPIO
@@ -44,20 +44,20 @@ struct s3c_gpio_chip;
44 * per-bank configuration information that other systems such as the 44 * per-bank configuration information that other systems such as the
45 * external interrupt code will need. 45 * external interrupt code will need.
46 * 46 *
47 * @sa s3c_gpio_cfgpin 47 * @sa samsung_gpio_cfgpin
48 * @sa s3c_gpio_getcfg 48 * @sa s3c_gpio_getcfg
49 * @sa s3c_gpio_setpull 49 * @sa s3c_gpio_setpull
50 * @sa s3c_gpio_getpull 50 * @sa s3c_gpio_getpull
51 */ 51 */
52struct s3c_gpio_cfg { 52struct samsung_gpio_cfg {
53 unsigned int cfg_eint; 53 unsigned int cfg_eint;
54 54
55 s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); 55 samsung_gpio_pull_t (*get_pull)(struct samsung_gpio_chip *chip, unsigned offs);
56 int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, 56 int (*set_pull)(struct samsung_gpio_chip *chip, unsigned offs,
57 s3c_gpio_pull_t pull); 57 samsung_gpio_pull_t pull);
58 58
59 unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); 59 unsigned (*get_config)(struct samsung_gpio_chip *chip, unsigned offs);
60 int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, 60 int (*set_config)(struct samsung_gpio_chip *chip, unsigned offs,
61 unsigned config); 61 unsigned config);
62}; 62};
63 63
@@ -69,7 +69,7 @@ struct s3c_gpio_cfg {
69#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) 69#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
70#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) 70#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
71 71
72#define s3c_gpio_is_cfg_special(_cfg) \ 72#define samsung_gpio_is_cfg_special(_cfg) \
73 (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) 73 (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
74 74
75/** 75/**
@@ -128,9 +128,9 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
128 * up or down settings, and it may be dependent on the chip that is being 128 * up or down settings, and it may be dependent on the chip that is being
129 * used to whether the particular mode is available. 129 * used to whether the particular mode is available.
130 */ 130 */
131#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) 131#define S3C_GPIO_PULL_NONE ((__force samsung_gpio_pull_t)0x00)
132#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) 132#define S3C_GPIO_PULL_DOWN ((__force samsung_gpio_pull_t)0x01)
133#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) 133#define S3C_GPIO_PULL_UP ((__force samsung_gpio_pull_t)0x02)
134 134
135/** 135/**
136 * s3c_gpio_setpull() - set the state of a gpio pin pull resistor 136 * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
@@ -143,7 +143,7 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
143 * 143 *
144 * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP. 144 * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP.
145*/ 145*/
146extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); 146extern int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull);
147 147
148/** 148/**
149 * s3c_gpio_getpull() - get the pull resistor state of a gpio pin 149 * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
@@ -151,7 +151,7 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
151 * 151 *
152 * Read the pull resistor value for the specified pin. 152 * Read the pull resistor value for the specified pin.
153*/ 153*/
154extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); 154extern samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
155 155
156/* configure `all` aspects of an gpio */ 156/* configure `all` aspects of an gpio */
157 157
@@ -170,7 +170,7 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
170 * @sa s3c_gpio_cfgpin_range 170 * @sa s3c_gpio_cfgpin_range
171 */ 171 */
172extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, 172extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
173 unsigned int cfg, s3c_gpio_pull_t pull); 173 unsigned int cfg, samsung_gpio_pull_t pull);
174 174
175static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size, 175static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
176 unsigned int cfg) 176 unsigned int cfg)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf19c3c..1fe6917f6a2a 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -25,22 +25,22 @@
25 * specific code. 25 * specific code.
26*/ 26*/
27 27
28struct s3c_gpio_chip; 28struct samsung_gpio_chip;
29 29
30/** 30/**
31 * struct s3c_gpio_pm - power management (suspend/resume) information 31 * struct samsung_gpio_pm - power management (suspend/resume) information
32 * @save: Routine to save the state of the GPIO block 32 * @save: Routine to save the state of the GPIO block
33 * @resume: Routine to resume the GPIO block. 33 * @resume: Routine to resume the GPIO block.
34 */ 34 */
35struct s3c_gpio_pm { 35struct samsung_gpio_pm {
36 void (*save)(struct s3c_gpio_chip *chip); 36 void (*save)(struct samsung_gpio_chip *chip);
37 void (*resume)(struct s3c_gpio_chip *chip); 37 void (*resume)(struct samsung_gpio_chip *chip);
38}; 38};
39 39
40struct s3c_gpio_cfg; 40struct samsung_gpio_cfg;
41 41
42/** 42/**
43 * struct s3c_gpio_chip - wrapper for specific implementation of gpio 43 * struct samsung_gpio_chip - wrapper for specific implementation of gpio
44 * @chip: The chip structure to be exported via gpiolib. 44 * @chip: The chip structure to be exported via gpiolib.
45 * @base: The base pointer to the gpio configuration registers. 45 * @base: The base pointer to the gpio configuration registers.
46 * @group: The group register number for gpio interrupt support. 46 * @group: The group register number for gpio interrupt support.
@@ -60,10 +60,10 @@ struct s3c_gpio_cfg;
60 * CPU cores trying to get one lock for different GPIO banks, where each 60 * CPU cores trying to get one lock for different GPIO banks, where each
61 * bank of GPIO has its own register space and configuration registers. 61 * bank of GPIO has its own register space and configuration registers.
62 */ 62 */
63struct s3c_gpio_chip { 63struct samsung_gpio_chip {
64 struct gpio_chip chip; 64 struct gpio_chip chip;
65 struct s3c_gpio_cfg *config; 65 struct samsung_gpio_cfg *config;
66 struct s3c_gpio_pm *pm; 66 struct samsung_gpio_pm *pm;
67 void __iomem *base; 67 void __iomem *base;
68 int irq_base; 68 int irq_base;
69 int group; 69 int group;
@@ -73,58 +73,11 @@ struct s3c_gpio_chip {
73#endif 73#endif
74}; 74};
75 75
76static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) 76static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
77{ 77{
78 return container_of(gpc, struct s3c_gpio_chip, chip); 78 return container_of(gpc, struct samsung_gpio_chip, chip);
79} 79}
80 80
81/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
82 * @chip: The chip to register
83 *
84 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
85 * information and makes the necessary alterations for the platform and
86 * notes the information for use with the configuration systems and any
87 * other parts of the system.
88 */
89extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
90
91/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
92 * for use with the configuration calls, and other parts of the s3c gpiolib
93 * support code.
94 *
95 * Not all s3c support code will need this, as some configurations of cpu
96 * may only support one or two different configuration options and have an
97 * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
98 * the machine support file should provide its own s3c_gpiolib_getchip()
99 * and any other necessary functions.
100 */
101
102/**
103 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
104 * @chip: The gpio chip that is being configured.
105 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
106 *
107 * This helper deal with the GPIO cases where the control register has 4 bits
108 * of control per GPIO, generally in the form of:
109 * 0000 = Input
110 * 0001 = Output
111 * others = Special functions (dependent on bank)
112 *
113 * Note, since the code to deal with the case where there are two control
114 * registers instead of one, we do not have a separate set of function
115 * (samsung_gpiolib_add_4bit2_chips)for each case.
116 */
117extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
118 int nr_chips);
119extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
120 int nr_chips);
121extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
122 int nr_chips);
123
124extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
125extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
126
127
128/** 81/**
129 * samsung_gpiolib_to_irq - convert gpio pin to irq number 82 * samsung_gpiolib_to_irq - convert gpio pin to irq number
130 * @chip: The gpio chip that the pin belongs to. 83 * @chip: The gpio chip that the pin belongs to.
@@ -136,36 +89,36 @@ extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
136extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset); 89extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
137 90
138/* exported for core SoC support to change */ 91/* exported for core SoC support to change */
139extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; 92extern struct samsung_gpio_cfg s3c24xx_gpiocfg_default;
140 93
141#ifdef CONFIG_S3C_GPIO_TRACK 94#ifdef CONFIG_S3C_GPIO_TRACK
142extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; 95extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
143 96
144static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) 97static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip)
145{ 98{
146 return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; 99 return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
147} 100}
148#else 101#else
149/* machine specific code should provide s3c_gpiolib_getchip */ 102/* machine specific code should provide samsung_gpiolib_getchip */
150 103
151#include <mach/gpio-track.h> 104#include <mach/gpio-track.h>
152 105
153static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } 106static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { }
154#endif 107#endif
155 108
156#ifdef CONFIG_PM 109#ifdef CONFIG_PM
157extern struct s3c_gpio_pm s3c_gpio_pm_1bit; 110extern struct samsung_gpio_pm samsung_gpio_pm_1bit;
158extern struct s3c_gpio_pm s3c_gpio_pm_2bit; 111extern struct samsung_gpio_pm samsung_gpio_pm_2bit;
159extern struct s3c_gpio_pm s3c_gpio_pm_4bit; 112extern struct samsung_gpio_pm samsung_gpio_pm_4bit;
160#define __gpio_pm(x) x 113#define __gpio_pm(x) x
161#else 114#else
162#define s3c_gpio_pm_1bit NULL 115#define samsung_gpio_pm_1bit NULL
163#define s3c_gpio_pm_2bit NULL 116#define samsung_gpio_pm_2bit NULL
164#define s3c_gpio_pm_4bit NULL 117#define samsung_gpio_pm_4bit NULL
165#define __gpio_pm(x) NULL 118#define __gpio_pm(x) NULL
166 119
167#endif /* CONFIG_PM */ 120#endif /* CONFIG_PM */
168 121
169/* locking wrappers to deal with multiple access to the same gpio bank */ 122/* locking wrappers to deal with multiple access to the same gpio bank */
170#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) 123#define samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
171#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) 124#define samsung_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-fns.h b/arch/arm/plat-samsung/include/plat/gpio-fns.h
new file mode 100644
index 000000000000..bab139201761
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-fns.h
@@ -0,0 +1,98 @@
1/* arch/arm/mach-s3c2410/include/mach/gpio-fns.h
2 *
3 * Copyright (c) 2003-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 - hardware
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __MACH_GPIO_FNS_H
14#define __MACH_GPIO_FNS_H __FILE__
15
16/* These functions are in the to-be-removed category and it is strongly
17 * encouraged not to use these in new code. They will be marked deprecated
18 * very soon.
19 *
20 * Most of the functionality can be either replaced by the gpiocfg calls
21 * for the s3c platform or by the generic GPIOlib API.
22 *
23 * As of 2.6.35-rc, these will be removed, with the few drivers using them
24 * either replaced or given a wrapper until the calls can be removed.
25*/
26
27#include <plat/gpio-cfg.h>
28
29static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
30{
31 /* 1:1 mapping between cfgpin and setcfg calls at the moment */
32 s3c_gpio_cfgpin(pin, cfg);
33}
34
35/* external functions for GPIO support
36 *
37 * These allow various different clients to access the same GPIO
38 * registers without conflicting. If your driver only owns the entire
39 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
40*/
41
42extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
43
44/* s3c2410_gpio_getirq
45 *
46 * turn the given pin number into the corresponding IRQ number
47 *
48 * returns:
49 * < 0 = no interrupt for this pin
50 * >=0 = interrupt number for the pin
51*/
52
53extern int s3c2410_gpio_getirq(unsigned int pin);
54
55/* s3c2410_gpio_irqfilter
56 *
57 * set the irq filtering on the given pin
58 *
59 * on = 0 => disable filtering
60 * 1 => enable filtering
61 *
62 * config = S3C2410_EINTFLT_PCLK or S3C2410_EINTFLT_EXTCLK orred with
63 * width of filter (0 through 63)
64 *
65 *
66*/
67
68extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
69 unsigned int config);
70
71/* s3c2410_gpio_pullup
72 *
73 * This call should be replaced with s3c_gpio_setpull().
74 *
75 * As a note, there is currently no distinction between pull-up and pull-down
76 * in the s3c24xx series devices with only an on/off configuration.
77 */
78
79/* s3c2410_gpio_pullup
80 *
81 * configure the pull-up control on the given pin
82 *
83 * to = 1 => disable the pull-up
84 * 0 => enable the pull-up
85 *
86 * eg;
87 *
88 * s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
89 * s3c2410_gpio_pullup(S3C2410_GPE(8), 0);
90*/
91
92extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
93
94extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
95
96extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
97
98#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 56b0059439e1..51d52e767a19 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -60,6 +60,7 @@ extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
60extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c); 60extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
61extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c); 61extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
62extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c); 62extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
63extern void s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *i2c);
63 64
64/* defined by architecture to configure gpio */ 65/* defined by architecture to configure gpio */
65extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); 66extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-samsung/include/plat/irq.h
index ec087d6054b1..e21a89bc26c9 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-samsung/include/plat/irq.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/irq.h 1/* linux/arch/arm/plat-samsung/include/plat/irq.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -25,9 +25,9 @@
25extern struct irq_chip s3c_irq_level_chip; 25extern struct irq_chip s3c_irq_level_chip;
26extern struct irq_chip s3c_irq_chip; 26extern struct irq_chip s3c_irq_chip;
27 27
28static inline void 28static inline void s3c_irqsub_mask(unsigned int irqno,
29s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, 29 unsigned int parentbit,
30 int subcheck) 30 int subcheck)
31{ 31{
32 unsigned long mask; 32 unsigned long mask;
33 unsigned long submask; 33 unsigned long submask;
@@ -39,17 +39,16 @@ s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
39 39
40 /* check to see if we need to mask the parent IRQ */ 40 /* check to see if we need to mask the parent IRQ */
41 41
42 if ((submask & subcheck) == subcheck) { 42 if ((submask & subcheck) == subcheck)
43 __raw_writel(mask | parentbit, S3C2410_INTMSK); 43 __raw_writel(mask | parentbit, S3C2410_INTMSK);
44 }
45 44
46 /* write back masks */ 45 /* write back masks */
47 __raw_writel(submask, S3C2410_INTSUBMSK); 46 __raw_writel(submask, S3C2410_INTSUBMSK);
48 47
49} 48}
50 49
51static inline void 50static inline void s3c_irqsub_unmask(unsigned int irqno,
52s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit) 51 unsigned int parentbit)
53{ 52{
54 unsigned long mask; 53 unsigned long mask;
55 unsigned long submask; 54 unsigned long submask;
@@ -66,8 +65,9 @@ s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
66} 65}
67 66
68 67
69static inline void 68static inline void s3c_irqsub_maskack(unsigned int irqno,
70s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group) 69 unsigned int parentmask,
70 unsigned int group)
71{ 71{
72 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); 72 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
73 73
@@ -86,8 +86,9 @@ s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int gro
86 } 86 }
87} 87}
88 88
89static inline void 89static inline void s3c_irqsub_ack(unsigned int irqno,
90s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) 90 unsigned int parentmask,
91 unsigned int group)
91{ 92{
92 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); 93 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
93 94
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
index 144dbfc6506d..08d1a7ef97b7 100644
--- a/arch/arm/plat-s5p/include/plat/irqs.h
+++ b/arch/arm/plat-samsung/include/plat/irqs.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/irqs.h 1/* linux/arch/arm/plat-samsung/include/plat/irqs.h
2 * 2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
@@ -10,8 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#ifndef __ASM_PLAT_S5P_IRQS_H 13#ifndef __PLAT_SAMSUNG_IRQS_H
14#define __ASM_PLAT_S5P_IRQS_H __FILE__ 14#define __PLAT_SAMSUNG_IRQS_H __FILE__
15 15
16/* we keep the first set of CPU IRQs out of the range of 16/* we keep the first set of CPU IRQs out of the range of
17 * the ISA space, so that the PC104 has them to itself 17 * the ISA space, so that the PC104 has them to itself
@@ -77,4 +77,4 @@
77#define S5P_IRQ_TYPE_EDGE_RISING (0x03) 77#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
78#define S5P_IRQ_TYPE_EDGE_BOTH (0x04) 78#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
79 79
80#endif /* __ASM_PLAT_S5P_IRQS_H */ 80#endif /* __PLAT_SAMSUNG_IRQS_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-samsung/include/plat/mci.h
index 2ac2b21ec490..c42d31711944 100644
--- a/arch/arm/plat-s3c24xx/include/plat/mci.h
+++ b/arch/arm/plat-samsung/include/plat/mci.h
@@ -27,11 +27,11 @@
27 * to a non-zero value, otherwise the default of 3.2-3.4V is used. 27 * to a non-zero value, otherwise the default of 3.2-3.4V is used.
28 */ 28 */
29struct s3c24xx_mci_pdata { 29struct s3c24xx_mci_pdata {
30 unsigned int no_wprotect : 1; 30 unsigned int no_wprotect:1;
31 unsigned int no_detect : 1; 31 unsigned int no_detect:1;
32 unsigned int wprotect_invert : 1; 32 unsigned int wprotect_invert:1;
33 unsigned int detect_invert : 1; /* set => detect active high. */ 33 unsigned int detect_invert:1; /* set => detect active high */
34 unsigned int use_dma : 1; 34 unsigned int use_dma:1;
35 35
36 unsigned int gpio_detect; 36 unsigned int gpio_detect;
37 unsigned int gpio_wprotect; 37 unsigned int gpio_wprotect;
diff --git a/arch/arm/plat-s5p/include/plat/mfc.h b/arch/arm/plat-samsung/include/plat/mfc.h
index 6697f8cb2949..ac13227272f0 100644
--- a/arch/arm/plat-s5p/include/plat/mfc.h
+++ b/arch/arm/plat-samsung/include/plat/mfc.h
@@ -7,8 +7,8 @@
7 * option) any later version. 7 * option) any later version.
8 */ 8 */
9 9
10#ifndef __PLAT_S5P_MFC_H 10#ifndef __PLAT_SAMSUNG_MFC_H
11#define __PLAT_S5P_MFC_H 11#define __PLAT_SAMSUNG_MFC_H __FILE__
12 12
13/** 13/**
14 * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver 14 * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
@@ -24,4 +24,4 @@
24void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, 24void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
25 phys_addr_t lbase, unsigned int lsize); 25 phys_addr_t lbase, unsigned int lsize);
26 26
27#endif /* __PLAT_S5P_MFC_H */ 27#endif /* __PLAT_SAMSUNG_MFC_H */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-samsung/include/plat/mipi_csis.h
index 9bd254c5ed22..c45b1e8d4c2e 100644
--- a/arch/arm/plat-s5p/include/plat/mipi_csis.h
+++ b/arch/arm/plat-samsung/include/plat/mipi_csis.h
@@ -8,8 +8,8 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#ifndef PLAT_S5P_MIPI_CSIS_H_ 11#ifndef __PLAT_SAMSUNG_MIPI_CSIS_H_
12#define PLAT_S5P_MIPI_CSIS_H_ __FILE__ 12#define __PLAT_SAMSUNG_MIPI_CSIS_H_ __FILE__
13 13
14struct platform_device; 14struct platform_device;
15 15
@@ -40,4 +40,4 @@ struct s5p_platform_mipi_csis {
40 */ 40 */
41int s5p_csis_phy_enable(struct platform_device *pdev, bool on); 41int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
42 42
43#endif /* PLAT_S5P_MIPI_CSIS_H_ */ 43#endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-samsung/include/plat/pll.h
index 3e21b9444cc5..357af7c1c664 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-samsung/include/plat/pll.h
@@ -1,11 +1,14 @@
1/* arch/arm/plat-s5p/include/plat/pll.h 1/* linux/arch/arm/plat-samsung/include/plat/pll.h
2 * 2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
5 * 5 *
6 * S5P PLL code 6 * Copyright 2008 Openmoko, Inc.
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
7 * 10 *
8 * Based on arch/arm/plat-s3c64xx/include/plat/pll.h 11 * Samsung PLL codes
9 * 12 *
10 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +17,111 @@
14 17
15#include <asm/div64.h> 18#include <asm/div64.h>
16 19
20#define S3C24XX_PLL_MDIV_MASK (0xFF)
21#define S3C24XX_PLL_PDIV_MASK (0x1F)
22#define S3C24XX_PLL_SDIV_MASK (0x3)
23#define S3C24XX_PLL_MDIV_SHIFT (12)
24#define S3C24XX_PLL_PDIV_SHIFT (4)
25#define S3C24XX_PLL_SDIV_SHIFT (0)
26
27static inline unsigned int s3c24xx_get_pll(unsigned int pllval,
28 unsigned int baseclk)
29{
30 unsigned int mdiv, pdiv, sdiv;
31 uint64_t fvco;
32
33 mdiv = (pllval >> S3C24XX_PLL_MDIV_SHIFT) & S3C24XX_PLL_MDIV_MASK;
34 pdiv = (pllval >> S3C24XX_PLL_PDIV_SHIFT) & S3C24XX_PLL_PDIV_MASK;
35 sdiv = (pllval >> S3C24XX_PLL_SDIV_SHIFT) & S3C24XX_PLL_SDIV_MASK;
36
37 fvco = (uint64_t)baseclk * (mdiv + 8);
38 do_div(fvco, (pdiv + 2) << sdiv);
39
40 return (unsigned int)fvco;
41}
42
43#define S3C2416_PLL_MDIV_MASK (0x3FF)
44#define S3C2416_PLL_PDIV_MASK (0x3F)
45#define S3C2416_PLL_SDIV_MASK (0x7)
46#define S3C2416_PLL_MDIV_SHIFT (14)
47#define S3C2416_PLL_PDIV_SHIFT (5)
48#define S3C2416_PLL_SDIV_SHIFT (0)
49
50static inline unsigned int s3c2416_get_pll(unsigned int pllval,
51 unsigned int baseclk)
52{
53 unsigned int mdiv, pdiv, sdiv;
54 uint64_t fvco;
55
56 mdiv = (pllval >> S3C2416_PLL_MDIV_SHIFT) & S3C2416_PLL_MDIV_MASK;
57 pdiv = (pllval >> S3C2416_PLL_PDIV_SHIFT) & S3C2416_PLL_PDIV_MASK;
58 sdiv = (pllval >> S3C2416_PLL_SDIV_SHIFT) & S3C2416_PLL_SDIV_MASK;
59
60 fvco = (uint64_t)baseclk * mdiv;
61 do_div(fvco, (pdiv << sdiv));
62
63 return (unsigned int)fvco;
64}
65
66#define S3C6400_PLL_MDIV_MASK (0x3FF)
67#define S3C6400_PLL_PDIV_MASK (0x3F)
68#define S3C6400_PLL_SDIV_MASK (0x7)
69#define S3C6400_PLL_MDIV_SHIFT (16)
70#define S3C6400_PLL_PDIV_SHIFT (8)
71#define S3C6400_PLL_SDIV_SHIFT (0)
72
73static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
74 u32 pllcon)
75{
76 u32 mdiv, pdiv, sdiv;
77 u64 fvco = baseclk;
78
79 mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
80 pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
81 sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
82
83 fvco *= mdiv;
84 do_div(fvco, (pdiv << sdiv));
85
86 return (unsigned long)fvco;
87}
88
89#define PLL6553X_MDIV_MASK (0x7F)
90#define PLL6553X_PDIV_MASK (0x1F)
91#define PLL6553X_SDIV_MASK (0x3)
92#define PLL6553X_KDIV_MASK (0xFFFF)
93#define PLL6553X_MDIV_SHIFT (16)
94#define PLL6553X_PDIV_SHIFT (8)
95#define PLL6553X_SDIV_SHIFT (0)
96
97static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
98 u32 pll_con0, u32 pll_con1)
99{
100 unsigned long result;
101 u32 mdiv, pdiv, sdiv, kdiv;
102 u64 tmp;
103
104 mdiv = (pll_con0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
105 pdiv = (pll_con0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
106 sdiv = (pll_con0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
107 kdiv = pll_con1 & PLL6553X_KDIV_MASK;
108
109 /*
110 * We need to multiple baseclk by mdiv (the integer part) and kdiv
111 * which is in 2^16ths, so shift mdiv up (does not overflow) and
112 * add kdiv before multiplying. The use of tmp is to avoid any
113 * overflows before shifting bac down into result when multipling
114 * by the mdiv and kdiv pair.
115 */
116
117 tmp = baseclk;
118 tmp *= (mdiv << 16) + kdiv;
119 do_div(tmp, (pdiv << sdiv));
120 result = tmp >> 16;
121
122 return result;
123}
124
17#define PLL35XX_MDIV_MASK (0x3FF) 125#define PLL35XX_MDIV_MASK (0x3FF)
18#define PLL35XX_PDIV_MASK (0x3F) 126#define PLL35XX_PDIV_MASK (0x3F)
19#define PLL35XX_SDIV_MASK (0x7) 127#define PLL35XX_SDIV_MASK (0x7)
@@ -97,15 +205,24 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
97 return (unsigned long)fvco; 205 return (unsigned long)fvco;
98} 206}
99 207
100#define PLL46XX_KDIV_MASK (0xFFFF) 208/* CON0 bit-fields */
101#define PLL4650C_KDIV_MASK (0xFFF)
102#define PLL46XX_MDIV_MASK (0x1FF) 209#define PLL46XX_MDIV_MASK (0x1FF)
103#define PLL46XX_PDIV_MASK (0x3F) 210#define PLL46XX_PDIV_MASK (0x3F)
104#define PLL46XX_SDIV_MASK (0x7) 211#define PLL46XX_SDIV_MASK (0x7)
212#define PLL46XX_LOCKED_SHIFT (29)
105#define PLL46XX_MDIV_SHIFT (16) 213#define PLL46XX_MDIV_SHIFT (16)
106#define PLL46XX_PDIV_SHIFT (8) 214#define PLL46XX_PDIV_SHIFT (8)
107#define PLL46XX_SDIV_SHIFT (0) 215#define PLL46XX_SDIV_SHIFT (0)
108 216
217/* CON1 bit-fields */
218#define PLL46XX_MRR_MASK (0x1F)
219#define PLL46XX_MFR_MASK (0x3F)
220#define PLL46XX_KDIV_MASK (0xFFFF)
221#define PLL4650C_KDIV_MASK (0xFFF)
222#define PLL46XX_MRR_SHIFT (24)
223#define PLL46XX_MFR_SHIFT (16)
224#define PLL46XX_KDIV_SHIFT (0)
225
109enum pll46xx_type_t { 226enum pll46xx_type_t {
110 pll_4600, 227 pll_4600,
111 pll_4650, 228 pll_4650,
@@ -123,6 +240,7 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
123 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; 240 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
124 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; 241 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
125 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; 242 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
243 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
126 244
127 if (pll_type == pll_4650c) 245 if (pll_type == pll_4650c)
128 kdiv = pll_con1 & PLL4650C_KDIV_MASK; 246 kdiv = pll_con1 & PLL4650C_KDIV_MASK;
@@ -148,6 +266,7 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
148#define PLL90XX_PDIV_MASK (0x3F) 266#define PLL90XX_PDIV_MASK (0x3F)
149#define PLL90XX_SDIV_MASK (0x7) 267#define PLL90XX_SDIV_MASK (0x7)
150#define PLL90XX_KDIV_MASK (0xffff) 268#define PLL90XX_KDIV_MASK (0xffff)
269#define PLL90XX_LOCKED_SHIFT (29)
151#define PLL90XX_MDIV_SHIFT (16) 270#define PLL90XX_MDIV_SHIFT (16)
152#define PLL90XX_PDIV_SHIFT (8) 271#define PLL90XX_PDIV_SHIFT (8)
153#define PLL90XX_SDIV_SHIFT (0) 272#define PLL90XX_SDIV_SHIFT (0)
@@ -165,7 +284,8 @@ static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
165 sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK; 284 sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
166 kdiv = pll_conk & PLL90XX_KDIV_MASK; 285 kdiv = pll_conk & PLL90XX_KDIV_MASK;
167 286
168 /* We need to multiple baseclk by mdiv (the integer part) and kdiv 287 /*
288 * We need to multiple baseclk by mdiv (the integer part) and kdiv
169 * which is in 2^16ths, so shift mdiv up (does not overflow) and 289 * which is in 2^16ths, so shift mdiv up (does not overflow) and
170 * add kdiv before multiplying. The use of tmp is to avoid any 290 * add kdiv before multiplying. The use of tmp is to avoid any
171 * overflows before shifting bac down into result when multipling 291 * overflows before shifting bac down into result when multipling
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
deleted file mode 100644
index b8b7e1d884f8..000000000000
--- a/arch/arm/plat-samsung/include/plat/pll6553x.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/* arch/arm/plat-samsung/include/plat/pll6553x.h
2 * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung PLL6553x PLL code
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
17
18#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
19#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
20#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
21#define PLL6553X_MDIV_SHIFT (16)
22#define PLL6553X_PDIV_SHIFT (8)
23#define PLL6553X_SDIV_SHIFT (0)
24#define PLL6553X_KDIV_MASK (0xffff)
25
26static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
27 u32 pll0, u32 pll1)
28{
29 unsigned long result;
30 u32 mdiv, pdiv, sdiv, kdiv;
31 u64 tmp;
32
33 mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
34 pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
35 sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
36 kdiv = pll1 & PLL6553X_KDIV_MASK;
37
38 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
39 * which is in 2^16ths, so shift mdiv up (does not overflow) and
40 * add kdiv before multiplying. The use of tmp is to avoid any
41 * overflows before shifting bac down into result when multipling
42 * by the mdiv and kdiv pair.
43 */
44
45 tmp = baseclk;
46 tmp *= (mdiv << 16) + kdiv;
47 do_div(tmp, (pdiv << sdiv));
48 result = tmp >> 16;
49
50 return result;
51}
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index f6749916d194..dcf68709f9cf 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -165,20 +165,20 @@ extern void s3c_pm_check_store(void);
165extern void s3c_pm_configure_extint(void); 165extern void s3c_pm_configure_extint(void);
166 166
167/** 167/**
168 * s3c_pm_restore_gpios() - restore the state of the gpios after sleep. 168 * samsung_pm_restore_gpios() - restore the state of the gpios after sleep.
169 * 169 *
170 * Restore the state of the GPIO pins after sleep, which may involve ensuring 170 * Restore the state of the GPIO pins after sleep, which may involve ensuring
171 * that we do not glitch the state of the pins from that the bootloader's 171 * that we do not glitch the state of the pins from that the bootloader's
172 * resume code has done. 172 * resume code has done.
173*/ 173*/
174extern void s3c_pm_restore_gpios(void); 174extern void samsung_pm_restore_gpios(void);
175 175
176/** 176/**
177 * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. 177 * samsung_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
178 * 178 *
179 * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios(). 179 * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios().
180 */ 180 */
181extern void s3c_pm_save_gpios(void); 181extern void samsung_pm_save_gpios(void);
182 182
183extern void s3c_pm_save_core(void); 183extern void s3c_pm_save_core(void);
184extern void s3c_pm_restore_core(void); 184extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/mach-exynos4/include/mach/pwm-clock.h b/arch/arm/plat-samsung/include/plat/pwm-clock.h
index 8e12090287bb..bf6a60eb6237 100644
--- a/arch/arm/mach-exynos4/include/mach/pwm-clock.h
+++ b/arch/arm/plat-samsung/include/plat/pwm-clock.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-exynos4/include/mach/pwm-clock.h 1/* linux/arch/arm/plat-samsung/include/plat/pwm-clock.h
2 * 2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -8,17 +8,15 @@
8 * Ben Dooks <ben@simtec.co.uk> 8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/ 9 * http://armlinux.simtec.co.uk/
10 * 10 *
11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h 11 * SAMSUNG - pwm clock and timer support
12 *
13 * EXYNOS4 - pwm clock and timer support
14 * 12 *
15 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
18*/ 16*/
19 17
20#ifndef __ASM_ARCH_PWMCLK_H 18#ifndef __ASM_PLAT_PWM_CLOCK_H
21#define __ASM_ARCH_PWMCLK_H __FILE__ 19#define __ASM_PLAT_PWM_CLOCK_H __FILE__
22 20
23/** 21/**
24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk 22 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
@@ -29,7 +27,14 @@
29 */ 27 */
30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) 28static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
31{ 29{
32 return tcfg == S3C64XX_TCFG1_MUX_TCLK; 30 if (soc_is_s3c24xx())
31 return tcfg == S3C2410_TCFG1_MUX_TCLK;
32 else if (soc_is_s3c64xx() || soc_is_s5pc100())
33 return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
34 else if (soc_is_s5p6440() || soc_is_s5p6450())
35 return 0;
36 else
37 return tcfg == S3C64XX_TCFG1_MUX_TCLK;
33} 38}
34 39
35/** 40/**
@@ -41,7 +46,10 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
41 */ 46 */
42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) 47static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
43{ 48{
44 return 1 << tcfg1; 49 if (soc_is_s3c24xx())
50 return 1 << (tcfg1 + 1);
51 else
52 return 1 << tcfg1;
45} 53}
46 54
47/** 55/**
@@ -51,7 +59,10 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
51 */ 59 */
52static inline unsigned int pwm_tdiv_has_div1(void) 60static inline unsigned int pwm_tdiv_has_div1(void)
53{ 61{
54 return 1; 62 if (soc_is_s3c24xx())
63 return 0;
64 else
65 return 1;
55} 66}
56 67
57/** 68/**
@@ -62,9 +73,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
62 */ 73 */
63static inline unsigned long pwm_tdiv_div_bits(unsigned int div) 74static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
64{ 75{
65 return ilog2(div); 76 if (soc_is_s3c24xx())
77 return ilog2(div) - 1;
78 else
79 return ilog2(div);
66} 80}
67 81#endif /* __ASM_PLAT_PWM_CLOCK_H */
68#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
69
70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h
index 035e8c38d69c..70612100120f 100644
--- a/arch/arm/plat-samsung/include/plat/regs-adc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -20,6 +20,7 @@
20#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C) 20#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
21#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) 21#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
22#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) 22#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
23#define S3C2443_ADCMUX S3C2410_ADCREG(0x18)
23#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) 24#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
24#define S5P_ADCMUX S3C2410_ADCREG(0x1C) 25#define S5P_ADCMUX S3C2410_ADCREG(0x1C)
25#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) 26#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
@@ -33,6 +34,7 @@
33#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6) 34#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
34#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3) 35#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
35#define S3C2410_ADCCON_MUXMASK (0x7<<3) 36#define S3C2410_ADCCON_MUXMASK (0x7<<3)
37#define S3C2416_ADCCON_RESSEL (1 << 3)
36#define S3C2410_ADCCON_STDBM (1<<2) 38#define S3C2410_ADCCON_STDBM (1<<2)
37#define S3C2410_ADCCON_READ_START (1<<1) 39#define S3C2410_ADCCON_READ_START (1<<1)
38#define S3C2410_ADCCON_ENABLE_START (1<<0) 40#define S3C2410_ADCCON_ENABLE_START (1<<0)
@@ -40,6 +42,7 @@
40 42
41 43
42/* ADCTSC Register Bits */ 44/* ADCTSC Register Bits */
45#define S3C2443_ADCTSC_UD_SEN (1 << 8)
43#define S3C2410_ADCTSC_YM_SEN (1<<7) 46#define S3C2410_ADCTSC_YM_SEN (1<<7)
44#define S3C2410_ADCTSC_YP_SEN (1<<6) 47#define S3C2410_ADCTSC_YP_SEN (1<<6)
45#define S3C2410_ADCTSC_XM_SEN (1<<5) 48#define S3C2410_ADCTSC_XM_SEN (1<<5)
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h
index 1b0f4c36d384..178bccbe4804 100644
--- a/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
+++ b/arch/arm/plat-samsung/include/plat/regs-dma.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/include/mach/dma.h 1/* arch/arm/plat-samsung/include/plat/regs-dma.h
2 * 2 *
3 * Copyright (C) 2003-2006 Simtec Electronics 3 * Copyright (C) 2003-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -10,7 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13/* DMA Register definitions */ 13#ifndef __ASM_PLAT_REGS_DMA_H
14#define __ASM_PLAT_REGS_DMA_H __FILE__
14 15
15#define S3C2410_DMA_DISRC (0x00) 16#define S3C2410_DMA_DISRC (0x00)
16#define S3C2410_DMA_DISRCC (0x04) 17#define S3C2410_DMA_DISRCC (0x04)
@@ -24,74 +25,75 @@
24#define S3C2412_DMA_DMAREQSEL (0x24) 25#define S3C2412_DMA_DMAREQSEL (0x24)
25#define S3C2443_DMA_DMAREQSEL (0x24) 26#define S3C2443_DMA_DMAREQSEL (0x24)
26 27
27#define S3C2410_DISRCC_INC (1<<0) 28#define S3C2410_DISRCC_INC (1 << 0)
28#define S3C2410_DISRCC_APB (1<<1) 29#define S3C2410_DISRCC_APB (1 << 1)
29 30
30#define S3C2410_DMASKTRIG_STOP (1<<2) 31#define S3C2410_DMASKTRIG_STOP (1 << 2)
31#define S3C2410_DMASKTRIG_ON (1<<1) 32#define S3C2410_DMASKTRIG_ON (1 << 1)
32#define S3C2410_DMASKTRIG_SWTRIG (1<<0) 33#define S3C2410_DMASKTRIG_SWTRIG (1 << 0)
33 34
34#define S3C2410_DCON_DEMAND (0<<31) 35#define S3C2410_DCON_DEMAND (0 << 31)
35#define S3C2410_DCON_HANDSHAKE (1<<31) 36#define S3C2410_DCON_HANDSHAKE (1 << 31)
36#define S3C2410_DCON_SYNC_PCLK (0<<30) 37#define S3C2410_DCON_SYNC_PCLK (0 << 30)
37#define S3C2410_DCON_SYNC_HCLK (1<<30) 38#define S3C2410_DCON_SYNC_HCLK (1 << 30)
38 39
39#define S3C2410_DCON_INTREQ (1<<29) 40#define S3C2410_DCON_INTREQ (1 << 29)
40 41
41#define S3C2410_DCON_CH0_XDREQ0 (0<<24) 42#define S3C2410_DCON_CH0_XDREQ0 (0 << 24)
42#define S3C2410_DCON_CH0_UART0 (1<<24) 43#define S3C2410_DCON_CH0_UART0 (1 << 24)
43#define S3C2410_DCON_CH0_SDI (2<<24) 44#define S3C2410_DCON_CH0_SDI (2 << 24)
44#define S3C2410_DCON_CH0_TIMER (3<<24) 45#define S3C2410_DCON_CH0_TIMER (3 << 24)
45#define S3C2410_DCON_CH0_USBEP1 (4<<24) 46#define S3C2410_DCON_CH0_USBEP1 (4 << 24)
46 47
47#define S3C2410_DCON_CH1_XDREQ1 (0<<24) 48#define S3C2410_DCON_CH1_XDREQ1 (0 << 24)
48#define S3C2410_DCON_CH1_UART1 (1<<24) 49#define S3C2410_DCON_CH1_UART1 (1 << 24)
49#define S3C2410_DCON_CH1_I2SSDI (2<<24) 50#define S3C2410_DCON_CH1_I2SSDI (2 << 24)
50#define S3C2410_DCON_CH1_SPI (3<<24) 51#define S3C2410_DCON_CH1_SPI (3 << 24)
51#define S3C2410_DCON_CH1_USBEP2 (4<<24) 52#define S3C2410_DCON_CH1_USBEP2 (4 << 24)
52 53
53#define S3C2410_DCON_CH2_I2SSDO (0<<24) 54#define S3C2410_DCON_CH2_I2SSDO (0 << 24)
54#define S3C2410_DCON_CH2_I2SSDI (1<<24) 55#define S3C2410_DCON_CH2_I2SSDI (1 << 24)
55#define S3C2410_DCON_CH2_SDI (2<<24) 56#define S3C2410_DCON_CH2_SDI (2 << 24)
56#define S3C2410_DCON_CH2_TIMER (3<<24) 57#define S3C2410_DCON_CH2_TIMER (3 << 24)
57#define S3C2410_DCON_CH2_USBEP3 (4<<24) 58#define S3C2410_DCON_CH2_USBEP3 (4 << 24)
58 59
59#define S3C2410_DCON_CH3_UART2 (0<<24) 60#define S3C2410_DCON_CH3_UART2 (0 << 24)
60#define S3C2410_DCON_CH3_SDI (1<<24) 61#define S3C2410_DCON_CH3_SDI (1 << 24)
61#define S3C2410_DCON_CH3_SPI (2<<24) 62#define S3C2410_DCON_CH3_SPI (2 << 24)
62#define S3C2410_DCON_CH3_TIMER (3<<24) 63#define S3C2410_DCON_CH3_TIMER (3 << 24)
63#define S3C2410_DCON_CH3_USBEP4 (4<<24) 64#define S3C2410_DCON_CH3_USBEP4 (4 << 24)
64 65
65#define S3C2410_DCON_SRCSHIFT (24) 66#define S3C2410_DCON_SRCSHIFT (24)
66#define S3C2410_DCON_SRCMASK (7<<24) 67#define S3C2410_DCON_SRCMASK (7 << 24)
67 68
68#define S3C2410_DCON_BYTE (0<<20) 69#define S3C2410_DCON_BYTE (0 << 20)
69#define S3C2410_DCON_HALFWORD (1<<20) 70#define S3C2410_DCON_HALFWORD (1 << 20)
70#define S3C2410_DCON_WORD (2<<20) 71#define S3C2410_DCON_WORD (2 << 20)
71 72
72#define S3C2410_DCON_AUTORELOAD (0<<22) 73#define S3C2410_DCON_AUTORELOAD (0 << 22)
73#define S3C2410_DCON_NORELOAD (1<<22) 74#define S3C2410_DCON_NORELOAD (1 << 22)
74#define S3C2410_DCON_HWTRIG (1<<23) 75#define S3C2410_DCON_HWTRIG (1 << 23)
75 76
76#ifdef CONFIG_CPU_S3C2440 77#ifdef CONFIG_CPU_S3C2440
77#define S3C2440_DIDSTC_CHKINT (1<<2)
78 78
79#define S3C2440_DCON_CH0_I2SSDO (5<<24) 79#define S3C2440_DIDSTC_CHKINT (1 << 2)
80#define S3C2440_DCON_CH0_PCMIN (6<<24)
81 80
82#define S3C2440_DCON_CH1_PCMOUT (5<<24) 81#define S3C2440_DCON_CH0_I2SSDO (5 << 24)
83#define S3C2440_DCON_CH1_SDI (6<<24) 82#define S3C2440_DCON_CH0_PCMIN (6 << 24)
84 83
85#define S3C2440_DCON_CH2_PCMIN (5<<24) 84#define S3C2440_DCON_CH1_PCMOUT (5 << 24)
86#define S3C2440_DCON_CH2_MICIN (6<<24) 85#define S3C2440_DCON_CH1_SDI (6 << 24)
87 86
88#define S3C2440_DCON_CH3_MICIN (5<<24) 87#define S3C2440_DCON_CH2_PCMIN (5 << 24)
89#define S3C2440_DCON_CH3_PCMOUT (6<<24) 88#define S3C2440_DCON_CH2_MICIN (6 << 24)
90#endif 89
90#define S3C2440_DCON_CH3_MICIN (5 << 24)
91#define S3C2440_DCON_CH3_PCMOUT (6 << 24)
92#endif /* CONFIG_CPU_S3C2440 */
91 93
92#ifdef CONFIG_CPU_S3C2412 94#ifdef CONFIG_CPU_S3C2412
93 95
94#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1) 96#define S3C2412_DMAREQSEL_SRC(x) ((x) << 1)
95 97
96#define S3C2412_DMAREQSEL_HW (1) 98#define S3C2412_DMAREQSEL_HW (1)
97 99
@@ -115,10 +117,11 @@
115#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22) 117#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
116#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23) 118#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
117#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) 119#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
120#endif /* CONFIG_CPU_S3C2412 */
118 121
119#endif 122#ifdef CONFIG_CPU_S3C2443
120 123
121#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1) 124#define S3C2443_DMAREQSEL_SRC(x) ((x) << 1)
122 125
123#define S3C2443_DMAREQSEL_HW (1) 126#define S3C2443_DMAREQSEL_HW (1)
124 127
@@ -141,5 +144,8 @@
141#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25) 144#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
142#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26) 145#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
143#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27) 146#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
144#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28) 147#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
145#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29) 148#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
149#endif /* CONFIG_CPU_S3C2443 */
150
151#endif /* __ASM_PLAT_REGS_DMA_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-iis.h b/arch/arm/plat-samsung/include/plat/regs-iis.h
new file mode 100644
index 000000000000..a18d35e7a735
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-iis.h
@@ -0,0 +1,70 @@
1/* arch/arm/plat-samsung/include/plat/regs-iis.h
2 *
3 * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
4 * http://www.simtec.co.uk/products/SWLINUX/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * S3C2410 IIS register definition
11*/
12
13#ifndef __ASM_ARCH_REGS_IIS_H
14#define __ASM_ARCH_REGS_IIS_H
15
16#define S3C2410_IISCON (0x00)
17
18#define S3C2410_IISCON_LRINDEX (1 << 8)
19#define S3C2410_IISCON_TXFIFORDY (1 << 7)
20#define S3C2410_IISCON_RXFIFORDY (1 << 6)
21#define S3C2410_IISCON_TXDMAEN (1 << 5)
22#define S3C2410_IISCON_RXDMAEN (1 << 4)
23#define S3C2410_IISCON_TXIDLE (1 << 3)
24#define S3C2410_IISCON_RXIDLE (1 << 2)
25#define S3C2410_IISCON_PSCEN (1 << 1)
26#define S3C2410_IISCON_IISEN (1 << 0)
27
28#define S3C2410_IISMOD (0x04)
29
30#define S3C2440_IISMOD_MPLL (1 << 9)
31#define S3C2410_IISMOD_SLAVE (1 << 8)
32#define S3C2410_IISMOD_NOXFER (0 << 6)
33#define S3C2410_IISMOD_RXMODE (1 << 6)
34#define S3C2410_IISMOD_TXMODE (2 << 6)
35#define S3C2410_IISMOD_TXRXMODE (3 << 6)
36#define S3C2410_IISMOD_LR_LLOW (0 << 5)
37#define S3C2410_IISMOD_LR_RLOW (1 << 5)
38#define S3C2410_IISMOD_IIS (0 << 4)
39#define S3C2410_IISMOD_MSB (1 << 4)
40#define S3C2410_IISMOD_8BIT (0 << 3)
41#define S3C2410_IISMOD_16BIT (1 << 3)
42#define S3C2410_IISMOD_BITMASK (1 << 3)
43#define S3C2410_IISMOD_256FS (0 << 2)
44#define S3C2410_IISMOD_384FS (1 << 2)
45#define S3C2410_IISMOD_16FS (0 << 0)
46#define S3C2410_IISMOD_32FS (1 << 0)
47#define S3C2410_IISMOD_48FS (2 << 0)
48#define S3C2410_IISMOD_FS_MASK (3 << 0)
49
50#define S3C2410_IISPSR (0x08)
51
52#define S3C2410_IISPSR_INTMASK (31 << 5)
53#define S3C2410_IISPSR_INTSHIFT (5)
54#define S3C2410_IISPSR_EXTMASK (31 << 0)
55#define S3C2410_IISPSR_EXTSHFIT (0)
56
57#define S3C2410_IISFCON (0x0c)
58
59#define S3C2410_IISFCON_TXDMA (1 << 15)
60#define S3C2410_IISFCON_RXDMA (1 << 14)
61#define S3C2410_IISFCON_TXENABLE (1 << 13)
62#define S3C2410_IISFCON_RXENABLE (1 << 12)
63#define S3C2410_IISFCON_TXMASK (0x3f << 6)
64#define S3C2410_IISFCON_TXSHIFT (6)
65#define S3C2410_IISFCON_RXMASK (0x3f)
66#define S3C2410_IISFCON_RXSHIFT (0)
67
68#define S3C2410_IISFIFO (0x10)
69
70#endif /* __ASM_ARCH_REGS_IIS_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-spi.h b/arch/arm/plat-samsung/include/plat/regs-spi.h
new file mode 100644
index 000000000000..552fe7cfe281
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-spi.h
@@ -0,0 +1,48 @@
1/* arch/arm/plat-samsung/include/plat/regs-spi.h
2 *
3 * Copyright (c) 2004 Fetron GmbH
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * S3C2410 SPI register definition
10*/
11
12#ifndef __ASM_ARCH_REGS_SPI_H
13#define __ASM_ARCH_REGS_SPI_H
14
15#define S3C2410_SPI1 (0x20)
16#define S3C2412_SPI1 (0x100)
17
18#define S3C2410_SPCON (0x00)
19
20#define S3C2410_SPCON_SMOD_DMA (2 << 5) /* DMA mode */
21#define S3C2410_SPCON_SMOD_INT (1 << 5) /* interrupt mode */
22#define S3C2410_SPCON_SMOD_POLL (0 << 5) /* polling mode */
23#define S3C2410_SPCON_ENSCK (1 << 4) /* Enable SCK */
24#define S3C2410_SPCON_MSTR (1 << 3) /* Master:1, Slave:0 select */
25#define S3C2410_SPCON_CPOL_HIGH (1 << 2) /* Clock polarity select */
26#define S3C2410_SPCON_CPOL_LOW (0 << 2) /* Clock polarity select */
27
28#define S3C2410_SPCON_CPHA_FMTB (1 << 1) /* Clock Phase Select */
29#define S3C2410_SPCON_CPHA_FMTA (0 << 1) /* Clock Phase Select */
30
31#define S3C2410_SPSTA (0x04)
32
33#define S3C2410_SPSTA_DCOL (1 << 2) /* Data Collision Error */
34#define S3C2410_SPSTA_MULD (1 << 1) /* Multi Master Error */
35#define S3C2410_SPSTA_READY (1 << 0) /* Data Tx/Rx ready */
36#define S3C2412_SPSTA_READY_ORG (1 << 3)
37
38#define S3C2410_SPPIN (0x08)
39
40#define S3C2410_SPPIN_ENMUL (1 << 2) /* Multi Master Error detect */
41#define S3C2410_SPPIN_RESERVED (1 << 1)
42#define S3C2410_SPPIN_KEEP (1 << 0) /* Master Out keep */
43
44#define S3C2410_SPPRE (0x0C)
45#define S3C2410_SPTDAT (0x10)
46#define S3C2410_SPRDAT (0x14)
47
48#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-samsung/include/plat/regs-srom.h
index f121ab5e76cb..9b6729c81cda 100644
--- a/arch/arm/plat-s5p/include/plat/regs-srom.h
+++ b/arch/arm/plat-samsung/include/plat/regs-srom.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h 1/* linux/arch/arm/plat-samsung/include/plat/regs-srom.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -10,8 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#ifndef __ASM_PLAT_S5P_REGS_SROM_H 13#ifndef __PLAT_SAMSUNG_REGS_SROM_H
14#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__ 14#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__
15 15
16#include <mach/map.h> 16#include <mach/map.h>
17 17
@@ -51,4 +51,4 @@
51#define S5P_SROM_BCX__TCOS__SHIFT 24 51#define S5P_SROM_BCX__TCOS__SHIFT 24
52#define S5P_SROM_BCX__TACS__SHIFT 28 52#define S5P_SROM_BCX__TACS__SHIFT 28
53 53
54#endif /* __ASM_PLAT_S5P_REGS_SROM_H */ 54#endif /* __PLAT_SAMSUNG_REGS_SROM_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-udc.h b/arch/arm/plat-samsung/include/plat/regs-udc.h
index f0dd4a41b37b..4003d3dab4e7 100644
--- a/arch/arm/plat-s3c24xx/include/plat/regs-udc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-udc.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-udc.h 1/* arch/arm/plat-samsung/include/plat/regs-udc.h
2 * 2 *
3 * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at> 3 * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
4 * 4 *
@@ -75,79 +75,77 @@
75#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198) 75#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198)
76#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c) 76#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c)
77 77
78#define S3C2410_UDC_FUNCADDR_UPDATE (1<<7) 78#define S3C2410_UDC_FUNCADDR_UPDATE (1 << 7)
79 79
80#define S3C2410_UDC_PWR_ISOUP (1<<7) // R/W 80#define S3C2410_UDC_PWR_ISOUP (1 << 7) /* R/W */
81#define S3C2410_UDC_PWR_RESET (1<<3) // R 81#define S3C2410_UDC_PWR_RESET (1 << 3) /* R */
82#define S3C2410_UDC_PWR_RESUME (1<<2) // R/W 82#define S3C2410_UDC_PWR_RESUME (1 << 2) /* R/W */
83#define S3C2410_UDC_PWR_SUSPEND (1<<1) // R 83#define S3C2410_UDC_PWR_SUSPEND (1 << 1) /* R */
84#define S3C2410_UDC_PWR_ENSUSPEND (1<<0) // R/W 84#define S3C2410_UDC_PWR_ENSUSPEND (1 << 0) /* R/W */
85 85
86#define S3C2410_UDC_PWR_DEFAULT 0x00 86#define S3C2410_UDC_PWR_DEFAULT (0x00)
87 87
88#define S3C2410_UDC_INT_EP4 (1<<4) // R/W (clear only) 88#define S3C2410_UDC_INT_EP4 (1 << 4) /* R/W (clear only) */
89#define S3C2410_UDC_INT_EP3 (1<<3) // R/W (clear only) 89#define S3C2410_UDC_INT_EP3 (1 << 3) /* R/W (clear only) */
90#define S3C2410_UDC_INT_EP2 (1<<2) // R/W (clear only) 90#define S3C2410_UDC_INT_EP2 (1 << 2) /* R/W (clear only) */
91#define S3C2410_UDC_INT_EP1 (1<<1) // R/W (clear only) 91#define S3C2410_UDC_INT_EP1 (1 << 1) /* R/W (clear only) */
92#define S3C2410_UDC_INT_EP0 (1<<0) // R/W (clear only) 92#define S3C2410_UDC_INT_EP0 (1 << 0) /* R/W (clear only) */
93 93
94#define S3C2410_UDC_USBINT_RESET (1<<2) // R/W (clear only) 94#define S3C2410_UDC_USBINT_RESET (1 << 2) /* R/W (clear only) */
95#define S3C2410_UDC_USBINT_RESUME (1<<1) // R/W (clear only) 95#define S3C2410_UDC_USBINT_RESUME (1 << 1) /* R/W (clear only) */
96#define S3C2410_UDC_USBINT_SUSPEND (1<<0) // R/W (clear only) 96#define S3C2410_UDC_USBINT_SUSPEND (1 << 0) /* R/W (clear only) */
97 97
98#define S3C2410_UDC_INTE_EP4 (1<<4) // R/W 98#define S3C2410_UDC_INTE_EP4 (1 << 4) /* R/W */
99#define S3C2410_UDC_INTE_EP3 (1<<3) // R/W 99#define S3C2410_UDC_INTE_EP3 (1 << 3) /* R/W */
100#define S3C2410_UDC_INTE_EP2 (1<<2) // R/W 100#define S3C2410_UDC_INTE_EP2 (1 << 2) /* R/W */
101#define S3C2410_UDC_INTE_EP1 (1<<1) // R/W 101#define S3C2410_UDC_INTE_EP1 (1 << 1) /* R/W */
102#define S3C2410_UDC_INTE_EP0 (1<<0) // R/W 102#define S3C2410_UDC_INTE_EP0 (1 << 0) /* R/W */
103
104#define S3C2410_UDC_USBINTE_RESET (1<<2) // R/W
105#define S3C2410_UDC_USBINTE_SUSPEND (1<<0) // R/W
106 103
104#define S3C2410_UDC_USBINTE_RESET (1 << 2) /* R/W */
105#define S3C2410_UDC_USBINTE_SUSPEND (1 << 0) /* R/W */
107 106
108#define S3C2410_UDC_INDEX_EP0 (0x00) 107#define S3C2410_UDC_INDEX_EP0 (0x00)
109#define S3C2410_UDC_INDEX_EP1 (0x01) // ?? 108#define S3C2410_UDC_INDEX_EP1 (0x01)
110#define S3C2410_UDC_INDEX_EP2 (0x02) // ?? 109#define S3C2410_UDC_INDEX_EP2 (0x02)
111#define S3C2410_UDC_INDEX_EP3 (0x03) // ?? 110#define S3C2410_UDC_INDEX_EP3 (0x03)
112#define S3C2410_UDC_INDEX_EP4 (0x04) // ?? 111#define S3C2410_UDC_INDEX_EP4 (0x04)
113 112
114#define S3C2410_UDC_ICSR1_CLRDT (1<<6) // R/W 113#define S3C2410_UDC_ICSR1_CLRDT (1 << 6) /* R/W */
115#define S3C2410_UDC_ICSR1_SENTSTL (1<<5) // R/W (clear only) 114#define S3C2410_UDC_ICSR1_SENTSTL (1 << 5) /* R/W (clear only) */
116#define S3C2410_UDC_ICSR1_SENDSTL (1<<4) // R/W 115#define S3C2410_UDC_ICSR1_SENDSTL (1 << 4) /* R/W */
117#define S3C2410_UDC_ICSR1_FFLUSH (1<<3) // W (set only) 116#define S3C2410_UDC_ICSR1_FFLUSH (1 << 3) /* W (set only) */
118#define S3C2410_UDC_ICSR1_UNDRUN (1<<2) // R/W (clear only) 117#define S3C2410_UDC_ICSR1_UNDRUN (1 << 2) /* R/W (clear only) */
119#define S3C2410_UDC_ICSR1_PKTRDY (1<<0) // R/W (set only) 118#define S3C2410_UDC_ICSR1_PKTRDY (1 << 0) /* R/W (set only) */
120 119
121#define S3C2410_UDC_ICSR2_AUTOSET (1<<7) // R/W 120#define S3C2410_UDC_ICSR2_AUTOSET (1 << 7) /* R/W */
122#define S3C2410_UDC_ICSR2_ISO (1<<6) // R/W 121#define S3C2410_UDC_ICSR2_ISO (1 << 6) /* R/W */
123#define S3C2410_UDC_ICSR2_MODEIN (1<<5) // R/W 122#define S3C2410_UDC_ICSR2_MODEIN (1 << 5) /* R/W */
124#define S3C2410_UDC_ICSR2_DMAIEN (1<<4) // R/W 123#define S3C2410_UDC_ICSR2_DMAIEN (1 << 4) /* R/W */
125 124
126#define S3C2410_UDC_OCSR1_CLRDT (1<<7) // R/W 125#define S3C2410_UDC_OCSR1_CLRDT (1 << 7) /* R/W */
127#define S3C2410_UDC_OCSR1_SENTSTL (1<<6) // R/W (clear only) 126#define S3C2410_UDC_OCSR1_SENTSTL (1 << 6) /* R/W (clear only) */
128#define S3C2410_UDC_OCSR1_SENDSTL (1<<5) // R/W 127#define S3C2410_UDC_OCSR1_SENDSTL (1 << 5) /* R/W */
129#define S3C2410_UDC_OCSR1_FFLUSH (1<<4) // R/W 128#define S3C2410_UDC_OCSR1_FFLUSH (1 << 4) /* R/W */
130#define S3C2410_UDC_OCSR1_DERROR (1<<3) // R 129#define S3C2410_UDC_OCSR1_DERROR (1 << 3) /* R */
131#define S3C2410_UDC_OCSR1_OVRRUN (1<<2) // R/W (clear only) 130#define S3C2410_UDC_OCSR1_OVRRUN (1 << 2) /* R/W (clear only) */
132#define S3C2410_UDC_OCSR1_PKTRDY (1<<0) // R/W (clear only) 131#define S3C2410_UDC_OCSR1_PKTRDY (1 << 0) /* R/W (clear only) */
133 132
134#define S3C2410_UDC_OCSR2_AUTOCLR (1<<7) // R/W 133#define S3C2410_UDC_OCSR2_AUTOCLR (1 << 7) /* R/W */
135#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W 134#define S3C2410_UDC_OCSR2_ISO (1 << 6) /* R/W */
136#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W 135#define S3C2410_UDC_OCSR2_DMAIEN (1 << 5) /* R/W */
137 136
138#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0) 137#define S3C2410_UDC_EP0_CSR_OPKRDY (1 << 0)
139#define S3C2410_UDC_EP0_CSR_IPKRDY (1<<1) 138#define S3C2410_UDC_EP0_CSR_IPKRDY (1 << 1)
140#define S3C2410_UDC_EP0_CSR_SENTSTL (1<<2) 139#define S3C2410_UDC_EP0_CSR_SENTSTL (1 << 2)
141#define S3C2410_UDC_EP0_CSR_DE (1<<3) 140#define S3C2410_UDC_EP0_CSR_DE (1 << 3)
142#define S3C2410_UDC_EP0_CSR_SE (1<<4) 141#define S3C2410_UDC_EP0_CSR_SE (1 << 4)
143#define S3C2410_UDC_EP0_CSR_SENDSTL (1<<5) 142#define S3C2410_UDC_EP0_CSR_SENDSTL (1 << 5)
144#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1<<6) 143#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1 << 6)
145#define S3C2410_UDC_EP0_CSR_SSE (1<<7) 144#define S3C2410_UDC_EP0_CSR_SSE (1 << 7)
146 145
147#define S3C2410_UDC_MAXP_8 (1<<0) 146#define S3C2410_UDC_MAXP_8 (1 << 0)
148#define S3C2410_UDC_MAXP_16 (1<<1) 147#define S3C2410_UDC_MAXP_16 (1 << 1)
149#define S3C2410_UDC_MAXP_32 (1<<2) 148#define S3C2410_UDC_MAXP_32 (1 << 2)
150#define S3C2410_UDC_MAXP_64 (1<<3) 149#define S3C2410_UDC_MAXP_64 (1 << 3)
151
152 150
153#endif 151#endif
diff --git a/arch/arm/plat-s5p/include/plat/reset.h b/arch/arm/plat-samsung/include/plat/reset.h
index 335e97812eed..32ca5179c6e1 100644
--- a/arch/arm/plat-s5p/include/plat/reset.h
+++ b/arch/arm/plat-samsung/include/plat/reset.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/reset.h 1/* linux/arch/arm/plat-samsung/include/plat/reset.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
@@ -8,9 +8,9 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9*/ 9*/
10 10
11#ifndef __ASM_PLAT_S5P_RESET_H 11#ifndef __PLAT_SAMSUNG_RESET_H
12#define __ASM_PLAT_S5P_RESET_H __FILE__ 12#define __PLAT_SAMSUNG_RESET_H __FILE__
13 13
14extern void (*s5p_reset_hook)(void); 14extern void (*s5p_reset_hook)(void);
15 15
16#endif /* __ASM_PLAT_S5P_RESET_H */ 16#endif /* __PLAT_SAMSUNG_RESET_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
deleted file mode 100644
index bf5e2a9d408d..000000000000
--- a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __S3C_PL330_PDATA_H
13#define __S3C_PL330_PDATA_H
14
15#include <plat/s3c-dma-pl330.h>
16
17/*
18 * Every PL330 DMAC has max 32 peripheral interfaces,
19 * of which some may be not be really used in your
20 * DMAC's configuration.
21 * Populate this array of 32 peri i/fs with relevant
22 * channel IDs for used peri i/f and DMACH_MAX for
23 * those unused.
24 *
25 * The platforms just need to provide this info
26 * to the S3C DMA API driver for PL330.
27 */
28struct s3c_pl330_platdata {
29 enum dma_ch peri[32];
30};
31
32#endif /* __S3C_PL330_PDATA_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h
index 82ab4aad1bbe..3986497dd3f7 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2410.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c2410.h
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2412.h b/arch/arm/plat-samsung/include/plat/s3c2412.h
index bb15d3b68be5..5bcfd143ba16 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2412.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c2412.h
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
index dc3c0907d221..a764f8503f52 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2416.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c2416.h
2 * 2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com> 3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4 * 4 *
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h
index a19715feb798..7fae1a050694 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-samsung/include/plat/s3c2443.h
@@ -1,4 +1,4 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c2443.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -37,10 +37,11 @@ extern int s3c2443_baseclk_add(void);
37struct clk; /* some files don't need clk.h otherwise */ 37struct clk; /* some files don't need clk.h otherwise */
38 38
39typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); 39typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
40typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
41 40
42extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv); 41extern void s3c2443_common_setup_clocks(pll_fn get_mpll);
43extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv); 42extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
43 unsigned int *divs, int nr_divs,
44 int divmask);
44 45
45extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); 46extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
46extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); 47extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-samsung/include/plat/s3c244x.h
index 89e8d0a25f87..ea0c961b7603 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
+++ b/arch/arm/plat-samsung/include/plat/s3c244x.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s3c24xx/include/plat/s3c244x.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c244x.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6400.h b/arch/arm/plat-samsung/include/plat/s3c6400.h
index f86958d05352..37d428aaaebb 100644
--- a/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
+++ b/arch/arm/plat-samsung/include/plat/s3c6400.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c64xx/include/macht/s3c6400.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c6400.h
2 * 2 *
3 * Copyright 2008 Openmoko, Inc. 3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008 Simtec Electronics
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6410.h b/arch/arm/plat-samsung/include/plat/s3c6410.h
index 24f1141ffcb7..20a6675b9d17 100644
--- a/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
+++ b/arch/arm/plat-samsung/include/plat/s3c6410.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c64xx/include/mach/s3c6410.h 1/* linux/arch/arm/plat-samsung/include/plat/s3c6410.h
2 * 2 *
3 * Copyright 2008 Openmoko, Inc. 3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008 Simtec Electronics
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h
index 769b5bdfb046..984bf9e7bc89 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h 1/* linux/arch/arm/plat-samsung/include/plat/s5p-clock.h
2 * 2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h
index 575e88109db8..3a70aebc9205 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-time.h
+++ b/arch/arm/plat-samsung/include/plat/s5p-time.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h 1/* linux/arch/arm/plat-samsung/include/plat/s5p-time.h
2 * 2 *
3 * Copyright 2011 Samsung Electronics Co., Ltd. 3 * Copyright 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-samsung/include/plat/s5p6440.h
index 528585d2cafc..bf85ebbb4fbc 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6440.h
+++ b/arch/arm/plat-samsung/include/plat/s5p6440.h
@@ -1,4 +1,4 @@
1/* arch/arm/plat-s5p/include/plat/s5p6440.h 1/* linux/arch/arm/plat-samsung/include/plat/s5p6440.h
2 * 2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-samsung/include/plat/s5p6450.h
index 640a41c26be3..da25f9a1c54a 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6450.h
+++ b/arch/arm/plat-samsung/include/plat/s5p6450.h
@@ -1,4 +1,4 @@
1/* arch/arm/plat-s5p/include/plat/s5p6450.h 1/* linux/arch/arm/plat-samsung/include/plat/s5p6450.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-samsung/include/plat/s5pc100.h
index 5f6099dd7cad..9a21aeaaf452 100644
--- a/arch/arm/plat-s5p/include/plat/s5pc100.h
+++ b/arch/arm/plat-samsung/include/plat/s5pc100.h
@@ -1,4 +1,4 @@
1/* arch/arm/plat-s5p/include/plat/s5pc100.h 1/* linux/arch/arm/plat-samsung/include/plat/s5pc100.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-samsung/include/plat/s5pv210.h
index 6c93a0c78100..b4bc6be77072 100644
--- a/arch/arm/plat-s5p/include/plat/s5pv210.h
+++ b/arch/arm/plat-samsung/include/plat/s5pv210.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h 1/* linux/arch/arm/plat-samsung/include/plat/s5pv210.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 4a6552066c7e..e7b3c752e919 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -55,10 +55,6 @@ enum clk_types {
55 * cd_type == S3C_SDHCI_CD_GPIO 55 * cd_type == S3C_SDHCI_CD_GPIO
56 * @ext_cd_gpio_invert: invert values for external CD gpio line 56 * @ext_cd_gpio_invert: invert values for external CD gpio line
57 * @cfg_gpio: Configure the GPIO for a specific card bit-width 57 * @cfg_gpio: Configure the GPIO for a specific card bit-width
58 * @cfg_card: Configure the interface for a specific card and speed. This
59 * is necessary the controllers and/or GPIO blocks require the
60 * changing of driver-strength and other controls dependent on
61 * the card and speed of operation.
62 * 58 *
63 * Initialisation data specific to either the machine or the platform 59 * Initialisation data specific to either the machine or the platform
64 * for the device driver to use or call-back when configuring gpio or 60 * for the device driver to use or call-back when configuring gpio or
@@ -80,10 +76,6 @@ struct s3c_sdhci_platdata {
80 int state)); 76 int state));
81 77
82 void (*cfg_gpio)(struct platform_device *dev, int width); 78 void (*cfg_gpio)(struct platform_device *dev, int width);
83 void (*cfg_card)(struct platform_device *dev,
84 void __iomem *regbase,
85 struct mmc_ios *ios,
86 struct mmc_card *card);
87}; 79};
88 80
89/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data 81/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data
@@ -139,17 +131,11 @@ extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
139#ifdef CONFIG_S3C2416_SETUP_SDHCI 131#ifdef CONFIG_S3C2416_SETUP_SDHCI
140extern char *s3c2416_hsmmc_clksrcs[4]; 132extern char *s3c2416_hsmmc_clksrcs[4];
141 133
142extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
143 void __iomem *r,
144 struct mmc_ios *ios,
145 struct mmc_card *card);
146
147static inline void s3c2416_default_sdhci0(void) 134static inline void s3c2416_default_sdhci0(void)
148{ 135{
149#ifdef CONFIG_S3C_DEV_HSMMC 136#ifdef CONFIG_S3C_DEV_HSMMC
150 s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs; 137 s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
151 s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; 138 s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
152 s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
153#endif /* CONFIG_S3C_DEV_HSMMC */ 139#endif /* CONFIG_S3C_DEV_HSMMC */
154} 140}
155 141
@@ -158,7 +144,6 @@ static inline void s3c2416_default_sdhci1(void)
158#ifdef CONFIG_S3C_DEV_HSMMC1 144#ifdef CONFIG_S3C_DEV_HSMMC1
159 s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs; 145 s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
160 s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; 146 s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
161 s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
162#endif /* CONFIG_S3C_DEV_HSMMC1 */ 147#endif /* CONFIG_S3C_DEV_HSMMC1 */
163} 148}
164 149
@@ -172,17 +157,11 @@ static inline void s3c2416_default_sdhci1(void) { }
172#ifdef CONFIG_S3C64XX_SETUP_SDHCI 157#ifdef CONFIG_S3C64XX_SETUP_SDHCI
173extern char *s3c64xx_hsmmc_clksrcs[4]; 158extern char *s3c64xx_hsmmc_clksrcs[4];
174 159
175extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
176 void __iomem *r,
177 struct mmc_ios *ios,
178 struct mmc_card *card);
179
180static inline void s3c6400_default_sdhci0(void) 160static inline void s3c6400_default_sdhci0(void)
181{ 161{
182#ifdef CONFIG_S3C_DEV_HSMMC 162#ifdef CONFIG_S3C_DEV_HSMMC
183 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 163 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
184 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 164 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
185 s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
186#endif 165#endif
187} 166}
188 167
@@ -191,7 +170,6 @@ static inline void s3c6400_default_sdhci1(void)
191#ifdef CONFIG_S3C_DEV_HSMMC1 170#ifdef CONFIG_S3C_DEV_HSMMC1
192 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 171 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
193 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 172 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
194 s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
195#endif 173#endif
196} 174}
197 175
@@ -200,21 +178,14 @@ static inline void s3c6400_default_sdhci2(void)
200#ifdef CONFIG_S3C_DEV_HSMMC2 178#ifdef CONFIG_S3C_DEV_HSMMC2
201 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 179 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
202 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 180 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
203 s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
204#endif 181#endif
205} 182}
206 183
207extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
208 void __iomem *r,
209 struct mmc_ios *ios,
210 struct mmc_card *card);
211
212static inline void s3c6410_default_sdhci0(void) 184static inline void s3c6410_default_sdhci0(void)
213{ 185{
214#ifdef CONFIG_S3C_DEV_HSMMC 186#ifdef CONFIG_S3C_DEV_HSMMC
215 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 187 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
216 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 188 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
217 s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
218#endif 189#endif
219} 190}
220 191
@@ -223,7 +194,6 @@ static inline void s3c6410_default_sdhci1(void)
223#ifdef CONFIG_S3C_DEV_HSMMC1 194#ifdef CONFIG_S3C_DEV_HSMMC1
224 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 195 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
225 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 196 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
226 s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
227#endif 197#endif
228} 198}
229 199
@@ -232,7 +202,6 @@ static inline void s3c6410_default_sdhci2(void)
232#ifdef CONFIG_S3C_DEV_HSMMC2 202#ifdef CONFIG_S3C_DEV_HSMMC2
233 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 203 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
234 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 204 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
235 s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
236#endif 205#endif
237} 206}
238 207
@@ -251,17 +220,11 @@ static inline void s3c6400_default_sdhci2(void) { }
251#ifdef CONFIG_S5PC100_SETUP_SDHCI 220#ifdef CONFIG_S5PC100_SETUP_SDHCI
252extern char *s5pc100_hsmmc_clksrcs[4]; 221extern char *s5pc100_hsmmc_clksrcs[4];
253 222
254extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
255 void __iomem *r,
256 struct mmc_ios *ios,
257 struct mmc_card *card);
258
259static inline void s5pc100_default_sdhci0(void) 223static inline void s5pc100_default_sdhci0(void)
260{ 224{
261#ifdef CONFIG_S3C_DEV_HSMMC 225#ifdef CONFIG_S3C_DEV_HSMMC
262 s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 226 s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
263 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio; 227 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
264 s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
265#endif 228#endif
266} 229}
267 230
@@ -270,7 +233,6 @@ static inline void s5pc100_default_sdhci1(void)
270#ifdef CONFIG_S3C_DEV_HSMMC1 233#ifdef CONFIG_S3C_DEV_HSMMC1
271 s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 234 s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
272 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio; 235 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
273 s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
274#endif 236#endif
275} 237}
276 238
@@ -279,7 +241,6 @@ static inline void s5pc100_default_sdhci2(void)
279#ifdef CONFIG_S3C_DEV_HSMMC2 241#ifdef CONFIG_S3C_DEV_HSMMC2
280 s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 242 s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
281 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio; 243 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
282 s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
283#endif 244#endif
284} 245}
285 246
@@ -295,17 +256,11 @@ static inline void s5pc100_default_sdhci2(void) { }
295#ifdef CONFIG_S5PV210_SETUP_SDHCI 256#ifdef CONFIG_S5PV210_SETUP_SDHCI
296extern char *s5pv210_hsmmc_clksrcs[4]; 257extern char *s5pv210_hsmmc_clksrcs[4];
297 258
298extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
299 void __iomem *r,
300 struct mmc_ios *ios,
301 struct mmc_card *card);
302
303static inline void s5pv210_default_sdhci0(void) 259static inline void s5pv210_default_sdhci0(void)
304{ 260{
305#ifdef CONFIG_S3C_DEV_HSMMC 261#ifdef CONFIG_S3C_DEV_HSMMC
306 s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 262 s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
307 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio; 263 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
308 s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
309#endif 264#endif
310} 265}
311 266
@@ -314,7 +269,6 @@ static inline void s5pv210_default_sdhci1(void)
314#ifdef CONFIG_S3C_DEV_HSMMC1 269#ifdef CONFIG_S3C_DEV_HSMMC1
315 s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 270 s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
316 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio; 271 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
317 s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
318#endif 272#endif
319} 273}
320 274
@@ -323,7 +277,6 @@ static inline void s5pv210_default_sdhci2(void)
323#ifdef CONFIG_S3C_DEV_HSMMC2 277#ifdef CONFIG_S3C_DEV_HSMMC2
324 s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 278 s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
325 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio; 279 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
326 s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
327#endif 280#endif
328} 281}
329 282
@@ -332,7 +285,6 @@ static inline void s5pv210_default_sdhci3(void)
332#ifdef CONFIG_S3C_DEV_HSMMC3 285#ifdef CONFIG_S3C_DEV_HSMMC3
333 s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 286 s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
334 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio; 287 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
335 s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
336#endif 288#endif
337} 289}
338 290
@@ -348,17 +300,11 @@ static inline void s5pv210_default_sdhci3(void) { }
348#ifdef CONFIG_EXYNOS4_SETUP_SDHCI 300#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
349extern char *exynos4_hsmmc_clksrcs[4]; 301extern char *exynos4_hsmmc_clksrcs[4];
350 302
351extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev,
352 void __iomem *r,
353 struct mmc_ios *ios,
354 struct mmc_card *card);
355
356static inline void exynos4_default_sdhci0(void) 303static inline void exynos4_default_sdhci0(void)
357{ 304{
358#ifdef CONFIG_S3C_DEV_HSMMC 305#ifdef CONFIG_S3C_DEV_HSMMC
359 s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs; 306 s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
360 s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio; 307 s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio;
361 s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
362#endif 308#endif
363} 309}
364 310
@@ -367,7 +313,6 @@ static inline void exynos4_default_sdhci1(void)
367#ifdef CONFIG_S3C_DEV_HSMMC1 313#ifdef CONFIG_S3C_DEV_HSMMC1
368 s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs; 314 s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
369 s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio; 315 s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio;
370 s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
371#endif 316#endif
372} 317}
373 318
@@ -376,7 +321,6 @@ static inline void exynos4_default_sdhci2(void)
376#ifdef CONFIG_S3C_DEV_HSMMC2 321#ifdef CONFIG_S3C_DEV_HSMMC2
377 s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs; 322 s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
378 s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio; 323 s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio;
379 s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
380#endif 324#endif
381} 325}
382 326
@@ -385,7 +329,6 @@ static inline void exynos4_default_sdhci3(void)
385#ifdef CONFIG_S3C_DEV_HSMMC3 329#ifdef CONFIG_S3C_DEV_HSMMC3
386 s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs; 330 s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
387 s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio; 331 s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio;
388 s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
389#endif 332#endif
390} 333}
391 334
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
index bf5283c2a19d..5fe8ee01a5ba 100644
--- a/arch/arm/plat-s5p/include/plat/sysmmu.h
+++ b/arch/arm/plat-samsung/include/plat/sysmmu.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h 1/* linux/arch/arm/plat-samsung/include/plat/sysmmu.h
2 * 2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
@@ -10,8 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#ifndef __ASM__PLAT_SYSMMU_H 13#ifndef __PLAT_SAMSUNG_SYSMMU_H
14#define __ASM__PLAT_SYSMMU_H __FILE__ 14#define __PLAT_SAMSUNG_SYSMMU_H __FILE__
15 15
16enum S5P_SYSMMU_INTERRUPT_TYPE { 16enum S5P_SYSMMU_INTERRUPT_TYPE {
17 SYSMMU_PAGEFAULT, 17 SYSMMU_PAGEFAULT,
diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-samsung/include/plat/system-reset.h
index f307f34e6422..a448e990964d 100644
--- a/arch/arm/plat-s5p/include/plat/system-reset.h
+++ b/arch/arm/plat-samsung/include/plat/system-reset.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/plat-s5p/include/plat/system-reset.h 1/* linux/arch/arm/plat-samsung/include/plat/system-reset.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
diff --git a/arch/arm/plat-samsung/include/plat/tv-core.h b/arch/arm/plat-samsung/include/plat/tv-core.h
new file mode 100644
index 000000000000..3bc34f3ce28f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/tv-core.h
@@ -0,0 +1,44 @@
1/*
2 * arch/arm/plat-samsung/include/plat/tv.h
3 *
4 * Copyright 2011 Samsung Electronics Co., Ltd.
5 * Tomasz Stanislawski <t.stanislaws@samsung.com>
6 *
7 * Samsung TV driver core functions
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef __SAMSUNG_PLAT_TV_H
15#define __SAMSUNG_PLAT_TV_H __FILE__
16
17/*
18 * These functions are only for use with the core support code, such as
19 * the CPU-specific initialization code.
20 */
21
22/* Re-define device name to differentiate the subsystem in various SoCs. */
23static inline void s5p_hdmi_setname(char *name)
24{
25#ifdef CONFIG_S5P_DEV_TV
26 s5p_device_hdmi.name = name;
27#endif
28}
29
30static inline void s5p_mixer_setname(char *name)
31{
32#ifdef CONFIG_S5P_DEV_TV
33 s5p_device_mixer.name = name;
34#endif
35}
36
37static inline void s5p_sdo_setname(char *name)
38{
39#ifdef CONFIG_S5P_DEV_TV
40 s5p_device_sdo.name = name;
41#endif
42}
43
44#endif /* __SAMSUNG_PLAT_TV_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-samsung/include/plat/udc.h
index f63884242506..8c22d586befb 100644
--- a/arch/arm/plat-s3c24xx/include/plat/udc.h
+++ b/arch/arm/plat-samsung/include/plat/udc.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/include/mach/udc.h 1/* arch/arm/plat-samsung/include/plat/udc.h
2 * 2 *
3 * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org> 3 * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
4 * 4 *
@@ -26,7 +26,7 @@ enum s3c2410_udc_cmd_e {
26 26
27struct s3c2410_udc_mach_info { 27struct s3c2410_udc_mach_info {
28 void (*udc_command)(enum s3c2410_udc_cmd_e); 28 void (*udc_command)(enum s3c2410_udc_cmd_e);
29 void (*vbus_draw)(unsigned int ma); 29 void (*vbus_draw)(unsigned int ma);
30 30
31 unsigned int pullup_pin; 31 unsigned int pullup_pin;
32 unsigned int pullup_pin_inverted; 32 unsigned int pullup_pin_inverted;
diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
index 6dd6bcfca3ce..959bcdb03a25 100644
--- a/arch/arm/plat-s5p/include/plat/usb-phy.h
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -8,8 +8,8 @@
8 * option) any later version. 8 * option) any later version.
9 */ 9 */
10 10
11#ifndef __PLAT_S5P_USB_PHY_H 11#ifndef __PLAT_SAMSUNG_USB_PHY_H
12#define __PLAT_S5P_USB_PHY_H 12#define __PLAT_SAMSUNG_USB_PHY_H __FILE__
13 13
14enum s5p_usb_phy_type { 14enum s5p_usb_phy_type {
15 S5P_USB_PHY_DEVICE, 15 S5P_USB_PHY_DEVICE,
@@ -19,4 +19,4 @@ enum s5p_usb_phy_type {
19extern int s5p_usb_phy_init(struct platform_device *pdev, int type); 19extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
20extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); 20extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
21 21
22#endif /* __PLAT_S5P_REGS_USB_PHY_H */ 22#endif /* __PLAT_SAMSUNG_USB_PHY_H */
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
index 6de1a3825927..4c9a20734fe3 100644
--- a/arch/arm/plat-samsung/platformdata.c
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -50,8 +50,6 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
50 set->max_width = pd->max_width; 50 set->max_width = pd->max_width;
51 if (pd->cfg_gpio) 51 if (pd->cfg_gpio)
52 set->cfg_gpio = pd->cfg_gpio; 52 set->cfg_gpio = pd->cfg_gpio;
53 if (pd->cfg_card)
54 set->cfg_card = pd->cfg_card;
55 if (pd->host_caps) 53 if (pd->host_caps)
56 set->host_caps |= pd->host_caps; 54 set->host_caps |= pd->host_caps;
57 if (pd->clk_type) 55 if (pd->clk_type)
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 96528200eb79..4be016eaa6db 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -28,13 +28,13 @@
28#define OFFS_DAT (0x04) 28#define OFFS_DAT (0x04)
29#define OFFS_UP (0x08) 29#define OFFS_UP (0x08)
30 30
31static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip) 31static void samsung_gpio_pm_1bit_save(struct samsung_gpio_chip *chip)
32{ 32{
33 chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); 33 chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
34 chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); 34 chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
35} 35}
36 36
37static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip) 37static void samsung_gpio_pm_1bit_resume(struct samsung_gpio_chip *chip)
38{ 38{
39 void __iomem *base = chip->base; 39 void __iomem *base = chip->base;
40 u32 old_gpcon = __raw_readl(base + OFFS_CON); 40 u32 old_gpcon = __raw_readl(base + OFFS_CON);
@@ -60,12 +60,12 @@ static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
60 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); 60 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
61} 61}
62 62
63struct s3c_gpio_pm s3c_gpio_pm_1bit = { 63struct samsung_gpio_pm samsung_gpio_pm_1bit = {
64 .save = s3c_gpio_pm_1bit_save, 64 .save = samsung_gpio_pm_1bit_save,
65 .resume = s3c_gpio_pm_1bit_resume, 65 .resume = samsung_gpio_pm_1bit_resume,
66}; 66};
67 67
68static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip) 68static void samsung_gpio_pm_2bit_save(struct samsung_gpio_chip *chip)
69{ 69{
70 chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); 70 chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
71 chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); 71 chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
@@ -95,7 +95,7 @@ static inline int is_out(unsigned long con)
95} 95}
96 96
97/** 97/**
98 * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank 98 * samsung_gpio_pm_2bit_resume() - restore the given GPIO bank
99 * @chip: The chip information to resume. 99 * @chip: The chip information to resume.
100 * 100 *
101 * Restore one of the GPIO banks that was saved during suspend. This is 101 * Restore one of the GPIO banks that was saved during suspend. This is
@@ -121,7 +121,7 @@ static inline int is_out(unsigned long con)
121 * [1] this assumes that writing to a pin DAT whilst in SFN will set the 121 * [1] this assumes that writing to a pin DAT whilst in SFN will set the
122 * state for when it is next output. 122 * state for when it is next output.
123 */ 123 */
124static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip) 124static void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip)
125{ 125{
126 void __iomem *base = chip->base; 126 void __iomem *base = chip->base;
127 u32 old_gpcon = __raw_readl(base + OFFS_CON); 127 u32 old_gpcon = __raw_readl(base + OFFS_CON);
@@ -187,13 +187,13 @@ static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
187 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); 187 chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
188} 188}
189 189
190struct s3c_gpio_pm s3c_gpio_pm_2bit = { 190struct samsung_gpio_pm samsung_gpio_pm_2bit = {
191 .save = s3c_gpio_pm_2bit_save, 191 .save = samsung_gpio_pm_2bit_save,
192 .resume = s3c_gpio_pm_2bit_resume, 192 .resume = samsung_gpio_pm_2bit_resume,
193}; 193};
194 194
195#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) 195#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
196static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) 196static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
197{ 197{
198 chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); 198 chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
199 chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT); 199 chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
@@ -203,7 +203,7 @@ static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
203 chip->pm_save[0] = __raw_readl(chip->base - 4); 203 chip->pm_save[0] = __raw_readl(chip->base - 4);
204} 204}
205 205
206static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) 206static u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
207{ 207{
208 u32 old, new, mask; 208 u32 old, new, mask;
209 u32 change_mask = 0x0; 209 u32 change_mask = 0x0;
@@ -242,14 +242,14 @@ static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
242 return change_mask; 242 return change_mask;
243} 243}
244 244
245static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index) 245static void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index)
246{ 246{
247 void __iomem *con = chip->base + (index * 4); 247 void __iomem *con = chip->base + (index * 4);
248 u32 old_gpcon = __raw_readl(con); 248 u32 old_gpcon = __raw_readl(con);
249 u32 gps_gpcon = chip->pm_save[index + 1]; 249 u32 gps_gpcon = chip->pm_save[index + 1];
250 u32 gpcon, mask; 250 u32 gpcon, mask;
251 251
252 mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon); 252 mask = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
253 253
254 gpcon = old_gpcon & ~mask; 254 gpcon = old_gpcon & ~mask;
255 gpcon |= gps_gpcon & mask; 255 gpcon |= gps_gpcon & mask;
@@ -257,7 +257,7 @@ static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
257 __raw_writel(gpcon, con); 257 __raw_writel(gpcon, con);
258} 258}
259 259
260static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip) 260static void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip)
261{ 261{
262 void __iomem *base = chip->base; 262 void __iomem *base = chip->base;
263 u32 old_gpcon[2]; 263 u32 old_gpcon[2];
@@ -269,10 +269,10 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
269 old_gpcon[0] = 0; 269 old_gpcon[0] = 0;
270 old_gpcon[1] = __raw_readl(base + OFFS_CON); 270 old_gpcon[1] = __raw_readl(base + OFFS_CON);
271 271
272 s3c_gpio_pm_4bit_con(chip, 0); 272 samsung_gpio_pm_4bit_con(chip, 0);
273 if (chip->chip.ngpio > 8) { 273 if (chip->chip.ngpio > 8) {
274 old_gpcon[0] = __raw_readl(base - 4); 274 old_gpcon[0] = __raw_readl(base - 4);
275 s3c_gpio_pm_4bit_con(chip, -1); 275 samsung_gpio_pm_4bit_con(chip, -1);
276 } 276 }
277 277
278 /* Now change the configurations that require DAT,CON */ 278 /* Now change the configurations that require DAT,CON */
@@ -298,19 +298,19 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
298 old_gpdat, gps_gpdat); 298 old_gpdat, gps_gpdat);
299} 299}
300 300
301struct s3c_gpio_pm s3c_gpio_pm_4bit = { 301struct samsung_gpio_pm samsung_gpio_pm_4bit = {
302 .save = s3c_gpio_pm_4bit_save, 302 .save = samsung_gpio_pm_4bit_save,
303 .resume = s3c_gpio_pm_4bit_resume, 303 .resume = samsung_gpio_pm_4bit_resume,
304}; 304};
305#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */ 305#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
306 306
307/** 307/**
308 * s3c_pm_save_gpio() - save gpio chip data for suspend 308 * samsung_pm_save_gpio() - save gpio chip data for suspend
309 * @ourchip: The chip for suspend. 309 * @ourchip: The chip for suspend.
310 */ 310 */
311static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip) 311static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip)
312{ 312{
313 struct s3c_gpio_pm *pm = ourchip->pm; 313 struct samsung_gpio_pm *pm = ourchip->pm;
314 314
315 if (pm == NULL || pm->save == NULL) 315 if (pm == NULL || pm->save == NULL)
316 S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); 316 S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
@@ -319,24 +319,24 @@ static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
319} 319}
320 320
321/** 321/**
322 * s3c_pm_save_gpios() - Save the state of the GPIO banks. 322 * samsung_pm_save_gpios() - Save the state of the GPIO banks.
323 * 323 *
324 * For all the GPIO banks, save the state of each one ready for going 324 * For all the GPIO banks, save the state of each one ready for going
325 * into a suspend mode. 325 * into a suspend mode.
326 */ 326 */
327void s3c_pm_save_gpios(void) 327void samsung_pm_save_gpios(void)
328{ 328{
329 struct s3c_gpio_chip *ourchip; 329 struct samsung_gpio_chip *ourchip;
330 unsigned int gpio_nr; 330 unsigned int gpio_nr;
331 331
332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { 332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
333 ourchip = s3c_gpiolib_getchip(gpio_nr); 333 ourchip = samsung_gpiolib_getchip(gpio_nr);
334 if (!ourchip) { 334 if (!ourchip) {
335 gpio_nr++; 335 gpio_nr++;
336 continue; 336 continue;
337 } 337 }
338 338
339 s3c_pm_save_gpio(ourchip); 339 samsung_pm_save_gpio(ourchip);
340 340
341 S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n", 341 S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
342 ourchip->chip.label, 342 ourchip->chip.label,
@@ -351,12 +351,12 @@ void s3c_pm_save_gpios(void)
351} 351}
352 352
353/** 353/**
354 * s3c_pm_resume_gpio() - restore gpio chip data after suspend 354 * samsung_pm_resume_gpio() - restore gpio chip data after suspend
355 * @ourchip: The suspended chip. 355 * @ourchip: The suspended chip.
356 */ 356 */
357static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip) 357static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip)
358{ 358{
359 struct s3c_gpio_pm *pm = ourchip->pm; 359 struct samsung_gpio_pm *pm = ourchip->pm;
360 360
361 if (pm == NULL || pm->resume == NULL) 361 if (pm == NULL || pm->resume == NULL)
362 S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); 362 S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
@@ -364,19 +364,19 @@ static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
364 pm->resume(ourchip); 364 pm->resume(ourchip);
365} 365}
366 366
367void s3c_pm_restore_gpios(void) 367void samsung_pm_restore_gpios(void)
368{ 368{
369 struct s3c_gpio_chip *ourchip; 369 struct samsung_gpio_chip *ourchip;
370 unsigned int gpio_nr; 370 unsigned int gpio_nr;
371 371
372 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) { 372 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
373 ourchip = s3c_gpiolib_getchip(gpio_nr); 373 ourchip = samsung_gpiolib_getchip(gpio_nr);
374 if (!ourchip) { 374 if (!ourchip) {
375 gpio_nr++; 375 gpio_nr++;
376 continue; 376 continue;
377 } 377 }
378 378
379 s3c_pm_resume_gpio(ourchip); 379 samsung_pm_resume_gpio(ourchip);
380 380
381 gpio_nr += ourchip->chip.ngpio; 381 gpio_nr += ourchip->chip.ngpio;
382 gpio_nr += CONFIG_S3C_GPIO_SPACE; 382 gpio_nr += CONFIG_S3C_GPIO_SPACE;
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index ae6f99834cdd..64ab65f0fdbc 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -268,8 +268,8 @@ static int s3c_pm_enter(suspend_state_t state)
268 268
269 /* save all necessary core registers not covered by the drivers */ 269 /* save all necessary core registers not covered by the drivers */
270 270
271 s3c_pm_save_gpios(); 271 samsung_pm_save_gpios();
272 s3c_pm_saved_gpios(); 272 samsung_pm_saved_gpios();
273 s3c_pm_save_uarts(); 273 s3c_pm_save_uarts();
274 s3c_pm_save_core(); 274 s3c_pm_save_core();
275 275
@@ -306,7 +306,7 @@ static int s3c_pm_enter(suspend_state_t state)
306 306
307 s3c_pm_restore_core(); 307 s3c_pm_restore_core();
308 s3c_pm_restore_uarts(); 308 s3c_pm_restore_uarts();
309 s3c_pm_restore_gpios(); 309 samsung_pm_restore_gpios();
310 s3c_pm_restored_gpios(); 310 s3c_pm_restored_gpios();
311 311
312 s3c_pm_debug_init(); 312 s3c_pm_debug_init();
diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c
index f1bba88ed2f5..a35ff3bcffe4 100644
--- a/arch/arm/plat-samsung/pwm-clock.c
+++ b/arch/arm/plat-samsung/pwm-clock.c
@@ -27,7 +27,7 @@
27#include <plat/cpu.h> 27#include <plat/cpu.h>
28 28
29#include <plat/regs-timer.h> 29#include <plat/regs-timer.h>
30#include <mach/pwm-clock.h> 30#include <plat/pwm-clock.h>
31 31
32/* Each of the timers 0 through 5 go through the following 32/* Each of the timers 0 through 5 go through the following
33 * clock tree, with the inputs depending on the timers. 33 * clock tree, with the inputs depending on the timers.
@@ -339,8 +339,17 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
339 unsigned long bits; 339 unsigned long bits;
340 unsigned long shift = S3C2410_TCFG1_SHIFT(id); 340 unsigned long shift = S3C2410_TCFG1_SHIFT(id);
341 341
342 unsigned long mux_tclk;
343
344 if (soc_is_s3c24xx())
345 mux_tclk = S3C2410_TCFG1_MUX_TCLK;
346 else if (soc_is_s5p6440() || soc_is_s5p6450())
347 mux_tclk = 0;
348 else
349 mux_tclk = S3C64XX_TCFG1_MUX_TCLK;
350
342 if (parent == s3c24xx_pwmclk_tclk(id)) 351 if (parent == s3c24xx_pwmclk_tclk(id))
343 bits = S3C_TCFG1_MUX_TCLK << shift; 352 bits = mux_tclk << shift;
344 else if (parent == s3c24xx_pwmclk_tdiv(id)) 353 else if (parent == s3c24xx_pwmclk_tdiv(id))
345 bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift; 354 bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
346 else 355 else
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index f37457c52064..dc1185dcf80d 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -299,6 +299,9 @@ static int s3c_pwm_probe(struct platform_device *pdev)
299 goto err_clk_tin; 299 goto err_clk_tin;
300 } 300 }
301 301
302 clk_enable(pwm->clk);
303 clk_enable(pwm->clk_div);
304
302 local_irq_save(flags); 305 local_irq_save(flags);
303 306
304 tcon = __raw_readl(S3C2410_TCON); 307 tcon = __raw_readl(S3C2410_TCON);
@@ -326,6 +329,8 @@ static int s3c_pwm_probe(struct platform_device *pdev)
326 return 0; 329 return 0;
327 330
328 err_clk_tdiv: 331 err_clk_tdiv:
332 clk_disable(pwm->clk_div);
333 clk_disable(pwm->clk);
329 clk_put(pwm->clk_div); 334 clk_put(pwm->clk_div);
330 335
331 err_clk_tin: 336 err_clk_tin:
@@ -340,6 +345,8 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev)
340{ 345{
341 struct pwm_device *pwm = platform_get_drvdata(pdev); 346 struct pwm_device *pwm = platform_get_drvdata(pdev);
342 347
348 clk_disable(pwm->clk_div);
349 clk_disable(pwm->clk);
343 clk_put(pwm->clk_div); 350 clk_put(pwm->clk_div);
344 clk_put(pwm->clk); 351 clk_put(pwm->clk);
345 kfree(pwm); 352 kfree(pwm);
diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c
new file mode 100644
index 000000000000..582333c70585
--- /dev/null
+++ b/arch/arm/plat-samsung/s3c-dma-ops.c
@@ -0,0 +1,130 @@
1/* linux/arch/arm/plat-samsung/s3c-dma-ops.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung S3C-DMA Operations
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/slab.h>
16#include <linux/types.h>
17
18#include <mach/dma.h>
19
20struct cb_data {
21 void (*fp) (void *);
22 void *fp_param;
23 unsigned ch;
24 struct list_head node;
25};
26
27static LIST_HEAD(dma_list);
28
29static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
30 int size, enum s3c2410_dma_buffresult res)
31{
32 struct cb_data *data = param;
33
34 data->fp(data->fp_param);
35}
36
37static unsigned s3c_dma_request(enum dma_ch dma_ch,
38 struct samsung_dma_info *info)
39{
40 struct cb_data *data;
41
42 if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) {
43 s3c2410_dma_free(dma_ch, info->client);
44 return 0;
45 }
46
47 data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
48 data->ch = dma_ch;
49 list_add_tail(&data->node, &dma_list);
50
51 s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo);
52
53 if (info->cap == DMA_CYCLIC)
54 s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
55
56 s3c2410_dma_config(dma_ch, info->width);
57
58 return (unsigned)dma_ch;
59}
60
61static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
62{
63 struct cb_data *data;
64
65 list_for_each_entry(data, &dma_list, node)
66 if (data->ch == ch)
67 break;
68 list_del(&data->node);
69
70 s3c2410_dma_free(ch, client);
71 kfree(data);
72
73 return 0;
74}
75
76static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
77{
78 struct cb_data *data;
79 int len = (info->cap == DMA_CYCLIC) ? info->period : info->len;
80
81 list_for_each_entry(data, &dma_list, node)
82 if (data->ch == ch)
83 break;
84
85 if (!data->fp) {
86 s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
87 data->fp = info->fp;
88 data->fp_param = info->fp_param;
89 }
90
91 s3c2410_dma_enqueue(ch, (void *)data, info->buf, len);
92
93 return 0;
94}
95
96static inline int s3c_dma_trigger(unsigned ch)
97{
98 return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START);
99}
100
101static inline int s3c_dma_started(unsigned ch)
102{
103 return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED);
104}
105
106static inline int s3c_dma_flush(unsigned ch)
107{
108 return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH);
109}
110
111static inline int s3c_dma_stop(unsigned ch)
112{
113 return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP);
114}
115
116static struct samsung_dma_ops s3c_dma_ops = {
117 .request = s3c_dma_request,
118 .release = s3c_dma_release,
119 .prepare = s3c_dma_prepare,
120 .trigger = s3c_dma_trigger,
121 .started = s3c_dma_started,
122 .flush = s3c_dma_flush,
123 .stop = s3c_dma_stop,
124};
125
126void *s3c_dma_get_ops(void)
127{
128 return &s3c_dma_ops;
129}
130EXPORT_SYMBOL(s3c_dma_get_ops);
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
deleted file mode 100644
index f85638c6f5ae..000000000000
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ /dev/null
@@ -1,1244 +0,0 @@
1/* linux/arch/arm/plat-samsung/s3c-pl330.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <asm/hardware/pl330.h>
22
23#include <plat/s3c-pl330-pdata.h>
24
25/**
26 * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
27 * @busy_chan: Number of channels currently busy.
28 * @peri: List of IDs of peripherals this DMAC can work with.
29 * @node: To attach to the global list of DMACs.
30 * @pi: PL330 configuration info for the DMAC.
31 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
32 * @clk: Pointer of DMAC operation clock.
33 */
34struct s3c_pl330_dmac {
35 unsigned busy_chan;
36 enum dma_ch *peri;
37 struct list_head node;
38 struct pl330_info *pi;
39 struct kmem_cache *kmcache;
40 struct clk *clk;
41};
42
43/**
44 * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
45 * @token: Xfer ID provided by the client.
46 * @node: To attach to the list of xfers on a channel.
47 * @px: Xfer for PL330 core.
48 * @chan: Owner channel of this xfer.
49 */
50struct s3c_pl330_xfer {
51 void *token;
52 struct list_head node;
53 struct pl330_xfer px;
54 struct s3c_pl330_chan *chan;
55};
56
57/**
58 * struct s3c_pl330_chan - Logical channel to communicate with
59 * a Physical peripheral.
60 * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
61 * NULL if the channel is available to be acquired.
62 * @id: ID of the peripheral that this channel can communicate with.
63 * @options: Options specified by the client.
64 * @sdaddr: Address provided via s3c2410_dma_devconfig.
65 * @node: To attach to the global list of channels.
66 * @lrq: Pointer to the last submitted pl330_req to PL330 core.
67 * @xfer_list: To manage list of xfers enqueued.
68 * @req: Two requests to communicate with the PL330 engine.
69 * @callback_fn: Callback function to the client.
70 * @rqcfg: Channel configuration for the xfers.
71 * @xfer_head: Pointer to the xfer to be next executed.
72 * @dmac: Pointer to the DMAC that manages this channel, NULL if the
73 * channel is available to be acquired.
74 * @client: Client of this channel. NULL if the
75 * channel is available to be acquired.
76 */
77struct s3c_pl330_chan {
78 void *pl330_chan_id;
79 enum dma_ch id;
80 unsigned int options;
81 unsigned long sdaddr;
82 struct list_head node;
83 struct pl330_req *lrq;
84 struct list_head xfer_list;
85 struct pl330_req req[2];
86 s3c2410_dma_cbfn_t callback_fn;
87 struct pl330_reqcfg rqcfg;
88 struct s3c_pl330_xfer *xfer_head;
89 struct s3c_pl330_dmac *dmac;
90 struct s3c2410_dma_client *client;
91};
92
93/* All DMACs in the platform */
94static LIST_HEAD(dmac_list);
95
96/* All channels to peripherals in the platform */
97static LIST_HEAD(chan_list);
98
99/*
100 * Since we add resources(DMACs and Channels) to the global pool,
101 * we need to guard access to the resources using a global lock
102 */
103static DEFINE_SPINLOCK(res_lock);
104
105/* Returns the channel with ID 'id' in the chan_list */
106static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
107{
108 struct s3c_pl330_chan *ch;
109
110 list_for_each_entry(ch, &chan_list, node)
111 if (ch->id == id)
112 return ch;
113
114 return NULL;
115}
116
117/* Allocate a new channel with ID 'id' and add to chan_list */
118static void chan_add(const enum dma_ch id)
119{
120 struct s3c_pl330_chan *ch = id_to_chan(id);
121
122 /* Return if the channel already exists */
123 if (ch)
124 return;
125
126 ch = kmalloc(sizeof(*ch), GFP_KERNEL);
127 /* Return silently to work with other channels */
128 if (!ch)
129 return;
130
131 ch->id = id;
132 ch->dmac = NULL;
133
134 list_add_tail(&ch->node, &chan_list);
135}
136
137/* If the channel is not yet acquired by any client */
138static bool chan_free(struct s3c_pl330_chan *ch)
139{
140 if (!ch)
141 return false;
142
143 /* Channel points to some DMAC only when it's acquired */
144 return ch->dmac ? false : true;
145}
146
147/*
148 * Returns 0 is peripheral i/f is invalid or not present on the dmac.
149 * Index + 1, otherwise.
150 */
151static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
152{
153 enum dma_ch *id = dmac->peri;
154 int i;
155
156 /* Discount invalid markers */
157 if (ch_id == DMACH_MAX)
158 return 0;
159
160 for (i = 0; i < PL330_MAX_PERI; i++)
161 if (id[i] == ch_id)
162 return i + 1;
163
164 return 0;
165}
166
167/* If all channel threads of the DMAC are busy */
168static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
169{
170 struct pl330_info *pi = dmac->pi;
171
172 return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
173}
174
175/*
176 * Returns the number of free channels that
177 * can be handled by this dmac only.
178 */
179static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
180{
181 enum dma_ch *id = dmac->peri;
182 struct s3c_pl330_dmac *d;
183 struct s3c_pl330_chan *ch;
184 unsigned found, count = 0;
185 enum dma_ch p;
186 int i;
187
188 for (i = 0; i < PL330_MAX_PERI; i++) {
189 p = id[i];
190 ch = id_to_chan(p);
191
192 if (p == DMACH_MAX || !chan_free(ch))
193 continue;
194
195 found = 0;
196 list_for_each_entry(d, &dmac_list, node) {
197 if (d != dmac && iface_of_dmac(d, ch->id)) {
198 found = 1;
199 break;
200 }
201 }
202 if (!found)
203 count++;
204 }
205
206 return count;
207}
208
209/*
210 * Measure of suitability of 'dmac' handling 'ch'
211 *
212 * 0 indicates 'dmac' can not handle 'ch' either
213 * because it is not supported by the hardware or
214 * because all dmac channels are currently busy.
215 *
216 * >0 vlaue indicates 'dmac' has the capability.
217 * The bigger the value the more suitable the dmac.
218 */
219#define MAX_SUIT UINT_MAX
220#define MIN_SUIT 0
221
222static unsigned suitablility(struct s3c_pl330_dmac *dmac,
223 struct s3c_pl330_chan *ch)
224{
225 struct pl330_info *pi = dmac->pi;
226 enum dma_ch *id = dmac->peri;
227 struct s3c_pl330_dmac *d;
228 unsigned s;
229 int i;
230
231 s = MIN_SUIT;
232 /* If all the DMAC channel threads are busy */
233 if (dmac_busy(dmac))
234 return s;
235
236 for (i = 0; i < PL330_MAX_PERI; i++)
237 if (id[i] == ch->id)
238 break;
239
240 /* If the 'dmac' can't talk to 'ch' */
241 if (i == PL330_MAX_PERI)
242 return s;
243
244 s = MAX_SUIT;
245 list_for_each_entry(d, &dmac_list, node) {
246 /*
247 * If some other dmac can talk to this
248 * peri and has some channel free.
249 */
250 if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
251 s = 0;
252 break;
253 }
254 }
255 if (s)
256 return s;
257
258 s = 100;
259
260 /* Good if free chans are more, bad otherwise */
261 s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
262
263 return s;
264}
265
266/* More than one DMAC may have capability to transfer data with the
267 * peripheral. This function assigns most suitable DMAC to manage the
268 * channel and hence communicate with the peripheral.
269 */
270static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
271{
272 struct s3c_pl330_dmac *d, *dmac = NULL;
273 unsigned sn, sl = MIN_SUIT;
274
275 list_for_each_entry(d, &dmac_list, node) {
276 sn = suitablility(d, ch);
277
278 if (sn == MAX_SUIT)
279 return d;
280
281 if (sn > sl)
282 dmac = d;
283 }
284
285 return dmac;
286}
287
288/* Acquire the channel for peripheral 'id' */
289static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
290{
291 struct s3c_pl330_chan *ch = id_to_chan(id);
292 struct s3c_pl330_dmac *dmac;
293
294 /* If the channel doesn't exist or is already acquired */
295 if (!ch || !chan_free(ch)) {
296 ch = NULL;
297 goto acq_exit;
298 }
299
300 dmac = map_chan_to_dmac(ch);
301 /* If couldn't map */
302 if (!dmac) {
303 ch = NULL;
304 goto acq_exit;
305 }
306
307 dmac->busy_chan++;
308 ch->dmac = dmac;
309
310acq_exit:
311 return ch;
312}
313
314/* Delete xfer from the queue */
315static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
316{
317 struct s3c_pl330_xfer *t;
318 struct s3c_pl330_chan *ch;
319 int found;
320
321 if (!xfer)
322 return;
323
324 ch = xfer->chan;
325
326 /* Make sure xfer is in the queue */
327 found = 0;
328 list_for_each_entry(t, &ch->xfer_list, node)
329 if (t == xfer) {
330 found = 1;
331 break;
332 }
333
334 if (!found)
335 return;
336
337 /* If xfer is last entry in the queue */
338 if (xfer->node.next == &ch->xfer_list)
339 t = list_entry(ch->xfer_list.next,
340 struct s3c_pl330_xfer, node);
341 else
342 t = list_entry(xfer->node.next,
343 struct s3c_pl330_xfer, node);
344
345 /* If there was only one node left */
346 if (t == xfer)
347 ch->xfer_head = NULL;
348 else if (ch->xfer_head == xfer)
349 ch->xfer_head = t;
350
351 list_del(&xfer->node);
352}
353
354/* Provides pointer to the next xfer in the queue.
355 * If CIRCULAR option is set, the list is left intact,
356 * otherwise the xfer is removed from the list.
357 * Forced delete 'pluck' can be set to override the CIRCULAR option.
358 */
359static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
360 int pluck)
361{
362 struct s3c_pl330_xfer *xfer = ch->xfer_head;
363
364 if (!xfer)
365 return NULL;
366
367 /* If xfer is last entry in the queue */
368 if (xfer->node.next == &ch->xfer_list)
369 ch->xfer_head = list_entry(ch->xfer_list.next,
370 struct s3c_pl330_xfer, node);
371 else
372 ch->xfer_head = list_entry(xfer->node.next,
373 struct s3c_pl330_xfer, node);
374
375 if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
376 del_from_queue(xfer);
377
378 return xfer;
379}
380
381static inline void add_to_queue(struct s3c_pl330_chan *ch,
382 struct s3c_pl330_xfer *xfer, int front)
383{
384 struct pl330_xfer *xt;
385
386 /* If queue empty */
387 if (ch->xfer_head == NULL)
388 ch->xfer_head = xfer;
389
390 xt = &ch->xfer_head->px;
391 /* If the head already submitted (CIRCULAR head) */
392 if (ch->options & S3C2410_DMAF_CIRCULAR &&
393 (xt == ch->req[0].x || xt == ch->req[1].x))
394 ch->xfer_head = xfer;
395
396 /* If this is a resubmission, it should go at the head */
397 if (front) {
398 ch->xfer_head = xfer;
399 list_add(&xfer->node, &ch->xfer_list);
400 } else {
401 list_add_tail(&xfer->node, &ch->xfer_list);
402 }
403}
404
405static inline void _finish_off(struct s3c_pl330_xfer *xfer,
406 enum s3c2410_dma_buffresult res, int ffree)
407{
408 struct s3c_pl330_chan *ch;
409
410 if (!xfer)
411 return;
412
413 ch = xfer->chan;
414
415 /* Do callback */
416 if (ch->callback_fn)
417 ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
418
419 /* Force Free or if buffer is not needed anymore */
420 if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
421 kmem_cache_free(ch->dmac->kmcache, xfer);
422}
423
424static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
425 struct pl330_req *r)
426{
427 struct s3c_pl330_xfer *xfer;
428 int ret = 0;
429
430 /* If already submitted */
431 if (r->x)
432 return 0;
433
434 xfer = get_from_queue(ch, 0);
435 if (xfer) {
436 r->x = &xfer->px;
437
438 /* Use max bandwidth for M<->M xfers */
439 if (r->rqtype == MEMTOMEM) {
440 struct pl330_info *pi = xfer->chan->dmac->pi;
441 int burst = 1 << ch->rqcfg.brst_size;
442 u32 bytes = r->x->bytes;
443 int bl;
444
445 bl = pi->pcfg.data_bus_width / 8;
446 bl *= pi->pcfg.data_buf_dep;
447 bl /= burst;
448
449 /* src/dst_burst_len can't be more than 16 */
450 if (bl > 16)
451 bl = 16;
452
453 while (bl > 1) {
454 if (!(bytes % (bl * burst)))
455 break;
456 bl--;
457 }
458
459 ch->rqcfg.brst_len = bl;
460 } else {
461 ch->rqcfg.brst_len = 1;
462 }
463
464 ret = pl330_submit_req(ch->pl330_chan_id, r);
465
466 /* If submission was successful */
467 if (!ret) {
468 ch->lrq = r; /* latest submitted req */
469 return 0;
470 }
471
472 r->x = NULL;
473
474 /* If both of the PL330 ping-pong buffers filled */
475 if (ret == -EAGAIN) {
476 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
477 __func__, __LINE__);
478 /* Queue back again */
479 add_to_queue(ch, xfer, 1);
480 ret = 0;
481 } else {
482 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
483 __func__, __LINE__);
484 _finish_off(xfer, S3C2410_RES_ERR, 0);
485 }
486 }
487
488 return ret;
489}
490
491static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
492 struct pl330_req *r, enum pl330_op_err err)
493{
494 unsigned long flags;
495 struct s3c_pl330_xfer *xfer;
496 struct pl330_xfer *xl = r->x;
497 enum s3c2410_dma_buffresult res;
498
499 spin_lock_irqsave(&res_lock, flags);
500
501 r->x = NULL;
502
503 s3c_pl330_submit(ch, r);
504
505 spin_unlock_irqrestore(&res_lock, flags);
506
507 /* Map result to S3C DMA API */
508 if (err == PL330_ERR_NONE)
509 res = S3C2410_RES_OK;
510 else if (err == PL330_ERR_ABORT)
511 res = S3C2410_RES_ABORT;
512 else
513 res = S3C2410_RES_ERR;
514
515 /* If last request had some xfer */
516 if (xl) {
517 xfer = container_of(xl, struct s3c_pl330_xfer, px);
518 _finish_off(xfer, res, 0);
519 } else {
520 dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
521 __func__, __LINE__);
522 }
523}
524
525static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
526{
527 struct pl330_req *r = token;
528 struct s3c_pl330_chan *ch = container_of(r,
529 struct s3c_pl330_chan, req[0]);
530 s3c_pl330_rq(ch, r, err);
531}
532
533static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
534{
535 struct pl330_req *r = token;
536 struct s3c_pl330_chan *ch = container_of(r,
537 struct s3c_pl330_chan, req[1]);
538 s3c_pl330_rq(ch, r, err);
539}
540
541/* Release an acquired channel */
542static void chan_release(struct s3c_pl330_chan *ch)
543{
544 struct s3c_pl330_dmac *dmac;
545
546 if (chan_free(ch))
547 return;
548
549 dmac = ch->dmac;
550 ch->dmac = NULL;
551 dmac->busy_chan--;
552}
553
554int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
555{
556 struct s3c_pl330_xfer *xfer;
557 enum pl330_chan_op pl330op;
558 struct s3c_pl330_chan *ch;
559 unsigned long flags;
560 int idx, ret;
561
562 spin_lock_irqsave(&res_lock, flags);
563
564 ch = id_to_chan(id);
565
566 if (!ch || chan_free(ch)) {
567 ret = -EINVAL;
568 goto ctrl_exit;
569 }
570
571 switch (op) {
572 case S3C2410_DMAOP_START:
573 /* Make sure both reqs are enqueued */
574 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
575 s3c_pl330_submit(ch, &ch->req[idx]);
576 s3c_pl330_submit(ch, &ch->req[1 - idx]);
577 pl330op = PL330_OP_START;
578 break;
579
580 case S3C2410_DMAOP_STOP:
581 pl330op = PL330_OP_ABORT;
582 break;
583
584 case S3C2410_DMAOP_FLUSH:
585 pl330op = PL330_OP_FLUSH;
586 break;
587
588 case S3C2410_DMAOP_PAUSE:
589 case S3C2410_DMAOP_RESUME:
590 case S3C2410_DMAOP_TIMEOUT:
591 case S3C2410_DMAOP_STARTED:
592 spin_unlock_irqrestore(&res_lock, flags);
593 return 0;
594
595 default:
596 spin_unlock_irqrestore(&res_lock, flags);
597 return -EINVAL;
598 }
599
600 ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
601
602 if (pl330op == PL330_OP_START) {
603 spin_unlock_irqrestore(&res_lock, flags);
604 return ret;
605 }
606
607 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
608
609 /* Abort the current xfer */
610 if (ch->req[idx].x) {
611 xfer = container_of(ch->req[idx].x,
612 struct s3c_pl330_xfer, px);
613
614 /* Drop xfer during FLUSH */
615 if (pl330op == PL330_OP_FLUSH)
616 del_from_queue(xfer);
617
618 ch->req[idx].x = NULL;
619
620 spin_unlock_irqrestore(&res_lock, flags);
621 _finish_off(xfer, S3C2410_RES_ABORT,
622 pl330op == PL330_OP_FLUSH ? 1 : 0);
623 spin_lock_irqsave(&res_lock, flags);
624 }
625
626 /* Flush the whole queue */
627 if (pl330op == PL330_OP_FLUSH) {
628
629 if (ch->req[1 - idx].x) {
630 xfer = container_of(ch->req[1 - idx].x,
631 struct s3c_pl330_xfer, px);
632
633 del_from_queue(xfer);
634
635 ch->req[1 - idx].x = NULL;
636
637 spin_unlock_irqrestore(&res_lock, flags);
638 _finish_off(xfer, S3C2410_RES_ABORT, 1);
639 spin_lock_irqsave(&res_lock, flags);
640 }
641
642 /* Finish off the remaining in the queue */
643 xfer = ch->xfer_head;
644 while (xfer) {
645
646 del_from_queue(xfer);
647
648 spin_unlock_irqrestore(&res_lock, flags);
649 _finish_off(xfer, S3C2410_RES_ABORT, 1);
650 spin_lock_irqsave(&res_lock, flags);
651
652 xfer = ch->xfer_head;
653 }
654 }
655
656ctrl_exit:
657 spin_unlock_irqrestore(&res_lock, flags);
658
659 return ret;
660}
661EXPORT_SYMBOL(s3c2410_dma_ctrl);
662
663int s3c2410_dma_enqueue(enum dma_ch id, void *token,
664 dma_addr_t addr, int size)
665{
666 struct s3c_pl330_chan *ch;
667 struct s3c_pl330_xfer *xfer;
668 unsigned long flags;
669 int idx, ret = 0;
670
671 spin_lock_irqsave(&res_lock, flags);
672
673 ch = id_to_chan(id);
674
675 /* Error if invalid or free channel */
676 if (!ch || chan_free(ch)) {
677 ret = -EINVAL;
678 goto enq_exit;
679 }
680
681 /* Error if size is unaligned */
682 if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
683 ret = -EINVAL;
684 goto enq_exit;
685 }
686
687 xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
688 if (!xfer) {
689 ret = -ENOMEM;
690 goto enq_exit;
691 }
692
693 xfer->token = token;
694 xfer->chan = ch;
695 xfer->px.bytes = size;
696 xfer->px.next = NULL; /* Single request */
697
698 /* For S3C DMA API, direction is always fixed for all xfers */
699 if (ch->req[0].rqtype == MEMTODEV) {
700 xfer->px.src_addr = addr;
701 xfer->px.dst_addr = ch->sdaddr;
702 } else {
703 xfer->px.src_addr = ch->sdaddr;
704 xfer->px.dst_addr = addr;
705 }
706
707 add_to_queue(ch, xfer, 0);
708
709 /* Try submitting on either request */
710 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
711
712 if (!ch->req[idx].x)
713 s3c_pl330_submit(ch, &ch->req[idx]);
714 else
715 s3c_pl330_submit(ch, &ch->req[1 - idx]);
716
717 spin_unlock_irqrestore(&res_lock, flags);
718
719 if (ch->options & S3C2410_DMAF_AUTOSTART)
720 s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
721
722 return 0;
723
724enq_exit:
725 spin_unlock_irqrestore(&res_lock, flags);
726
727 return ret;
728}
729EXPORT_SYMBOL(s3c2410_dma_enqueue);
730
731int s3c2410_dma_request(enum dma_ch id,
732 struct s3c2410_dma_client *client,
733 void *dev)
734{
735 struct s3c_pl330_dmac *dmac;
736 struct s3c_pl330_chan *ch;
737 unsigned long flags;
738 int ret = 0;
739
740 spin_lock_irqsave(&res_lock, flags);
741
742 ch = chan_acquire(id);
743 if (!ch) {
744 ret = -EBUSY;
745 goto req_exit;
746 }
747
748 dmac = ch->dmac;
749
750 ch->pl330_chan_id = pl330_request_channel(dmac->pi);
751 if (!ch->pl330_chan_id) {
752 chan_release(ch);
753 ret = -EBUSY;
754 goto req_exit;
755 }
756
757 ch->client = client;
758 ch->options = 0; /* Clear any option */
759 ch->callback_fn = NULL; /* Clear any callback */
760 ch->lrq = NULL;
761
762 ch->rqcfg.brst_size = 2; /* Default word size */
763 ch->rqcfg.swap = SWAP_NO;
764 ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
765 ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
766 ch->rqcfg.privileged = 0;
767 ch->rqcfg.insnaccess = 0;
768
769 /* Set invalid direction */
770 ch->req[0].rqtype = DEVTODEV;
771 ch->req[1].rqtype = ch->req[0].rqtype;
772
773 ch->req[0].cfg = &ch->rqcfg;
774 ch->req[1].cfg = ch->req[0].cfg;
775
776 ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
777 ch->req[1].peri = ch->req[0].peri;
778
779 ch->req[0].token = &ch->req[0];
780 ch->req[0].xfer_cb = s3c_pl330_rq0;
781 ch->req[1].token = &ch->req[1];
782 ch->req[1].xfer_cb = s3c_pl330_rq1;
783
784 ch->req[0].x = NULL;
785 ch->req[1].x = NULL;
786
787 /* Reset xfer list */
788 INIT_LIST_HEAD(&ch->xfer_list);
789 ch->xfer_head = NULL;
790
791req_exit:
792 spin_unlock_irqrestore(&res_lock, flags);
793
794 return ret;
795}
796EXPORT_SYMBOL(s3c2410_dma_request);
797
798int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
799{
800 struct s3c_pl330_chan *ch;
801 struct s3c_pl330_xfer *xfer;
802 unsigned long flags;
803 int ret = 0;
804 unsigned idx;
805
806 spin_lock_irqsave(&res_lock, flags);
807
808 ch = id_to_chan(id);
809
810 if (!ch || chan_free(ch))
811 goto free_exit;
812
813 /* Refuse if someone else wanted to free the channel */
814 if (ch->client != client) {
815 ret = -EBUSY;
816 goto free_exit;
817 }
818
819 /* Stop any active xfer, Flushe the queue and do callbacks */
820 pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
821
822 /* Abort the submitted requests */
823 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
824
825 if (ch->req[idx].x) {
826 xfer = container_of(ch->req[idx].x,
827 struct s3c_pl330_xfer, px);
828
829 ch->req[idx].x = NULL;
830 del_from_queue(xfer);
831
832 spin_unlock_irqrestore(&res_lock, flags);
833 _finish_off(xfer, S3C2410_RES_ABORT, 1);
834 spin_lock_irqsave(&res_lock, flags);
835 }
836
837 if (ch->req[1 - idx].x) {
838 xfer = container_of(ch->req[1 - idx].x,
839 struct s3c_pl330_xfer, px);
840
841 ch->req[1 - idx].x = NULL;
842 del_from_queue(xfer);
843
844 spin_unlock_irqrestore(&res_lock, flags);
845 _finish_off(xfer, S3C2410_RES_ABORT, 1);
846 spin_lock_irqsave(&res_lock, flags);
847 }
848
849 /* Pluck and Abort the queued requests in order */
850 do {
851 xfer = get_from_queue(ch, 1);
852
853 spin_unlock_irqrestore(&res_lock, flags);
854 _finish_off(xfer, S3C2410_RES_ABORT, 1);
855 spin_lock_irqsave(&res_lock, flags);
856 } while (xfer);
857
858 ch->client = NULL;
859
860 pl330_release_channel(ch->pl330_chan_id);
861
862 ch->pl330_chan_id = NULL;
863
864 chan_release(ch);
865
866free_exit:
867 spin_unlock_irqrestore(&res_lock, flags);
868
869 return ret;
870}
871EXPORT_SYMBOL(s3c2410_dma_free);
872
873int s3c2410_dma_config(enum dma_ch id, int xferunit)
874{
875 struct s3c_pl330_chan *ch;
876 struct pl330_info *pi;
877 unsigned long flags;
878 int i, dbwidth, ret = 0;
879
880 spin_lock_irqsave(&res_lock, flags);
881
882 ch = id_to_chan(id);
883
884 if (!ch || chan_free(ch)) {
885 ret = -EINVAL;
886 goto cfg_exit;
887 }
888
889 pi = ch->dmac->pi;
890 dbwidth = pi->pcfg.data_bus_width / 8;
891
892 /* Max size of xfer can be pcfg.data_bus_width */
893 if (xferunit > dbwidth) {
894 ret = -EINVAL;
895 goto cfg_exit;
896 }
897
898 i = 0;
899 while (xferunit != (1 << i))
900 i++;
901
902 /* If valid value */
903 if (xferunit == (1 << i))
904 ch->rqcfg.brst_size = i;
905 else
906 ret = -EINVAL;
907
908cfg_exit:
909 spin_unlock_irqrestore(&res_lock, flags);
910
911 return ret;
912}
913EXPORT_SYMBOL(s3c2410_dma_config);
914
915/* Options that are supported by this driver */
916#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
917
918int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
919{
920 struct s3c_pl330_chan *ch;
921 unsigned long flags;
922 int ret = 0;
923
924 spin_lock_irqsave(&res_lock, flags);
925
926 ch = id_to_chan(id);
927
928 if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
929 ret = -EINVAL;
930 else
931 ch->options = options;
932
933 spin_unlock_irqrestore(&res_lock, flags);
934
935 return 0;
936}
937EXPORT_SYMBOL(s3c2410_dma_setflags);
938
939int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
940{
941 struct s3c_pl330_chan *ch;
942 unsigned long flags;
943 int ret = 0;
944
945 spin_lock_irqsave(&res_lock, flags);
946
947 ch = id_to_chan(id);
948
949 if (!ch || chan_free(ch))
950 ret = -EINVAL;
951 else
952 ch->callback_fn = rtn;
953
954 spin_unlock_irqrestore(&res_lock, flags);
955
956 return ret;
957}
958EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
959
960int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
961 unsigned long address)
962{
963 struct s3c_pl330_chan *ch;
964 unsigned long flags;
965 int ret = 0;
966
967 spin_lock_irqsave(&res_lock, flags);
968
969 ch = id_to_chan(id);
970
971 if (!ch || chan_free(ch)) {
972 ret = -EINVAL;
973 goto devcfg_exit;
974 }
975
976 switch (source) {
977 case S3C2410_DMASRC_HW: /* P->M */
978 ch->req[0].rqtype = DEVTOMEM;
979 ch->req[1].rqtype = DEVTOMEM;
980 ch->rqcfg.src_inc = 0;
981 ch->rqcfg.dst_inc = 1;
982 break;
983 case S3C2410_DMASRC_MEM: /* M->P */
984 ch->req[0].rqtype = MEMTODEV;
985 ch->req[1].rqtype = MEMTODEV;
986 ch->rqcfg.src_inc = 1;
987 ch->rqcfg.dst_inc = 0;
988 break;
989 default:
990 ret = -EINVAL;
991 goto devcfg_exit;
992 }
993
994 ch->sdaddr = address;
995
996devcfg_exit:
997 spin_unlock_irqrestore(&res_lock, flags);
998
999 return ret;
1000}
1001EXPORT_SYMBOL(s3c2410_dma_devconfig);
1002
1003int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
1004{
1005 struct s3c_pl330_chan *ch = id_to_chan(id);
1006 struct pl330_chanstatus status;
1007 int ret;
1008
1009 if (!ch || chan_free(ch))
1010 return -EINVAL;
1011
1012 ret = pl330_chan_status(ch->pl330_chan_id, &status);
1013 if (ret < 0)
1014 return ret;
1015
1016 *src = status.src_addr;
1017 *dst = status.dst_addr;
1018
1019 return 0;
1020}
1021EXPORT_SYMBOL(s3c2410_dma_getposition);
1022
1023static irqreturn_t pl330_irq_handler(int irq, void *data)
1024{
1025 if (pl330_update(data))
1026 return IRQ_HANDLED;
1027 else
1028 return IRQ_NONE;
1029}
1030
1031static int pl330_probe(struct platform_device *pdev)
1032{
1033 struct s3c_pl330_dmac *s3c_pl330_dmac;
1034 struct s3c_pl330_platdata *pl330pd;
1035 struct pl330_info *pl330_info;
1036 struct resource *res;
1037 int i, ret, irq;
1038
1039 pl330pd = pdev->dev.platform_data;
1040
1041 /* Can't do without the list of _32_ peripherals */
1042 if (!pl330pd || !pl330pd->peri) {
1043 dev_err(&pdev->dev, "platform data missing!\n");
1044 return -ENODEV;
1045 }
1046
1047 pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
1048 if (!pl330_info)
1049 return -ENOMEM;
1050
1051 pl330_info->pl330_data = NULL;
1052 pl330_info->dev = &pdev->dev;
1053
1054 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1055 if (!res) {
1056 ret = -ENODEV;
1057 goto probe_err1;
1058 }
1059
1060 request_mem_region(res->start, resource_size(res), pdev->name);
1061
1062 pl330_info->base = ioremap(res->start, resource_size(res));
1063 if (!pl330_info->base) {
1064 ret = -ENXIO;
1065 goto probe_err2;
1066 }
1067
1068 irq = platform_get_irq(pdev, 0);
1069 if (irq < 0) {
1070 ret = irq;
1071 goto probe_err3;
1072 }
1073
1074 ret = request_irq(irq, pl330_irq_handler, 0,
1075 dev_name(&pdev->dev), pl330_info);
1076 if (ret)
1077 goto probe_err4;
1078
1079 /* Allocate a new DMAC */
1080 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
1081 if (!s3c_pl330_dmac) {
1082 ret = -ENOMEM;
1083 goto probe_err5;
1084 }
1085
1086 /* Get operation clock and enable it */
1087 s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
1088 if (IS_ERR(s3c_pl330_dmac->clk)) {
1089 dev_err(&pdev->dev, "Cannot get operation clock.\n");
1090 ret = -EINVAL;
1091 goto probe_err6;
1092 }
1093 clk_enable(s3c_pl330_dmac->clk);
1094
1095 ret = pl330_add(pl330_info);
1096 if (ret)
1097 goto probe_err7;
1098
1099 /* Hook the info */
1100 s3c_pl330_dmac->pi = pl330_info;
1101
1102 /* No busy channels */
1103 s3c_pl330_dmac->busy_chan = 0;
1104
1105 s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
1106 sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
1107
1108 if (!s3c_pl330_dmac->kmcache) {
1109 ret = -ENOMEM;
1110 goto probe_err8;
1111 }
1112
1113 /* Get the list of peripherals */
1114 s3c_pl330_dmac->peri = pl330pd->peri;
1115
1116 /* Attach to the list of DMACs */
1117 list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
1118
1119 /* Create a channel for each peripheral in the DMAC
1120 * that is, if it doesn't already exist
1121 */
1122 for (i = 0; i < PL330_MAX_PERI; i++)
1123 if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
1124 chan_add(s3c_pl330_dmac->peri[i]);
1125
1126 printk(KERN_INFO
1127 "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
1128 printk(KERN_INFO
1129 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
1130 pl330_info->pcfg.data_buf_dep,
1131 pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
1132 pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
1133
1134 return 0;
1135
1136probe_err8:
1137 pl330_del(pl330_info);
1138probe_err7:
1139 clk_disable(s3c_pl330_dmac->clk);
1140 clk_put(s3c_pl330_dmac->clk);
1141probe_err6:
1142 kfree(s3c_pl330_dmac);
1143probe_err5:
1144 free_irq(irq, pl330_info);
1145probe_err4:
1146probe_err3:
1147 iounmap(pl330_info->base);
1148probe_err2:
1149 release_mem_region(res->start, resource_size(res));
1150probe_err1:
1151 kfree(pl330_info);
1152
1153 return ret;
1154}
1155
1156static int pl330_remove(struct platform_device *pdev)
1157{
1158 struct s3c_pl330_dmac *dmac, *d;
1159 struct s3c_pl330_chan *ch;
1160 unsigned long flags;
1161 int del, found;
1162
1163 if (!pdev->dev.platform_data)
1164 return -EINVAL;
1165
1166 spin_lock_irqsave(&res_lock, flags);
1167
1168 found = 0;
1169 list_for_each_entry(d, &dmac_list, node)
1170 if (d->pi->dev == &pdev->dev) {
1171 found = 1;
1172 break;
1173 }
1174
1175 if (!found) {
1176 spin_unlock_irqrestore(&res_lock, flags);
1177 return 0;
1178 }
1179
1180 dmac = d;
1181
1182 /* Remove all Channels that are managed only by this DMAC */
1183 list_for_each_entry(ch, &chan_list, node) {
1184
1185 /* Only channels that are handled by this DMAC */
1186 if (iface_of_dmac(dmac, ch->id))
1187 del = 1;
1188 else
1189 continue;
1190
1191 /* Don't remove if some other DMAC has it too */
1192 list_for_each_entry(d, &dmac_list, node)
1193 if (d != dmac && iface_of_dmac(d, ch->id)) {
1194 del = 0;
1195 break;
1196 }
1197
1198 if (del) {
1199 spin_unlock_irqrestore(&res_lock, flags);
1200 s3c2410_dma_free(ch->id, ch->client);
1201 spin_lock_irqsave(&res_lock, flags);
1202 list_del(&ch->node);
1203 kfree(ch);
1204 }
1205 }
1206
1207 /* Disable operation clock */
1208 clk_disable(dmac->clk);
1209 clk_put(dmac->clk);
1210
1211 /* Remove the DMAC */
1212 list_del(&dmac->node);
1213 kfree(dmac);
1214
1215 spin_unlock_irqrestore(&res_lock, flags);
1216
1217 return 0;
1218}
1219
1220static struct platform_driver pl330_driver = {
1221 .driver = {
1222 .owner = THIS_MODULE,
1223 .name = "s3c-pl330",
1224 },
1225 .probe = pl330_probe,
1226 .remove = pl330_remove,
1227};
1228
1229static int __init pl330_init(void)
1230{
1231 return platform_driver_register(&pl330_driver);
1232}
1233module_init(pl330_init);
1234
1235static void __exit pl330_exit(void)
1236{
1237 platform_driver_unregister(&pl330_driver);
1238 return;
1239}
1240module_exit(pl330_exit);
1241
1242MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1243MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
1244MODULE_LICENSE("GPL");
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 7c928da35b17..7617248f0d11 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -321,11 +321,13 @@
321#define __NR_syncfs 1329 321#define __NR_syncfs 1329
322#define __NR_setns 1330 322#define __NR_setns 1330
323#define __NR_sendmmsg 1331 323#define __NR_sendmmsg 1331
324#define __NR_process_vm_readv 1332
325#define __NR_process_vm_writev 1333
324 326
325#ifdef __KERNEL__ 327#ifdef __KERNEL__
326 328
327 329
328#define NR_syscalls 308 /* length of syscall table */ 330#define NR_syscalls 310 /* length of syscall table */
329 331
330/* 332/*
331 * The following defines stop scripts/checksyscalls.sh from complaining about 333 * The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 198c753d1006..5b31d46aff67 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1777,6 +1777,8 @@ sys_call_table:
1777 data8 sys_syncfs 1777 data8 sys_syncfs
1778 data8 sys_setns // 1330 1778 data8 sys_setns // 1330
1779 data8 sys_sendmmsg 1779 data8 sys_sendmmsg
1780 data8 sys_process_vm_readv
1781 data8 sys_process_vm_writev
1780 1782
1781 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1783 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
1782#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ 1784#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 48e50f8c1c7e..e3011338ab40 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -59,7 +59,7 @@ struct nfhd_device {
59 struct gendisk *disk; 59 struct gendisk *disk;
60}; 60};
61 61
62static int nfhd_make_request(struct request_queue *queue, struct bio *bio) 62static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
63{ 63{
64 struct nfhd_device *dev = queue->queuedata; 64 struct nfhd_device *dev = queue->queuedata;
65 struct bio_vec *bvec; 65 struct bio_vec *bvec;
@@ -76,7 +76,6 @@ static int nfhd_make_request(struct request_queue *queue, struct bio *bio)
76 sec += len; 76 sec += len;
77 } 77 }
78 bio_endio(bio, 0); 78 bio_endio(bio, 0);
79 return 0;
80} 79}
81 80
82static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo) 81static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 47682b67fd36..85195e48a9e6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -323,7 +323,7 @@ config SWIOTLB
323 323
324config HOTPLUG_CPU 324config HOTPLUG_CPU
325 bool "Support for enabling/disabling CPUs" 325 bool "Support for enabling/disabling CPUs"
326 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) 326 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV)
327 ---help--- 327 ---help---
328 Say Y here to be able to disable and re-enable individual 328 Say Y here to be able to disable and re-enable individual
329 CPUs at runtime on SMP machines. 329 CPUs at runtime on SMP machines.
@@ -345,7 +345,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
345 345
346config KEXEC 346config KEXEC
347 bool "kexec system call (EXPERIMENTAL)" 347 bool "kexec system call (EXPERIMENTAL)"
348 depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL 348 depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !47x)) && EXPERIMENTAL
349 help 349 help
350 kexec is a system call that implements the ability to shutdown your 350 kexec is a system call that implements the ability to shutdown your
351 current kernel, and to start another kernel. It is like a reboot 351 current kernel, and to start another kernel. It is like a reboot
@@ -429,8 +429,7 @@ config ARCH_POPULATES_NODE_MAP
429 def_bool y 429 def_bool y
430 430
431config SYS_SUPPORTS_HUGETLBFS 431config SYS_SUPPORTS_HUGETLBFS
432 def_bool y 432 bool
433 depends on PPC_BOOK3S_64
434 433
435source "mm/Kconfig" 434source "mm/Kconfig"
436 435
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 067cb8480747..1b8a9c905cf7 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -141,9 +141,6 @@ config BOOTX_TEXT
141 141
142config PPC_EARLY_DEBUG 142config PPC_EARLY_DEBUG
143 bool "Early debugging (dangerous)" 143 bool "Early debugging (dangerous)"
144 # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water
145 # mark, which doesn't work with current 440 KVM.
146 depends on !KVM
147 help 144 help
148 Say Y to enable some early debugging facilities that may be available 145 Say Y to enable some early debugging facilities that may be available
149 for your processor/board combination. Those facilities are hacks 146 for your processor/board combination. Those facilities are hacks
@@ -222,7 +219,9 @@ config PPC_EARLY_DEBUG_BEAT
222 219
223config PPC_EARLY_DEBUG_44x 220config PPC_EARLY_DEBUG_44x
224 bool "Early serial debugging for IBM/AMCC 44x CPUs" 221 bool "Early serial debugging for IBM/AMCC 44x CPUs"
225 depends on 44x 222 # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water
223 # mark, which doesn't work with current 440 KVM.
224 depends on 44x && !KVM
226 help 225 help
227 Select this to enable early debugging for IBM 44x chips via the 226 Select this to enable early debugging for IBM 44x chips via the
228 inbuilt serial port. If you enable this, ensure you set 227 inbuilt serial port. If you enable this, ensure you set
@@ -258,8 +257,35 @@ config PPC_EARLY_DEBUG_WSP
258 depends on PPC_WSP 257 depends on PPC_WSP
259 select PPC_UDBG_16550 258 select PPC_UDBG_16550
260 259
260config PPC_EARLY_DEBUG_PS3GELIC
261 bool "Early debugging through the PS3 Ethernet port"
262 depends on PPC_PS3
263 select PS3GELIC_UDBG
264 help
265 Select this to enable early debugging for the PlayStation3 via
266 UDP broadcasts sent out through the Ethernet port.
267
268config PPC_EARLY_DEBUG_OPAL_RAW
269 bool "OPAL raw console"
270 depends on HVC_OPAL
271 help
272 Select this to enable early debugging for the PowerNV platform
273 using a "raw" console
274
275config PPC_EARLY_DEBUG_OPAL_HVSI
276 bool "OPAL hvsi console"
277 depends on HVC_OPAL
278 help
279 Select this to enable early debugging for the PowerNV platform
280 using an "hvsi" console
281
261endchoice 282endchoice
262 283
284config PPC_EARLY_DEBUG_OPAL
285 def_bool y
286 depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
287
288
263config PPC_EARLY_DEBUG_HVSI_VTERMNO 289config PPC_EARLY_DEBUG_HVSI_VTERMNO
264 hex "vterm number to use with early debug HVSI" 290 hex "vterm number to use with early debug HVSI"
265 depends on PPC_EARLY_DEBUG_LPAR_HVSI 291 depends on PPC_EARLY_DEBUG_LPAR_HVSI
@@ -268,6 +294,18 @@ config PPC_EARLY_DEBUG_HVSI_VTERMNO
268 You probably want 0x30000000 for your first serial port and 294 You probably want 0x30000000 for your first serial port and
269 0x30000001 for your second one 295 0x30000001 for your second one
270 296
297config PPC_EARLY_DEBUG_OPAL_VTERMNO
298 hex "vterm number to use with OPAL early debug"
299 depends on PPC_EARLY_DEBUG_OPAL
300 default "0"
301 help
302 This correspond to which /dev/hvcN you want to use for early
303 debug.
304
305 On OPAL v1 (takeover) this should always be 0
306 On OPAL v2, this will be 0 for network console and 1 or 2 for
307 the machine built-in serial ports.
308
271config PPC_EARLY_DEBUG_44x_PHYSLOW 309config PPC_EARLY_DEBUG_44x_PHYSLOW
272 hex "Low 32 bits of early debug UART physical address" 310 hex "Low 32 bits of early debug UART physical address"
273 depends on PPC_EARLY_DEBUG_44x 311 depends on PPC_EARLY_DEBUG_44x
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index c26200b40a47..72ee8c1fba48 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -58,7 +58,7 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \
58libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c 58libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
59libfdtheader := fdt.h libfdt.h libfdt_internal.h 59libfdtheader := fdt.h libfdt.h libfdt_internal.h
60 60
61$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o): \ 61$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \
62 $(addprefix $(obj)/,$(libfdtheader)) 62 $(addprefix $(obj)/,$(libfdtheader))
63 63
64src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ 64src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \
@@ -171,6 +171,7 @@ quiet_cmd_wrap = WRAP $@
171 $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux 171 $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
172 172
173image-$(CONFIG_PPC_PSERIES) += zImage.pseries 173image-$(CONFIG_PPC_PSERIES) += zImage.pseries
174image-$(CONFIG_PPC_POWERNV) += zImage.pseries
174image-$(CONFIG_PPC_MAPLE) += zImage.maple 175image-$(CONFIG_PPC_MAPLE) += zImage.maple
175image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries 176image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
176image-$(CONFIG_PPC_PS3) += dtbImage.ps3 177image-$(CONFIG_PPC_PS3) += dtbImage.ps3
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts
index 27bd267d631c..a7511f2d844d 100644
--- a/arch/powerpc/boot/dts/digsy_mtc.dts
+++ b/arch/powerpc/boot/dts/digsy_mtc.dts
@@ -23,19 +23,26 @@
23 23
24 soc5200@f0000000 { 24 soc5200@f0000000 {
25 timer@600 { // General Purpose Timer 25 timer@600 { // General Purpose Timer
26 #gpio-cells = <2>;
26 fsl,has-wdt; 27 fsl,has-wdt;
28 gpio-controller;
27 }; 29 };
28 30
29 rtc@800 { 31 timer@610 {
30 status = "disabled"; 32 #gpio-cells = <2>;
33 gpio-controller;
31 }; 34 };
32 35
33 can@900 { 36 rtc@800 {
34 status = "disabled"; 37 status = "disabled";
35 }; 38 };
36 39
37 can@980 { 40 spi@f00 {
38 status = "disabled"; 41 msp430@0 {
42 compatible = "spidev";
43 spi-max-frequency = <32000>;
44 reg = <0>;
45 };
39 }; 46 };
40 47
41 psc@2000 { // PSC1 48 psc@2000 { // PSC1
@@ -73,11 +80,16 @@
73 }; 80 };
74 81
75 i2c@3d00 { 82 i2c@3d00 {
76 rtc@50 { 83 eeprom@50 {
77 compatible = "at,24c08"; 84 compatible = "at,24c08";
78 reg = <0x50>; 85 reg = <0x50>;
79 }; 86 };
80 87
88 rtc@56 {
89 compatible = "mc,rv3029c2";
90 reg = <0x56>;
91 };
92
81 rtc@68 { 93 rtc@68 {
82 compatible = "dallas,ds1339"; 94 compatible = "dallas,ds1339";
83 reg = <0x68>; 95 reg = <0x68>;
@@ -90,11 +102,22 @@
90 }; 102 };
91 103
92 pci@f0000d00 { 104 pci@f0000d00 {
93 status = "disabled"; 105 interrupt-map-mask = <0xf800 0 0 7>;
106 interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
107 0xc000 0 0 2 &mpc5200_pic 0 0 3
108 0xc000 0 0 3 &mpc5200_pic 0 0 3
109 0xc000 0 0 4 &mpc5200_pic 0 0 3>;
110 clock-frequency = <0>; // From boot loader
111 interrupts = <2 8 0 2 9 0 2 10 0>;
112 bus-range = <0 0>;
113 ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
114 0x02000000 0 0x90000000 0x90000000 0 0x10000000
115 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
94 }; 116 };
95 117
96 localbus { 118 localbus {
97 ranges = <0 0 0xff000000 0x1000000>; 119 ranges = <0 0 0xff000000 0x1000000
120 4 0 0x60000000 0x0001000>;
98 121
99 // 16-bit flash device at LocalPlus Bus CS0 122 // 16-bit flash device at LocalPlus Bus CS0
100 flash@0,0 { 123 flash@0,0 {
@@ -122,5 +145,25 @@
122 reg = <0x00f00000 0x100000>; 145 reg = <0x00f00000 0x100000>;
123 }; 146 };
124 }; 147 };
148
149 can@4,0 {
150 compatible = "nxp,sja1000";
151 reg = <4 0x000 0x80>;
152 nxp,external-clock-frequency = <24000000>;
153 interrupts = <1 2 3>; // Level-low
154 };
155
156 can@4,100 {
157 compatible = "nxp,sja1000";
158 reg = <4 0x100 0x80>;
159 nxp,external-clock-frequency = <24000000>;
160 interrupts = <1 2 3>; // Level-low
161 };
162
163 serial@4,200 {
164 compatible = "nxp,sc28l92";
165 reg = <4 0x200 0x10>;
166 interrupts = <1 3 3>;
167 };
125 }; 168 };
126}; 169};
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
index 83f4b79dff85..2266bbb303d0 100644
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -269,14 +269,16 @@
269 enet0: ethernet@24000 { 269 enet0: ethernet@24000 {
270 #address-cells = <1>; 270 #address-cells = <1>;
271 #size-cells = <1>; 271 #size-cells = <1>;
272 cell-index = <0>;
272 device_type = "network"; 273 device_type = "network";
273 model = "eTSEC"; 274 model = "TSEC";
274 compatible = "gianfar"; 275 compatible = "gianfar";
275 reg = <0x24000 0x1000>; 276 reg = <0x24000 0x1000>;
276 ranges = <0x0 0x24000 0x1000>; 277 ranges = <0x0 0x24000 0x1000>;
277 local-mac-address = [ 00 00 00 00 00 00 ]; 278 local-mac-address = [ 00 00 00 00 00 00 ];
278 interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; 279 interrupts = <29 2 30 2 34 2>;
279 interrupt-parent = <&mpic>; 280 interrupt-parent = <&mpic>;
281 tbi-handle = <&tbi0>;
280 phy-handle = <&phy0>; 282 phy-handle = <&phy0>;
281 phy-connection-type = "gmii"; 283 phy-connection-type = "gmii";
282 284
@@ -290,25 +292,48 @@
290 interrupt-parent = <&gef_pic>; 292 interrupt-parent = <&gef_pic>;
291 interrupts = <0x9 0x4>; 293 interrupts = <0x9 0x4>;
292 reg = <1>; 294 reg = <1>;
295 device_type = "ethernet-phy";
293 }; 296 };
294 phy2: ethernet-phy@2 { 297 phy2: ethernet-phy@2 {
295 interrupt-parent = <&gef_pic>; 298 interrupt-parent = <&gef_pic>;
296 interrupts = <0x8 0x4>; 299 interrupts = <0x8 0x4>;
297 reg = <3>; 300 reg = <3>;
301 device_type = "ethernet-phy";
302 };
303 tbi0: tbi-phy@11 {
304 reg = <0x11>;
305 device_type = "tbi-phy";
298 }; 306 };
299 }; 307 };
300 }; 308 };
301 309
302 enet1: ethernet@26000 { 310 enet1: ethernet@26000 {
311 #address-cells = <1>;
312 #size-cells = <1>;
313 cell-index = <2>;
303 device_type = "network"; 314 device_type = "network";
304 model = "eTSEC"; 315 model = "TSEC";
305 compatible = "gianfar"; 316 compatible = "gianfar";
306 reg = <0x26000 0x1000>; 317 reg = <0x26000 0x1000>;
318 ranges = <0x0 0x26000 0x1000>;
307 local-mac-address = [ 00 00 00 00 00 00 ]; 319 local-mac-address = [ 00 00 00 00 00 00 ];
308 interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; 320 interrupts = <31 2 32 2 33 2>;
309 interrupt-parent = <&mpic>; 321 interrupt-parent = <&mpic>;
322 tbi-handle = <&tbi2>;
310 phy-handle = <&phy2>; 323 phy-handle = <&phy2>;
311 phy-connection-type = "gmii"; 324 phy-connection-type = "gmii";
325
326 mdio@520 {
327 #address-cells = <1>;
328 #size-cells = <0>;
329 compatible = "fsl,gianfar-tbi";
330 reg = <0x520 0x20>;
331
332 tbi2: tbi-phy@11 {
333 reg = <0x11>;
334 device_type = "tbi-phy";
335 };
336 };
312 }; 337 };
313 338
314 serial0: serial@4500 { 339 serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index fc3a331dd392..429e87d9acef 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -267,14 +267,16 @@
267 enet0: ethernet@24000 { 267 enet0: ethernet@24000 {
268 #address-cells = <1>; 268 #address-cells = <1>;
269 #size-cells = <1>; 269 #size-cells = <1>;
270 cell-index = <0>;
270 device_type = "network"; 271 device_type = "network";
271 model = "eTSEC"; 272 model = "TSEC";
272 compatible = "gianfar"; 273 compatible = "gianfar";
273 reg = <0x24000 0x1000>; 274 reg = <0x24000 0x1000>;
274 ranges = <0x0 0x24000 0x1000>; 275 ranges = <0x0 0x24000 0x1000>;
275 local-mac-address = [ 00 00 00 00 00 00 ]; 276 local-mac-address = [ 00 00 00 00 00 00 ];
276 interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; 277 interrupts = <29 2 30 2 34 2>;
277 interrupt-parent = <&mpic>; 278 interrupt-parent = <&mpic>;
279 tbi-handle = <&tbi0>;
278 phy-handle = <&phy0>; 280 phy-handle = <&phy0>;
279 phy-connection-type = "gmii"; 281 phy-connection-type = "gmii";
280 282
@@ -288,25 +290,48 @@
288 interrupt-parent = <&gef_pic>; 290 interrupt-parent = <&gef_pic>;
289 interrupts = <0x9 0x4>; 291 interrupts = <0x9 0x4>;
290 reg = <1>; 292 reg = <1>;
293 device_type = "ethernet-phy";
291 }; 294 };
292 phy2: ethernet-phy@2 { 295 phy2: ethernet-phy@2 {
293 interrupt-parent = <&gef_pic>; 296 interrupt-parent = <&gef_pic>;
294 interrupts = <0x8 0x4>; 297 interrupts = <0x8 0x4>;
295 reg = <3>; 298 reg = <3>;
299 device_type = "ethernet-phy";
300 };
301 tbi0: tbi-phy@11 {
302 reg = <0x11>;
303 device_type = "tbi-phy";
296 }; 304 };
297 }; 305 };
298 }; 306 };
299 307
300 enet1: ethernet@26000 { 308 enet1: ethernet@26000 {
309 #address-cells = <1>;
310 #size-cells = <1>;
311 cell-index = <2>;
301 device_type = "network"; 312 device_type = "network";
302 model = "eTSEC"; 313 model = "TSEC";
303 compatible = "gianfar"; 314 compatible = "gianfar";
304 reg = <0x26000 0x1000>; 315 reg = <0x26000 0x1000>;
316 ranges = <0x0 0x26000 0x1000>;
305 local-mac-address = [ 00 00 00 00 00 00 ]; 317 local-mac-address = [ 00 00 00 00 00 00 ];
306 interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; 318 interrupts = <31 2 32 2 33 2>;
307 interrupt-parent = <&mpic>; 319 interrupt-parent = <&mpic>;
320 tbi-handle = <&tbi2>;
308 phy-handle = <&phy2>; 321 phy-handle = <&phy2>;
309 phy-connection-type = "gmii"; 322 phy-connection-type = "gmii";
323
324 mdio@520 {
325 #address-cells = <1>;
326 #size-cells = <0>;
327 compatible = "fsl,gianfar-tbi";
328 reg = <0x520 0x20>;
329
330 tbi2: tbi-phy@11 {
331 reg = <0x11>;
332 device_type = "tbi-phy";
333 };
334 };
310 }; 335 };
311 336
312 serial0: serial@4500 { 337 serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index c0671cc98125..d81201ac2cad 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -267,14 +267,16 @@
267 enet0: ethernet@24000 { 267 enet0: ethernet@24000 {
268 #address-cells = <1>; 268 #address-cells = <1>;
269 #size-cells = <1>; 269 #size-cells = <1>;
270 cell-index = <0>;
270 device_type = "network"; 271 device_type = "network";
271 model = "eTSEC"; 272 model = "TSEC";
272 compatible = "gianfar"; 273 compatible = "gianfar";
273 reg = <0x24000 0x1000>; 274 reg = <0x24000 0x1000>;
274 ranges = <0x0 0x24000 0x1000>; 275 ranges = <0x0 0x24000 0x1000>;
275 local-mac-address = [ 00 00 00 00 00 00 ]; 276 local-mac-address = [ 00 00 00 00 00 00 ];
276 interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; 277 interrupts = <29 2 30 2 34 2>;
277 interrupt-parent = <&mpic>; 278 interrupt-parent = <&mpic>;
279 tbi-handle = <&tbi0>;
278 phy-handle = <&phy0>; 280 phy-handle = <&phy0>;
279 phy-connection-type = "gmii"; 281 phy-connection-type = "gmii";
280 282
@@ -288,25 +290,48 @@
288 interrupt-parent = <&gef_pic>; 290 interrupt-parent = <&gef_pic>;
289 interrupts = <0x9 0x4>; 291 interrupts = <0x9 0x4>;
290 reg = <1>; 292 reg = <1>;
293 device_type = "ethernet-phy";
291 }; 294 };
292 phy2: ethernet-phy@2 { 295 phy2: ethernet-phy@2 {
293 interrupt-parent = <&gef_pic>; 296 interrupt-parent = <&gef_pic>;
294 interrupts = <0x8 0x4>; 297 interrupts = <0x8 0x4>;
295 reg = <3>; 298 reg = <3>;
299 device_type = "ethernet-phy";
300 };
301 tbi0: tbi-phy@11 {
302 reg = <0x11>;
303 device_type = "tbi-phy";
296 }; 304 };
297 }; 305 };
298 }; 306 };
299 307
300 enet1: ethernet@26000 { 308 enet1: ethernet@26000 {
309 #address-cells = <1>;
310 #size-cells = <1>;
311 cell-index = <2>;
301 device_type = "network"; 312 device_type = "network";
302 model = "eTSEC"; 313 model = "TSEC";
303 compatible = "gianfar"; 314 compatible = "gianfar";
304 reg = <0x26000 0x1000>; 315 reg = <0x26000 0x1000>;
316 ranges = <0x0 0x26000 0x1000>;
305 local-mac-address = [ 00 00 00 00 00 00 ]; 317 local-mac-address = [ 00 00 00 00 00 00 ];
306 interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; 318 interrupts = <31 2 32 2 33 2>;
307 interrupt-parent = <&mpic>; 319 interrupt-parent = <&mpic>;
320 tbi-handle = <&tbi2>;
308 phy-handle = <&phy2>; 321 phy-handle = <&phy2>;
309 phy-connection-type = "gmii"; 322 phy-connection-type = "gmii";
323
324 mdio@520 {
325 #address-cells = <1>;
326 #size-cells = <0>;
327 compatible = "fsl,gianfar-tbi";
328 reg = <0x520 0x20>;
329
330 tbi2: tbi-phy@11 {
331 reg = <0x11>;
332 device_type = "tbi-phy";
333 };
334 };
310 }; 335 };
311 336
312 serial0: serial@4500 { 337 serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts
deleted file mode 100644
index 7988598da4c9..000000000000
--- a/arch/powerpc/boot/dts/hcu4.dts
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2* Device Tree Source for Netstal Maschinen HCU4
3* based on the IBM Walnut
4*
5* Copyright 2008
6* Niklaus Giger <niklaus.giger@member.fsf.org>
7*
8* Copyright 2007 IBM Corp.
9* Josh Boyer <jwboyer@linux.vnet.ibm.com>
10*
11* This file is licensed under the terms of the GNU General Public
12* License version 2. This program is licensed "as is" without
13* any warranty of any kind, whether express or implied.
14*/
15
16/dts-v1/;
17
18/ {
19 #address-cells = <0x1>;
20 #size-cells = <0x1>;
21 model = "netstal,hcu4";
22 compatible = "netstal,hcu4";
23 dcr-parent = <0x1>;
24
25 aliases {
26 ethernet0 = "/plb/opb/ethernet@ef600800";
27 serial0 = "/plb/opb/serial@ef600300";
28 };
29
30 cpus {
31 #address-cells = <0x1>;
32 #size-cells = <0x0>;
33
34 cpu@0 {
35 device_type = "cpu";
36 model = "PowerPC,405GPr";
37 reg = <0x0>;
38 clock-frequency = <0>; /* Filled in by U-Boot */
39 timebase-frequency = <0x0>; /* Filled in by U-Boot */
40 i-cache-line-size = <0x20>;
41 d-cache-line-size = <0x20>;
42 i-cache-size = <0x4000>;
43 d-cache-size = <0x4000>;
44 dcr-controller;
45 dcr-access-method = "native";
46 linux,phandle = <0x1>;
47 };
48 };
49
50 memory {
51 device_type = "memory";
52 reg = <0x0 0x0>; /* Filled in by U-Boot */
53 };
54
55 UIC0: interrupt-controller {
56 compatible = "ibm,uic";
57 interrupt-controller;
58 cell-index = <0x0>;
59 dcr-reg = <0xc0 0x9>;
60 #address-cells = <0x0>;
61 #size-cells = <0x0>;
62 #interrupt-cells = <0x2>;
63 linux,phandle = <0x2>;
64 };
65
66 plb {
67 compatible = "ibm,plb3";
68 #address-cells = <0x1>;
69 #size-cells = <0x1>;
70 ranges;
71 clock-frequency = <0x0>; /* Filled in by U-Boot */
72
73 SDRAM0: memory-controller {
74 compatible = "ibm,sdram-405gp";
75 dcr-reg = <0x10 0x2>;
76 };
77
78 MAL: mcmal {
79 compatible = "ibm,mcmal-405gp", "ibm,mcmal";
80 dcr-reg = <0x180 0x62>;
81 num-tx-chans = <0x1>;
82 num-rx-chans = <0x1>;
83 interrupt-parent = <0x2>;
84 interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>;
85 linux,phandle = <0x3>;
86 };
87
88 POB0: opb {
89 compatible = "ibm,opb-405gp", "ibm,opb";
90 #address-cells = <0x1>;
91 #size-cells = <0x1>;
92 ranges = <0xef600000 0xef600000 0xa00000>;
93 dcr-reg = <0xa0 0x5>;
94 clock-frequency = <0x0>; /* Filled in by U-Boot */
95
96 UART0: serial@ef600300 {
97 device_type = "serial";
98 compatible = "ns16550";
99 reg = <0xef600300 0x8>;
100 virtual-reg = <0xef600300>;
101 clock-frequency = <0x0>;/* Filled in by U-Boot */
102 current-speed = <0>; /* Filled in by U-Boot */
103 interrupt-parent = <0x2>;
104 interrupts = <0x0 0x4>;
105 };
106
107 IIC: i2c@ef600500 {
108 compatible = "ibm,iic-405gp", "ibm,iic";
109 reg = <0xef600500 0x11>;
110 interrupt-parent = <0x2>;
111 interrupts = <0x2 0x4>;
112 };
113
114 GPIO: gpio@ef600700 {
115 compatible = "ibm,gpio-405gp";
116 reg = <0xef600700 0x20>;
117 };
118
119 EMAC: ethernet@ef600800 {
120 device_type = "network";
121 compatible = "ibm,emac-405gp", "ibm,emac";
122 interrupt-parent = <0x2>;
123 interrupts = <0xf 0x4 0x9 0x4>;
124 local-mac-address = [00 00 00 00 00 00];
125 reg = <0xef600800 0x70>;
126 mal-device = <0x3>;
127 mal-tx-channel = <0x0>;
128 mal-rx-channel = <0x0>;
129 cell-index = <0x0>;
130 max-frame-size = <0x5dc>;
131 rx-fifo-size = <0x1000>;
132 tx-fifo-size = <0x800>;
133 phy-mode = "rmii";
134 phy-map = <0x1>;
135 };
136 };
137
138 EBC0: ebc {
139 compatible = "ibm,ebc-405gp", "ibm,ebc";
140 dcr-reg = <0x12 0x2>;
141 #address-cells = <0x2>;
142 #size-cells = <0x1>;
143 clock-frequency = <0x0>; /* Filled in by U-Boot */
144
145 sram@0,0 {
146 reg = <0x0 0x0 0x80000>;
147 };
148
149 flash@0,80000 {
150 compatible = "jedec-flash";
151 bank-width = <0x1>;
152 reg = <0x0 0x80000 0x80000>;
153 #address-cells = <0x1>;
154 #size-cells = <0x1>;
155
156 partition@0 {
157 label = "OpenBIOS";
158 reg = <0x0 0x80000>;
159 read-only;
160 };
161 };
162 };
163 };
164
165 chosen {
166 linux,stdout-path = "/plb/opb/serial@ef600300";
167 };
168};
diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts
index bdb7fc0fa332..296c572ea605 100644
--- a/arch/powerpc/boot/dts/ksi8560.dts
+++ b/arch/powerpc/boot/dts/ksi8560.dts
@@ -306,7 +306,7 @@
306 localbus@fdf05000 { 306 localbus@fdf05000 {
307 #address-cells = <2>; 307 #address-cells = <2>;
308 #size-cells = <1>; 308 #size-cells = <1>;
309 compatible = "fsl,mpc8560-localbus"; 309 compatible = "fsl,mpc8560-localbus", "simple-bus";
310 reg = <0xfdf05000 0x68>; 310 reg = <0xfdf05000 0x68>;
311 311
312 ranges = <0x0 0x0 0xe0000000 0x00800000 312 ranges = <0x0 0x0 0xe0000000 0x00800000
diff --git a/arch/powerpc/boot/dts/mgcoge.dts b/arch/powerpc/boot/dts/mgcoge.dts
index 1360d2f69024..ededaf5ac015 100644
--- a/arch/powerpc/boot/dts/mgcoge.dts
+++ b/arch/powerpc/boot/dts/mgcoge.dts
@@ -213,6 +213,15 @@
213 linux,network-index = <2>; 213 linux,network-index = <2>;
214 fsl,cpm-command = <0x16200300>; 214 fsl,cpm-command = <0x16200300>;
215 }; 215 };
216
217 usb@11b60 {
218 compatible = "fsl,mpc8272-cpm-usb";
219 mode = "peripheral";
220 reg = <0x11b60 0x40 0x8b00 0x100>;
221 interrupts = <11 8>;
222 interrupt-parent = <&PIC>;
223 usb-clock = <5>;
224 };
216 }; 225 };
217 226
218 cpm2_pio_c: gpio-controller@10d40 { 227 cpm2_pio_c: gpio-controller@10d40 {
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi
index bc27548e895d..7ab286ab5300 100644
--- a/arch/powerpc/boot/dts/mpc5200b.dtsi
+++ b/arch/powerpc/boot/dts/mpc5200b.dtsi
@@ -147,6 +147,8 @@
147 }; 147 };
148 148
149 spi@f00 { 149 spi@f00 {
150 #address-cells = <1>;
151 #size-cells = <0>;
150 compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; 152 compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
151 reg = <0xf00 0x20>; 153 reg = <0xf00 0x20>;
152 interrupts = <2 13 0 2 14 0>; 154 interrupts = <2 13 0 2 14 0>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index b53d1df11e2d..505dc842d808 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -390,7 +390,8 @@
390 #address-cells = <2>; 390 #address-cells = <2>;
391 #size-cells = <1>; 391 #size-cells = <1>;
392 compatible = "fsl,mpc8349e-localbus", 392 compatible = "fsl,mpc8349e-localbus",
393 "fsl,pq2pro-localbus"; 393 "fsl,pq2pro-localbus",
394 "simple-bus";
394 reg = <0xe0005000 0xd8>; 395 reg = <0xe0005000 0xd8>;
395 ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ 396 ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */
396 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ 397 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */
diff --git a/arch/powerpc/boot/dts/p1022ds.dts b/arch/powerpc/boot/dts/p1022ds.dts
index 1be9743ab5e0..b9b8719a6204 100644
--- a/arch/powerpc/boot/dts/p1022ds.dts
+++ b/arch/powerpc/boot/dts/p1022ds.dts
@@ -150,7 +150,7 @@
150 }; 150 };
151 151
152 board-control@3,0 { 152 board-control@3,0 {
153 compatible = "fsl,p1022ds-pixis"; 153 compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
154 reg = <3 0 0x30>; 154 reg = <3 0 0x30>;
155 interrupt-parent = <&mpic>; 155 interrupt-parent = <&mpic>;
156 /* 156 /*
diff --git a/arch/powerpc/boot/dts/p2020ds.dts b/arch/powerpc/boot/dts/p2020ds.dts
index dae403100f2f..66f03d6477b2 100644
--- a/arch/powerpc/boot/dts/p2020ds.dts
+++ b/arch/powerpc/boot/dts/p2020ds.dts
@@ -118,6 +118,11 @@
118 }; 118 };
119 }; 119 };
120 120
121 board-control@3,0 {
122 compatible = "fsl,p2020ds-fpga", "fsl,fpga-ngpixis";
123 reg = <0x3 0x0 0x30>;
124 };
125
121 nand@4,0 { 126 nand@4,0 {
122 compatible = "fsl,elbc-fcm-nand"; 127 compatible = "fsl,elbc-fcm-nand";
123 reg = <0x4 0x0 0x40000>; 128 reg = <0x4 0x0 0x40000>;
diff --git a/arch/powerpc/boot/dts/p2040rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts
index 7d84e391c632..79b6895027c0 100644
--- a/arch/powerpc/boot/dts/p2040rdb.dts
+++ b/arch/powerpc/boot/dts/p2041rdb.dts
@@ -1,5 +1,5 @@
1/* 1/*
2 * P2040RDB Device Tree Source 2 * P2041RDB Device Tree Source
3 * 3 *
4 * Copyright 2011 Freescale Semiconductor Inc. 4 * Copyright 2011 Freescale Semiconductor Inc.
5 * 5 *
@@ -32,11 +32,11 @@
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/include/ "p2040si.dtsi" 35/include/ "p2041si.dtsi"
36 36
37/ { 37/ {
38 model = "fsl,P2040RDB"; 38 model = "fsl,P2041RDB";
39 compatible = "fsl,P2040RDB"; 39 compatible = "fsl,P2041RDB";
40 #address-cells = <2>; 40 #address-cells = <2>;
41 #size-cells = <2>; 41 #size-cells = <2>;
42 interrupt-parent = <&mpic>; 42 interrupt-parent = <&mpic>;
@@ -45,6 +45,10 @@
45 device_type = "memory"; 45 device_type = "memory";
46 }; 46 };
47 47
48 dcsr: dcsr@f00000000 {
49 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
50 };
51
48 soc: soc@ffe000000 { 52 soc: soc@ffe000000 {
49 spi@110000 { 53 spi@110000 {
50 flash@0 { 54 flash@0 {
@@ -97,13 +101,8 @@
97 }; 101 };
98 }; 102 };
99 103
100 usb0: usb@210000 {
101 phy_type = "utmi";
102 };
103
104 usb1: usb@211000 { 104 usb1: usb@211000 {
105 dr_mode = "host"; 105 dr_mode = "host";
106 phy_type = "utmi";
107 }; 106 };
108 }; 107 };
109 108
diff --git a/arch/powerpc/boot/dts/p2040si.dtsi b/arch/powerpc/boot/dts/p2041si.dtsi
index 5fdbb24c0763..f7492edd0dfd 100644
--- a/arch/powerpc/boot/dts/p2040si.dtsi
+++ b/arch/powerpc/boot/dts/p2041si.dtsi
@@ -1,5 +1,5 @@
1/* 1/*
2 * P2040 Silicon Device Tree Source 2 * P2041 Silicon Device Tree Source
3 * 3 *
4 * Copyright 2011 Freescale Semiconductor Inc. 4 * Copyright 2011 Freescale Semiconductor Inc.
5 * 5 *
@@ -35,13 +35,14 @@
35/dts-v1/; 35/dts-v1/;
36 36
37/ { 37/ {
38 compatible = "fsl,P2040"; 38 compatible = "fsl,P2041";
39 #address-cells = <2>; 39 #address-cells = <2>;
40 #size-cells = <2>; 40 #size-cells = <2>;
41 interrupt-parent = <&mpic>; 41 interrupt-parent = <&mpic>;
42 42
43 aliases { 43 aliases {
44 ccsr = &soc; 44 ccsr = &soc;
45 dcsr = &dcsr;
45 46
46 serial0 = &serial0; 47 serial0 = &serial0;
47 serial1 = &serial1; 48 serial1 = &serial1;
@@ -109,6 +110,74 @@
109 }; 110 };
110 }; 111 };
111 112
113 dcsr: dcsr@f00000000 {
114 #address-cells = <1>;
115 #size-cells = <1>;
116 compatible = "fsl,dcsr", "simple-bus";
117
118 dcsr-epu@0 {
119 compatible = "fsl,dcsr-epu";
120 interrupts = <52 2 0 0
121 84 2 0 0
122 85 2 0 0>;
123 interrupt-parent = <&mpic>;
124 reg = <0x0 0x1000>;
125 };
126 dcsr-npc {
127 compatible = "fsl,dcsr-npc";
128 reg = <0x1000 0x1000 0x1000000 0x8000>;
129 };
130 dcsr-nxc@2000 {
131 compatible = "fsl,dcsr-nxc";
132 reg = <0x2000 0x1000>;
133 };
134 dcsr-corenet {
135 compatible = "fsl,dcsr-corenet";
136 reg = <0x8000 0x1000 0xB0000 0x1000>;
137 };
138 dcsr-dpaa@9000 {
139 compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa";
140 reg = <0x9000 0x1000>;
141 };
142 dcsr-ocn@11000 {
143 compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn";
144 reg = <0x11000 0x1000>;
145 };
146 dcsr-ddr@12000 {
147 compatible = "fsl,dcsr-ddr";
148 dev-handle = <&ddr>;
149 reg = <0x12000 0x1000>;
150 };
151 dcsr-nal@18000 {
152 compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal";
153 reg = <0x18000 0x1000>;
154 };
155 dcsr-rcpm@22000 {
156 compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm";
157 reg = <0x22000 0x1000>;
158 };
159 dcsr-cpu-sb-proxy@40000 {
160 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
161 cpu-handle = <&cpu0>;
162 reg = <0x40000 0x1000>;
163 };
164 dcsr-cpu-sb-proxy@41000 {
165 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
166 cpu-handle = <&cpu1>;
167 reg = <0x41000 0x1000>;
168 };
169 dcsr-cpu-sb-proxy@42000 {
170 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
171 cpu-handle = <&cpu2>;
172 reg = <0x42000 0x1000>;
173 };
174 dcsr-cpu-sb-proxy@43000 {
175 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
176 cpu-handle = <&cpu3>;
177 reg = <0x43000 0x1000>;
178 };
179 };
180
112 soc: soc@ffe000000 { 181 soc: soc@ffe000000 {
113 #address-cells = <1>; 182 #address-cells = <1>;
114 #size-cells = <1>; 183 #size-cells = <1>;
@@ -128,14 +197,14 @@
128 fsl,num-laws = <32>; 197 fsl,num-laws = <32>;
129 }; 198 };
130 199
131 memory-controller@8000 { 200 ddr: memory-controller@8000 {
132 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; 201 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
133 reg = <0x8000 0x1000>; 202 reg = <0x8000 0x1000>;
134 interrupts = <16 2 1 23>; 203 interrupts = <16 2 1 23>;
135 }; 204 };
136 205
137 cpc: l3-cache-controller@10000 { 206 cpc: l3-cache-controller@10000 {
138 compatible = "fsl,p2040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; 207 compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
139 reg = <0x10000 0x1000>; 208 reg = <0x10000 0x1000>;
140 interrupts = <16 2 1 27>; 209 interrupts = <16 2 1 27>;
141 }; 210 };
@@ -226,7 +295,7 @@
226 }; 295 };
227 296
228 clockgen: global-utilities@e1000 { 297 clockgen: global-utilities@e1000 {
229 compatible = "fsl,p2040-clockgen", "fsl,qoriq-clockgen-1.0"; 298 compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
230 reg = <0xe1000 0x1000>; 299 reg = <0xe1000 0x1000>;
231 clock-frequency = <0>; 300 clock-frequency = <0>;
232 }; 301 };
@@ -238,45 +307,45 @@
238 }; 307 };
239 308
240 sfp: sfp@e8000 { 309 sfp: sfp@e8000 {
241 compatible = "fsl,p2040-sfp", "fsl,qoriq-sfp-1.0"; 310 compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0";
242 reg = <0xe8000 0x1000>; 311 reg = <0xe8000 0x1000>;
243 }; 312 };
244 313
245 serdes: serdes@ea000 { 314 serdes: serdes@ea000 {
246 compatible = "fsl,p2040-serdes"; 315 compatible = "fsl,p2041-serdes";
247 reg = <0xea000 0x1000>; 316 reg = <0xea000 0x1000>;
248 }; 317 };
249 318
250 dma0: dma@100300 { 319 dma0: dma@100300 {
251 #address-cells = <1>; 320 #address-cells = <1>;
252 #size-cells = <1>; 321 #size-cells = <1>;
253 compatible = "fsl,p2040-dma", "fsl,eloplus-dma"; 322 compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
254 reg = <0x100300 0x4>; 323 reg = <0x100300 0x4>;
255 ranges = <0x0 0x100100 0x200>; 324 ranges = <0x0 0x100100 0x200>;
256 cell-index = <0>; 325 cell-index = <0>;
257 dma-channel@0 { 326 dma-channel@0 {
258 compatible = "fsl,p2040-dma-channel", 327 compatible = "fsl,p2041-dma-channel",
259 "fsl,eloplus-dma-channel"; 328 "fsl,eloplus-dma-channel";
260 reg = <0x0 0x80>; 329 reg = <0x0 0x80>;
261 cell-index = <0>; 330 cell-index = <0>;
262 interrupts = <28 2 0 0>; 331 interrupts = <28 2 0 0>;
263 }; 332 };
264 dma-channel@80 { 333 dma-channel@80 {
265 compatible = "fsl,p2040-dma-channel", 334 compatible = "fsl,p2041-dma-channel",
266 "fsl,eloplus-dma-channel"; 335 "fsl,eloplus-dma-channel";
267 reg = <0x80 0x80>; 336 reg = <0x80 0x80>;
268 cell-index = <1>; 337 cell-index = <1>;
269 interrupts = <29 2 0 0>; 338 interrupts = <29 2 0 0>;
270 }; 339 };
271 dma-channel@100 { 340 dma-channel@100 {
272 compatible = "fsl,p2040-dma-channel", 341 compatible = "fsl,p2041-dma-channel",
273 "fsl,eloplus-dma-channel"; 342 "fsl,eloplus-dma-channel";
274 reg = <0x100 0x80>; 343 reg = <0x100 0x80>;
275 cell-index = <2>; 344 cell-index = <2>;
276 interrupts = <30 2 0 0>; 345 interrupts = <30 2 0 0>;
277 }; 346 };
278 dma-channel@180 { 347 dma-channel@180 {
279 compatible = "fsl,p2040-dma-channel", 348 compatible = "fsl,p2041-dma-channel",
280 "fsl,eloplus-dma-channel"; 349 "fsl,eloplus-dma-channel";
281 reg = <0x180 0x80>; 350 reg = <0x180 0x80>;
282 cell-index = <3>; 351 cell-index = <3>;
@@ -287,33 +356,33 @@
287 dma1: dma@101300 { 356 dma1: dma@101300 {
288 #address-cells = <1>; 357 #address-cells = <1>;
289 #size-cells = <1>; 358 #size-cells = <1>;
290 compatible = "fsl,p2040-dma", "fsl,eloplus-dma"; 359 compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
291 reg = <0x101300 0x4>; 360 reg = <0x101300 0x4>;
292 ranges = <0x0 0x101100 0x200>; 361 ranges = <0x0 0x101100 0x200>;
293 cell-index = <1>; 362 cell-index = <1>;
294 dma-channel@0 { 363 dma-channel@0 {
295 compatible = "fsl,p2040-dma-channel", 364 compatible = "fsl,p2041-dma-channel",
296 "fsl,eloplus-dma-channel"; 365 "fsl,eloplus-dma-channel";
297 reg = <0x0 0x80>; 366 reg = <0x0 0x80>;
298 cell-index = <0>; 367 cell-index = <0>;
299 interrupts = <32 2 0 0>; 368 interrupts = <32 2 0 0>;
300 }; 369 };
301 dma-channel@80 { 370 dma-channel@80 {
302 compatible = "fsl,p2040-dma-channel", 371 compatible = "fsl,p2041-dma-channel",
303 "fsl,eloplus-dma-channel"; 372 "fsl,eloplus-dma-channel";
304 reg = <0x80 0x80>; 373 reg = <0x80 0x80>;
305 cell-index = <1>; 374 cell-index = <1>;
306 interrupts = <33 2 0 0>; 375 interrupts = <33 2 0 0>;
307 }; 376 };
308 dma-channel@100 { 377 dma-channel@100 {
309 compatible = "fsl,p2040-dma-channel", 378 compatible = "fsl,p2041-dma-channel",
310 "fsl,eloplus-dma-channel"; 379 "fsl,eloplus-dma-channel";
311 reg = <0x100 0x80>; 380 reg = <0x100 0x80>;
312 cell-index = <2>; 381 cell-index = <2>;
313 interrupts = <34 2 0 0>; 382 interrupts = <34 2 0 0>;
314 }; 383 };
315 dma-channel@180 { 384 dma-channel@180 {
316 compatible = "fsl,p2040-dma-channel", 385 compatible = "fsl,p2041-dma-channel",
317 "fsl,eloplus-dma-channel"; 386 "fsl,eloplus-dma-channel";
318 reg = <0x180 0x80>; 387 reg = <0x180 0x80>;
319 cell-index = <3>; 388 cell-index = <3>;
@@ -324,22 +393,20 @@
324 spi@110000 { 393 spi@110000 {
325 #address-cells = <1>; 394 #address-cells = <1>;
326 #size-cells = <0>; 395 #size-cells = <0>;
327 compatible = "fsl,p2040-espi", "fsl,mpc8536-espi"; 396 compatible = "fsl,p2041-espi", "fsl,mpc8536-espi";
328 reg = <0x110000 0x1000>; 397 reg = <0x110000 0x1000>;
329 interrupts = <53 0x2 0 0>; 398 interrupts = <53 0x2 0 0>;
330 fsl,espi-num-chipselects = <4>; 399 fsl,espi-num-chipselects = <4>;
331
332 }; 400 };
333 401
334 sdhc: sdhc@114000 { 402 sdhc: sdhc@114000 {
335 compatible = "fsl,p2040-esdhc", "fsl,esdhc"; 403 compatible = "fsl,p2041-esdhc", "fsl,esdhc";
336 reg = <0x114000 0x1000>; 404 reg = <0x114000 0x1000>;
337 interrupts = <48 2 0 0>; 405 interrupts = <48 2 0 0>;
338 sdhci,auto-cmd12; 406 sdhci,auto-cmd12;
339 clock-frequency = <0>; 407 clock-frequency = <0>;
340 }; 408 };
341 409
342
343 i2c@118000 { 410 i2c@118000 {
344 #address-cells = <1>; 411 #address-cells = <1>;
345 #size-cells = <0>; 412 #size-cells = <0>;
@@ -417,7 +484,7 @@
417 }; 484 };
418 485
419 gpio0: gpio@130000 { 486 gpio0: gpio@130000 {
420 compatible = "fsl,p2040-gpio", "fsl,qoriq-gpio"; 487 compatible = "fsl,p2041-gpio", "fsl,qoriq-gpio";
421 reg = <0x130000 0x1000>; 488 reg = <0x130000 0x1000>;
422 interrupts = <55 2 0 0>; 489 interrupts = <55 2 0 0>;
423 #gpio-cells = <2>; 490 #gpio-cells = <2>;
@@ -425,32 +492,34 @@
425 }; 492 };
426 493
427 usb0: usb@210000 { 494 usb0: usb@210000 {
428 compatible = "fsl,p2040-usb2-mph", 495 compatible = "fsl,p2041-usb2-mph",
429 "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; 496 "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
430 reg = <0x210000 0x1000>; 497 reg = <0x210000 0x1000>;
431 #address-cells = <1>; 498 #address-cells = <1>;
432 #size-cells = <0>; 499 #size-cells = <0>;
433 interrupts = <44 0x2 0 0>; 500 interrupts = <44 0x2 0 0>;
501 phy_type = "utmi";
434 port0; 502 port0;
435 }; 503 };
436 504
437 usb1: usb@211000 { 505 usb1: usb@211000 {
438 compatible = "fsl,p2040-usb2-dr", 506 compatible = "fsl,p2041-usb2-dr",
439 "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; 507 "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
440 reg = <0x211000 0x1000>; 508 reg = <0x211000 0x1000>;
441 #address-cells = <1>; 509 #address-cells = <1>;
442 #size-cells = <0>; 510 #size-cells = <0>;
443 interrupts = <45 0x2 0 0>; 511 interrupts = <45 0x2 0 0>;
512 phy_type = "utmi";
444 }; 513 };
445 514
446 sata@220000 { 515 sata@220000 {
447 compatible = "fsl,p2040-sata", "fsl,pq-sata-v2"; 516 compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
448 reg = <0x220000 0x1000>; 517 reg = <0x220000 0x1000>;
449 interrupts = <68 0x2 0 0>; 518 interrupts = <68 0x2 0 0>;
450 }; 519 };
451 520
452 sata@221000 { 521 sata@221000 {
453 compatible = "fsl,p2040-sata", "fsl,pq-sata-v2"; 522 compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
454 reg = <0x221000 0x1000>; 523 reg = <0x221000 0x1000>;
455 interrupts = <69 0x2 0 0>; 524 interrupts = <69 0x2 0 0>;
456 }; 525 };
@@ -534,19 +603,19 @@
534 }; 603 };
535 604
536 localbus@ffe124000 { 605 localbus@ffe124000 {
537 compatible = "fsl,p2040-elbc", "fsl,elbc", "simple-bus"; 606 compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus";
538 interrupts = <25 2 0 0>; 607 interrupts = <25 2 0 0>;
539 #address-cells = <2>; 608 #address-cells = <2>;
540 #size-cells = <1>; 609 #size-cells = <1>;
541 }; 610 };
542 611
543 pci0: pcie@ffe200000 { 612 pci0: pcie@ffe200000 {
544 compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; 613 compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
545 device_type = "pci"; 614 device_type = "pci";
546 #size-cells = <2>; 615 #size-cells = <2>;
547 #address-cells = <3>; 616 #address-cells = <3>;
548 bus-range = <0x0 0xff>; 617 bus-range = <0x0 0xff>;
549 clock-frequency = <0x1fca055>; 618 clock-frequency = <33333333>;
550 fsl,msi = <&msi0>; 619 fsl,msi = <&msi0>;
551 interrupts = <16 2 1 15>; 620 interrupts = <16 2 1 15>;
552 pcie@0 { 621 pcie@0 {
@@ -568,12 +637,12 @@
568 }; 637 };
569 638
570 pci1: pcie@ffe201000 { 639 pci1: pcie@ffe201000 {
571 compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; 640 compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
572 device_type = "pci"; 641 device_type = "pci";
573 #size-cells = <2>; 642 #size-cells = <2>;
574 #address-cells = <3>; 643 #address-cells = <3>;
575 bus-range = <0 0xff>; 644 bus-range = <0 0xff>;
576 clock-frequency = <0x1fca055>; 645 clock-frequency = <33333333>;
577 fsl,msi = <&msi1>; 646 fsl,msi = <&msi1>;
578 interrupts = <16 2 1 14>; 647 interrupts = <16 2 1 14>;
579 pcie@0 { 648 pcie@0 {
@@ -595,12 +664,12 @@
595 }; 664 };
596 665
597 pci2: pcie@ffe202000 { 666 pci2: pcie@ffe202000 {
598 compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2"; 667 compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
599 device_type = "pci"; 668 device_type = "pci";
600 #size-cells = <2>; 669 #size-cells = <2>;
601 #address-cells = <3>; 670 #address-cells = <3>;
602 bus-range = <0x0 0xff>; 671 bus-range = <0x0 0xff>;
603 clock-frequency = <0x1fca055>; 672 clock-frequency = <33333333>;
604 fsl,msi = <&msi2>; 673 fsl,msi = <&msi2>;
605 interrupts = <16 2 1 13>; 674 interrupts = <16 2 1 13>;
606 pcie@0 { 675 pcie@0 {
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts
index 69cae674f396..bbd113b49a8f 100644
--- a/arch/powerpc/boot/dts/p3041ds.dts
+++ b/arch/powerpc/boot/dts/p3041ds.dts
@@ -45,6 +45,10 @@
45 device_type = "memory"; 45 device_type = "memory";
46 }; 46 };
47 47
48 dcsr: dcsr@f00000000 {
49 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
50 };
51
48 soc: soc@ffe000000 { 52 soc: soc@ffe000000 {
49 spi@110000 { 53 spi@110000 {
50 flash@0 { 54 flash@0 {
@@ -147,8 +151,8 @@
147 }; 151 };
148 152
149 board-control@3,0 { 153 board-control@3,0 {
150 compatible = "fsl,p3041ds-pixis"; 154 compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
151 reg = <3 0 0x20>; 155 reg = <3 0 0x30>;
152 }; 156 };
153 }; 157 };
154 158
diff --git a/arch/powerpc/boot/dts/p3041si.dtsi b/arch/powerpc/boot/dts/p3041si.dtsi
index 8b695801f505..87130b732bc7 100644
--- a/arch/powerpc/boot/dts/p3041si.dtsi
+++ b/arch/powerpc/boot/dts/p3041si.dtsi
@@ -42,6 +42,7 @@
42 42
43 aliases { 43 aliases {
44 ccsr = &soc; 44 ccsr = &soc;
45 dcsr = &dcsr;
45 46
46 serial0 = &serial0; 47 serial0 = &serial0;
47 serial1 = &serial1; 48 serial1 = &serial1;
@@ -114,6 +115,74 @@
114 }; 115 };
115 }; 116 };
116 117
118 dcsr: dcsr@f00000000 {
119 #address-cells = <1>;
120 #size-cells = <1>;
121 compatible = "fsl,dcsr", "simple-bus";
122
123 dcsr-epu@0 {
124 compatible = "fsl,dcsr-epu";
125 interrupts = <52 2 0 0
126 84 2 0 0
127 85 2 0 0>;
128 interrupt-parent = <&mpic>;
129 reg = <0x0 0x1000>;
130 };
131 dcsr-npc {
132 compatible = "fsl,dcsr-npc";
133 reg = <0x1000 0x1000 0x1000000 0x8000>;
134 };
135 dcsr-nxc@2000 {
136 compatible = "fsl,dcsr-nxc";
137 reg = <0x2000 0x1000>;
138 };
139 dcsr-corenet {
140 compatible = "fsl,dcsr-corenet";
141 reg = <0x8000 0x1000 0xB0000 0x1000>;
142 };
143 dcsr-dpaa@9000 {
144 compatible = "fsl,p43041-dcsr-dpaa", "fsl,dcsr-dpaa";
145 reg = <0x9000 0x1000>;
146 };
147 dcsr-ocn@11000 {
148 compatible = "fsl,p43041-dcsr-ocn", "fsl,dcsr-ocn";
149 reg = <0x11000 0x1000>;
150 };
151 dcsr-ddr@12000 {
152 compatible = "fsl,dcsr-ddr";
153 dev-handle = <&ddr>;
154 reg = <0x12000 0x1000>;
155 };
156 dcsr-nal@18000 {
157 compatible = "fsl,p43041-dcsr-nal", "fsl,dcsr-nal";
158 reg = <0x18000 0x1000>;
159 };
160 dcsr-rcpm@22000 {
161 compatible = "fsl,p43041-dcsr-rcpm", "fsl,dcsr-rcpm";
162 reg = <0x22000 0x1000>;
163 };
164 dcsr-cpu-sb-proxy@40000 {
165 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
166 cpu-handle = <&cpu0>;
167 reg = <0x40000 0x1000>;
168 };
169 dcsr-cpu-sb-proxy@41000 {
170 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
171 cpu-handle = <&cpu1>;
172 reg = <0x41000 0x1000>;
173 };
174 dcsr-cpu-sb-proxy@42000 {
175 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
176 cpu-handle = <&cpu2>;
177 reg = <0x42000 0x1000>;
178 };
179 dcsr-cpu-sb-proxy@43000 {
180 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
181 cpu-handle = <&cpu3>;
182 reg = <0x43000 0x1000>;
183 };
184 };
185
117 soc: soc@ffe000000 { 186 soc: soc@ffe000000 {
118 #address-cells = <1>; 187 #address-cells = <1>;
119 #size-cells = <1>; 188 #size-cells = <1>;
@@ -133,7 +202,7 @@
133 fsl,num-laws = <32>; 202 fsl,num-laws = <32>;
134 }; 203 };
135 204
136 memory-controller@8000 { 205 ddr: memory-controller@8000 {
137 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; 206 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
138 reg = <0x8000 0x1000>; 207 reg = <0x8000 0x1000>;
139 interrupts = <16 2 1 23>; 208 interrupts = <16 2 1 23>;
diff --git a/arch/powerpc/boot/dts/p3060qds.dts b/arch/powerpc/boot/dts/p3060qds.dts
new file mode 100644
index 000000000000..08b9193213e7
--- /dev/null
+++ b/arch/powerpc/boot/dts/p3060qds.dts
@@ -0,0 +1,238 @@
1/*
2 * P3060QDS Device Tree Source
3 *
4 * Copyright 2011 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/include/ "p3060si.dtsi"
36
37/ {
38 model = "fsl,P3060QDS";
39 compatible = "fsl,P3060QDS";
40 #address-cells = <2>;
41 #size-cells = <2>;
42 interrupt-parent = <&mpic>;
43
44 memory {
45 device_type = "memory";
46 };
47
48 dcsr: dcsr@f00000000 {
49 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
50 };
51
52 soc: soc@ffe000000 {
53 spi@110000 {
54 flash@0 {
55 #address-cells = <1>;
56 #size-cells = <1>;
57 compatible = "spansion,s25sl12801";
58 reg = <0>;
59 spi-max-frequency = <40000000>; /* input clock */
60 partition@u-boot {
61 label = "u-boot";
62 reg = <0x00000000 0x00100000>;
63 read-only;
64 };
65 partition@kernel {
66 label = "kernel";
67 reg = <0x00100000 0x00500000>;
68 read-only;
69 };
70 partition@dtb {
71 label = "dtb";
72 reg = <0x00600000 0x00100000>;
73 read-only;
74 };
75 partition@fs {
76 label = "file system";
77 reg = <0x00700000 0x00900000>;
78 };
79 };
80 flash@1 {
81 #address-cells = <1>;
82 #size-cells = <1>;
83 compatible = "spansion,en25q32b";
84 reg = <1>;
85 spi-max-frequency = <40000000>; /* input clock */
86 partition@spi1 {
87 label = "spi1";
88 reg = <0x00000000 0x00400000>;
89 };
90 };
91 flash@2 {
92 #address-cells = <1>;
93 #size-cells = <1>;
94 compatible = "atmel,at45db081d";
95 reg = <2>;
96 spi-max-frequency = <40000000>; /* input clock */
97 partition@spi1 {
98 label = "spi2";
99 reg = <0x00000000 0x00100000>;
100 };
101 };
102 flash@3 {
103 #address-cells = <1>;
104 #size-cells = <1>;
105 compatible = "spansion,sst25wf040";
106 reg = <3>;
107 spi-max-frequency = <40000000>; /* input clock */
108 partition@spi3 {
109 label = "spi3";
110 reg = <0x00000000 0x00080000>;
111 };
112 };
113 };
114
115 i2c@118000 {
116 eeprom@51 {
117 compatible = "at24,24c256";
118 reg = <0x51>;
119 };
120 eeprom@53 {
121 compatible = "at24,24c256";
122 reg = <0x53>;
123 };
124 rtc@68 {
125 compatible = "dallas,ds3232";
126 reg = <0x68>;
127 interrupts = <0x1 0x1 0 0>;
128 };
129 };
130
131 usb0: usb@210000 {
132 phy_type = "ulpi";
133 };
134
135 usb1: usb@211000 {
136 dr_mode = "host";
137 phy_type = "ulpi";
138 };
139 };
140
141 rapidio@ffe0c0000 {
142 reg = <0xf 0xfe0c0000 0 0x11000>;
143
144 port1 {
145 ranges = <0 0 0xc 0x20000000 0 0x10000000>;
146 };
147 port2 {
148 ranges = <0 0 0xc 0x30000000 0 0x10000000>;
149 };
150 };
151
152 localbus@ffe124000 {
153 reg = <0xf 0xfe124000 0 0x1000>;
154 ranges = <0 0 0xf 0xe8000000 0x08000000
155 2 0 0xf 0xffa00000 0x00040000
156 3 0 0xf 0xffdf0000 0x00008000>;
157
158 flash@0,0 {
159 compatible = "cfi-flash";
160 reg = <0 0 0x08000000>;
161 bank-width = <2>;
162 device-width = <2>;
163 };
164
165 nand@2,0 {
166 #address-cells = <1>;
167 #size-cells = <1>;
168 compatible = "fsl,elbc-fcm-nand";
169 reg = <0x2 0x0 0x40000>;
170
171 partition@0 {
172 label = "NAND U-Boot Image";
173 reg = <0x0 0x02000000>;
174 read-only;
175 };
176
177 partition@2000000 {
178 label = "NAND Root File System";
179 reg = <0x02000000 0x10000000>;
180 };
181
182 partition@12000000 {
183 label = "NAND Compressed RFS Image";
184 reg = <0x12000000 0x08000000>;
185 };
186
187 partition@1a000000 {
188 label = "NAND Linux Kernel Image";
189 reg = <0x1a000000 0x04000000>;
190 };
191
192 partition@1e000000 {
193 label = "NAND DTB Image";
194 reg = <0x1e000000 0x01000000>;
195 };
196
197 partition@1f000000 {
198 label = "NAND Writable User area";
199 reg = <0x1f000000 0x21000000>;
200 };
201 };
202
203 board-control@3,0 {
204 compatible = "fsl,p3060qds-fpga", "fsl,fpga-qixis";
205 reg = <3 0 0x100>;
206 };
207 };
208
209 pci0: pcie@ffe200000 {
210 reg = <0xf 0xfe200000 0 0x1000>;
211 ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
212 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
213 pcie@0 {
214 ranges = <0x02000000 0 0xe0000000
215 0x02000000 0 0xe0000000
216 0 0x20000000
217
218 0x01000000 0 0x00000000
219 0x01000000 0 0x00000000
220 0 0x00010000>;
221 };
222 };
223
224 pci1: pcie@ffe201000 {
225 reg = <0xf 0xfe201000 0 0x1000>;
226 ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
227 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
228 pcie@0 {
229 ranges = <0x02000000 0 0xe0000000
230 0x02000000 0 0xe0000000
231 0 0x20000000
232
233 0x01000000 0 0x00000000
234 0x01000000 0 0x00000000
235 0 0x00010000>;
236 };
237 };
238};
diff --git a/arch/powerpc/boot/dts/p3060si.dtsi b/arch/powerpc/boot/dts/p3060si.dtsi
new file mode 100644
index 000000000000..68947e157bbc
--- /dev/null
+++ b/arch/powerpc/boot/dts/p3060si.dtsi
@@ -0,0 +1,719 @@
1/*
2 * P3060 Silicon Device Tree Source
3 *
4 * Copyright 2011 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/dts-v1/;
36
37/ {
38 compatible = "fsl,P3060";
39 #address-cells = <2>;
40 #size-cells = <2>;
41 interrupt-parent = <&mpic>;
42
43 aliases {
44 ccsr = &soc;
45 dcsr = &dcsr;
46
47 serial0 = &serial0;
48 serial1 = &serial1;
49 serial2 = &serial2;
50 serial3 = &serial3;
51 pci0 = &pci0;
52 pci1 = &pci1;
53 usb0 = &usb0;
54 usb1 = &usb1;
55 dma0 = &dma0;
56 dma1 = &dma1;
57 msi0 = &msi0;
58 msi1 = &msi1;
59 msi2 = &msi2;
60
61 crypto = &crypto;
62 sec_jr0 = &sec_jr0;
63 sec_jr1 = &sec_jr1;
64 sec_jr2 = &sec_jr2;
65 sec_jr3 = &sec_jr3;
66 rtic_a = &rtic_a;
67 rtic_b = &rtic_b;
68 rtic_c = &rtic_c;
69 rtic_d = &rtic_d;
70 sec_mon = &sec_mon;
71 };
72
73 cpus {
74 #address-cells = <1>;
75 #size-cells = <0>;
76
77 cpu0: PowerPC,e500mc@0 {
78 device_type = "cpu";
79 reg = <0>;
80 next-level-cache = <&L2_0>;
81 L2_0: l2-cache {
82 next-level-cache = <&cpc>;
83 };
84 };
85 cpu1: PowerPC,e500mc@1 {
86 device_type = "cpu";
87 reg = <1>;
88 next-level-cache = <&L2_1>;
89 L2_1: l2-cache {
90 next-level-cache = <&cpc>;
91 };
92 };
93 cpu4: PowerPC,e500mc@4 {
94 device_type = "cpu";
95 reg = <4>;
96 next-level-cache = <&L2_4>;
97 L2_4: l2-cache {
98 next-level-cache = <&cpc>;
99 };
100 };
101 cpu5: PowerPC,e500mc@5 {
102 device_type = "cpu";
103 reg = <5>;
104 next-level-cache = <&L2_5>;
105 L2_5: l2-cache {
106 next-level-cache = <&cpc>;
107 };
108 };
109 cpu6: PowerPC,e500mc@6 {
110 device_type = "cpu";
111 reg = <6>;
112 next-level-cache = <&L2_6>;
113 L2_6: l2-cache {
114 next-level-cache = <&cpc>;
115 };
116 };
117 cpu7: PowerPC,e500mc@7 {
118 device_type = "cpu";
119 reg = <7>;
120 next-level-cache = <&L2_7>;
121 L2_7: l2-cache {
122 next-level-cache = <&cpc>;
123 };
124 };
125 };
126
127 dcsr: dcsr@f00000000 {
128 #address-cells = <1>;
129 #size-cells = <1>;
130 compatible = "fsl,dcsr", "simple-bus";
131
132 dcsr-epu@0 {
133 compatible = "fsl,dcsr-epu";
134 interrupts = <52 2 0 0
135 84 2 0 0
136 85 2 0 0>;
137 interrupt-parent = <&mpic>;
138 reg = <0x0 0x1000>;
139 };
140 dcsr-npc {
141 compatible = "fsl,dcsr-npc";
142 reg = <0x1000 0x1000 0x1000000 0x8000>;
143 };
144 dcsr-nxc@2000 {
145 compatible = "fsl,dcsr-nxc";
146 reg = <0x2000 0x1000>;
147 };
148 dcsr-corenet {
149 compatible = "fsl,dcsr-corenet";
150 reg = <0x8000 0x1000 0xB0000 0x1000>;
151 };
152 dcsr-dpaa@9000 {
153 compatible = "fsl,p3060-dcsr-dpaa", "fsl,dcsr-dpaa";
154 reg = <0x9000 0x1000>;
155 };
156 dcsr-ocn@11000 {
157 compatible = "fsl,p3060-dcsr-ocn", "fsl,dcsr-ocn";
158 reg = <0x11000 0x1000>;
159 };
160 dcsr-ddr@12000 {
161 compatible = "fsl,dcsr-ddr";
162 dev-handle = <&ddr>;
163 reg = <0x12000 0x1000>;
164 };
165 dcsr-nal@18000 {
166 compatible = "fsl,p3060-dcsr-nal", "fsl,dcsr-nal";
167 reg = <0x18000 0x1000>;
168 };
169 dcsr-rcpm@22000 {
170 compatible = "fsl,p3060-dcsr-rcpm", "fsl,dcsr-rcpm";
171 reg = <0x22000 0x1000>;
172 };
173 dcsr-cpu-sb-proxy@40000 {
174 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
175 cpu-handle = <&cpu0>;
176 reg = <0x40000 0x1000>;
177 };
178 dcsr-cpu-sb-proxy@41000 {
179 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
180 cpu-handle = <&cpu1>;
181 reg = <0x41000 0x1000>;
182 };
183 dcsr-cpu-sb-proxy@44000 {
184 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
185 cpu-handle = <&cpu4>;
186 reg = <0x44000 0x1000>;
187 };
188 dcsr-cpu-sb-proxy@45000 {
189 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
190 cpu-handle = <&cpu5>;
191 reg = <0x45000 0x1000>;
192 };
193 dcsr-cpu-sb-proxy@46000 {
194 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
195 cpu-handle = <&cpu6>;
196 reg = <0x46000 0x1000>;
197 };
198 dcsr-cpu-sb-proxy@47000 {
199 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
200 cpu-handle = <&cpu7>;
201 reg = <0x47000 0x1000>;
202 };
203 };
204
205 soc: soc@ffe000000 {
206 #address-cells = <1>;
207 #size-cells = <1>;
208 device_type = "soc";
209 compatible = "simple-bus";
210 ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
211 reg = <0xf 0xfe000000 0 0x00001000>;
212
213 soc-sram-error {
214 compatible = "fsl,soc-sram-error";
215 interrupts = <16 2 1 29>;
216 };
217
218 corenet-law@0 {
219 compatible = "fsl,corenet-law";
220 reg = <0x0 0x1000>;
221 fsl,num-laws = <32>;
222 };
223
224 ddr: memory-controller@8000 {
225 compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller";
226 reg = <0x8000 0x1000>;
227 interrupts = <16 2 1 23>;
228 };
229
230 cpc: l3-cache-controller@10000 {
231 compatible = "fsl,p3060-l3-cache-controller", "cache";
232 reg = <0x10000 0x1000
233 0x11000 0x1000>;
234 interrupts = <16 2 1 27>;
235 };
236
237 corenet-cf@18000 {
238 compatible = "fsl,corenet-cf";
239 reg = <0x18000 0x1000>;
240 interrupts = <16 2 1 31>;
241 fsl,ccf-num-csdids = <32>;
242 fsl,ccf-num-snoopids = <32>;
243 };
244
245 iommu@20000 {
246 compatible = "fsl,pamu-v1.0", "fsl,pamu";
247 reg = <0x20000 0x5000>;
248 interrupts = <
249 24 2 0 0
250 16 2 1 30>;
251 };
252
253 mpic: pic@40000 {
254 clock-frequency = <0>;
255 interrupt-controller;
256 #address-cells = <0>;
257 #interrupt-cells = <4>;
258 reg = <0x40000 0x40000>;
259 compatible = "fsl,mpic", "chrp,open-pic";
260 device_type = "open-pic";
261 };
262
263 msi0: msi@41600 {
264 compatible = "fsl,mpic-msi";
265 reg = <0x41600 0x200>;
266 msi-available-ranges = <0 0x100>;
267 interrupts = <
268 0xe0 0 0 0
269 0xe1 0 0 0
270 0xe2 0 0 0
271 0xe3 0 0 0
272 0xe4 0 0 0
273 0xe5 0 0 0
274 0xe6 0 0 0
275 0xe7 0 0 0>;
276 };
277
278 msi1: msi@41800 {
279 compatible = "fsl,mpic-msi";
280 reg = <0x41800 0x200>;
281 msi-available-ranges = <0 0x100>;
282 interrupts = <
283 0xe8 0 0 0
284 0xe9 0 0 0
285 0xea 0 0 0
286 0xeb 0 0 0
287 0xec 0 0 0
288 0xed 0 0 0
289 0xee 0 0 0
290 0xef 0 0 0>;
291 };
292
293 msi2: msi@41a00 {
294 compatible = "fsl,mpic-msi";
295 reg = <0x41a00 0x200>;
296 msi-available-ranges = <0 0x100>;
297 interrupts = <
298 0xf0 0 0 0
299 0xf1 0 0 0
300 0xf2 0 0 0
301 0xf3 0 0 0
302 0xf4 0 0 0
303 0xf5 0 0 0
304 0xf6 0 0 0
305 0xf7 0 0 0>;
306 };
307
308 rmu: rmu@d3000 {
309 #address-cells = <1>;
310 #size-cells = <1>;
311 compatible = "fsl,srio-rmu";
312 reg = <0xd3000 0x500>;
313 ranges = <0x0 0xd3000 0x500>;
314
315 message-unit@0 {
316 compatible = "fsl,srio-msg-unit";
317 reg = <0x0 0x100>;
318 interrupts = <
319 60 2 0 0 /* msg1_tx_irq */
320 61 2 0 0>;/* msg1_rx_irq */
321 };
322 message-unit@100 {
323 compatible = "fsl,srio-msg-unit";
324 reg = <0x100 0x100>;
325 interrupts = <
326 62 2 0 0 /* msg2_tx_irq */
327 63 2 0 0>;/* msg2_rx_irq */
328 };
329 doorbell-unit@400 {
330 compatible = "fsl,srio-dbell-unit";
331 reg = <0x400 0x80>;
332 interrupts = <
333 56 2 0 0 /* bell_outb_irq */
334 57 2 0 0>;/* bell_inb_irq */
335 };
336 port-write-unit@4e0 {
337 compatible = "fsl,srio-port-write-unit";
338 reg = <0x4e0 0x20>;
339 interrupts = <16 2 1 11>;
340 };
341 };
342
343 guts: global-utilities@e0000 {
344 compatible = "fsl,qoriq-device-config-1.0";
345 reg = <0xe0000 0xe00>;
346 fsl,has-rstcr;
347 #sleep-cells = <1>;
348 fsl,liodn-bits = <12>;
349 };
350
351 pins: global-utilities@e0e00 {
352 compatible = "fsl,qoriq-pin-control-1.0";
353 reg = <0xe0e00 0x200>;
354 #sleep-cells = <2>;
355 };
356
357 clockgen: global-utilities@e1000 {
358 compatible = "fsl,p3060-clockgen", "fsl,qoriq-clockgen-1.0";
359 reg = <0xe1000 0x1000>;
360 clock-frequency = <0>;
361 };
362
363 rcpm: global-utilities@e2000 {
364 compatible = "fsl,qoriq-rcpm-1.0";
365 reg = <0xe2000 0x1000>;
366 #sleep-cells = <1>;
367 };
368
369 sfp: sfp@e8000 {
370 compatible = "fsl,p3060-sfp", "fsl,qoriq-sfp-1.0";
371 reg = <0xe8000 0x1000>;
372 };
373
374 serdes: serdes@ea000 {
375 compatible = "fsl,p3060-serdes";
376 reg = <0xea000 0x1000>;
377 };
378
379 dma0: dma@100300 {
380 #address-cells = <1>;
381 #size-cells = <1>;
382 compatible = "fsl,p3060-dma", "fsl,eloplus-dma";
383 reg = <0x100300 0x4>;
384 ranges = <0x0 0x100100 0x200>;
385 cell-index = <0>;
386 dma-channel@0 {
387 compatible = "fsl,p3060-dma-channel",
388 "fsl,eloplus-dma-channel";
389 reg = <0x0 0x80>;
390 cell-index = <0>;
391 interrupts = <28 2 0 0>;
392 };
393 dma-channel@80 {
394 compatible = "fsl,p3060-dma-channel",
395 "fsl,eloplus-dma-channel";
396 reg = <0x80 0x80>;
397 cell-index = <1>;
398 interrupts = <29 2 0 0>;
399 };
400 dma-channel@100 {
401 compatible = "fsl,p3060-dma-channel",
402 "fsl,eloplus-dma-channel";
403 reg = <0x100 0x80>;
404 cell-index = <2>;
405 interrupts = <30 2 0 0>;
406 };
407 dma-channel@180 {
408 compatible = "fsl,p3060-dma-channel",
409 "fsl,eloplus-dma-channel";
410 reg = <0x180 0x80>;
411 cell-index = <3>;
412 interrupts = <31 2 0 0>;
413 };
414 };
415
416 dma1: dma@101300 {
417 #address-cells = <1>;
418 #size-cells = <1>;
419 compatible = "fsl,p3060-dma", "fsl,eloplus-dma";
420 reg = <0x101300 0x4>;
421 ranges = <0x0 0x101100 0x200>;
422 cell-index = <1>;
423 dma-channel@0 {
424 compatible = "fsl,p3060-dma-channel",
425 "fsl,eloplus-dma-channel";
426 reg = <0x0 0x80>;
427 cell-index = <0>;
428 interrupts = <32 2 0 0>;
429 };
430 dma-channel@80 {
431 compatible = "fsl,p3060-dma-channel",
432 "fsl,eloplus-dma-channel";
433 reg = <0x80 0x80>;
434 cell-index = <1>;
435 interrupts = <33 2 0 0>;
436 };
437 dma-channel@100 {
438 compatible = "fsl,p3060-dma-channel",
439 "fsl,eloplus-dma-channel";
440 reg = <0x100 0x80>;
441 cell-index = <2>;
442 interrupts = <34 2 0 0>;
443 };
444 dma-channel@180 {
445 compatible = "fsl,p3060-dma-channel",
446 "fsl,eloplus-dma-channel";
447 reg = <0x180 0x80>;
448 cell-index = <3>;
449 interrupts = <35 2 0 0>;
450 };
451 };
452
453 spi@110000 {
454 #address-cells = <1>;
455 #size-cells = <0>;
456 compatible = "fsl,p3060-espi", "fsl,mpc8536-espi";
457 reg = <0x110000 0x1000>;
458 interrupts = <53 0x2 0 0>;
459 fsl,espi-num-chipselects = <4>;
460 };
461
462 i2c@118000 {
463 #address-cells = <1>;
464 #size-cells = <0>;
465 cell-index = <0>;
466 compatible = "fsl-i2c";
467 reg = <0x118000 0x100>;
468 interrupts = <38 2 0 0>;
469 dfsrr;
470 };
471
472 i2c@118100 {
473 #address-cells = <1>;
474 #size-cells = <0>;
475 cell-index = <1>;
476 compatible = "fsl-i2c";
477 reg = <0x118100 0x100>;
478 interrupts = <38 2 0 0>;
479 dfsrr;
480 };
481
482 i2c@119000 {
483 #address-cells = <1>;
484 #size-cells = <0>;
485 cell-index = <2>;
486 compatible = "fsl-i2c";
487 reg = <0x119000 0x100>;
488 interrupts = <39 2 0 0>;
489 dfsrr;
490 };
491
492 i2c@119100 {
493 #address-cells = <1>;
494 #size-cells = <0>;
495 cell-index = <3>;
496 compatible = "fsl-i2c";
497 reg = <0x119100 0x100>;
498 interrupts = <39 2 0 0>;
499 dfsrr;
500 };
501
502 serial0: serial@11c500 {
503 cell-index = <0>;
504 device_type = "serial";
505 compatible = "ns16550";
506 reg = <0x11c500 0x100>;
507 clock-frequency = <0>;
508 interrupts = <36 2 0 0>;
509 };
510
511 serial1: serial@11c600 {
512 cell-index = <1>;
513 device_type = "serial";
514 compatible = "ns16550";
515 reg = <0x11c600 0x100>;
516 clock-frequency = <0>;
517 interrupts = <36 2 0 0>;
518 };
519
520 serial2: serial@11d500 {
521 cell-index = <2>;
522 device_type = "serial";
523 compatible = "ns16550";
524 reg = <0x11d500 0x100>;
525 clock-frequency = <0>;
526 interrupts = <37 2 0 0>;
527 };
528
529 serial3: serial@11d600 {
530 cell-index = <3>;
531 device_type = "serial";
532 compatible = "ns16550";
533 reg = <0x11d600 0x100>;
534 clock-frequency = <0>;
535 interrupts = <37 2 0 0>;
536 };
537
538 gpio0: gpio@130000 {
539 compatible = "fsl,p3060-gpio", "fsl,qoriq-gpio";
540 reg = <0x130000 0x1000>;
541 interrupts = <55 2 0 0>;
542 #gpio-cells = <2>;
543 gpio-controller;
544 };
545
546 usb0: usb@210000 {
547 compatible = "fsl,p3060-usb2-mph",
548 "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
549 reg = <0x210000 0x1000>;
550 #address-cells = <1>;
551 #size-cells = <0>;
552 interrupts = <44 0x2 0 0>;
553 };
554
555 usb1: usb@211000 {
556 compatible = "fsl,p3060-usb2-dr",
557 "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
558 reg = <0x211000 0x1000>;
559 #address-cells = <1>;
560 #size-cells = <0>;
561 interrupts = <45 0x2 0 0>;
562 };
563
564 crypto: crypto@300000 {
565 compatible = "fsl,sec-v4.1", "fsl,sec-v4.0";
566 #address-cells = <1>;
567 #size-cells = <1>;
568 reg = <0x300000 0x10000>;
569 ranges = <0 0x300000 0x10000>;
570 interrupt-parent = <&mpic>;
571 interrupts = <92 2 0 0>;
572
573 sec_jr0: jr@1000 {
574 compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
575 reg = <0x1000 0x1000>;
576 interrupt-parent = <&mpic>;
577 interrupts = <88 2 0 0>;
578 };
579
580 sec_jr1: jr@2000 {
581 compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
582 reg = <0x2000 0x1000>;
583 interrupt-parent = <&mpic>;
584 interrupts = <89 2 0 0>;
585 };
586
587 sec_jr2: jr@3000 {
588 compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
589 reg = <0x3000 0x1000>;
590 interrupt-parent = <&mpic>;
591 interrupts = <90 2 0 0>;
592 };
593
594 sec_jr3: jr@4000 {
595 compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
596 reg = <0x4000 0x1000>;
597 interrupt-parent = <&mpic>;
598 interrupts = <91 2 0 0>;
599 };
600
601 rtic@6000 {
602 compatible = "fsl,sec-v4.1-rtic", "fsl,sec-v4.0-rtic";
603 #address-cells = <1>;
604 #size-cells = <1>;
605 reg = <0x6000 0x100>;
606 ranges = <0x0 0x6100 0xe00>;
607
608 rtic_a: rtic-a@0 {
609 compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
610 reg = <0x00 0x20 0x100 0x80>;
611 };
612
613 rtic_b: rtic-b@20 {
614 compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
615 reg = <0x20 0x20 0x200 0x80>;
616 };
617
618 rtic_c: rtic-c@40 {
619 compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
620 reg = <0x40 0x20 0x300 0x80>;
621 };
622
623 rtic_d: rtic-d@60 {
624 compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
625 reg = <0x60 0x20 0x500 0x80>;
626 };
627 };
628 };
629
630 sec_mon: sec_mon@314000 {
631 compatible = "fsl,sec-v4.1-mon", "fsl,sec-v4.0-mon";
632 reg = <0x314000 0x1000>;
633 interrupt-parent = <&mpic>;
634 interrupts = <93 2 0 0>;
635 };
636 };
637
638 rapidio@ffe0c0000 {
639 compatible = "fsl,srio";
640 interrupts = <16 2 1 11>;
641 #address-cells = <2>;
642 #size-cells = <2>;
643 fsl,srio-rmu-handle = <&rmu>;
644 ranges;
645
646 port1 {
647 #address-cells = <2>;
648 #size-cells = <2>;
649 cell-index = <1>;
650 };
651
652 port2 {
653 #address-cells = <2>;
654 #size-cells = <2>;
655 cell-index = <2>;
656 };
657 };
658
659 localbus@ffe124000 {
660 compatible = "fsl,p3060-elbc", "fsl,elbc", "simple-bus";
661 interrupts = <25 2 0 0>;
662 #address-cells = <2>;
663 #size-cells = <1>;
664 };
665
666 pci0: pcie@ffe200000 {
667 compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2";
668 device_type = "pci";
669 #size-cells = <2>;
670 #address-cells = <3>;
671 bus-range = <0x0 0xff>;
672 clock-frequency = <33333333>;
673 fsl,msi = <&msi0>;
674 interrupts = <16 2 1 15>;
675 pcie@0 {
676 reg = <0 0 0 0 0>;
677 #interrupt-cells = <1>;
678 #size-cells = <2>;
679 #address-cells = <3>;
680 device_type = "pci";
681 interrupts = <16 2 1 15>;
682 interrupt-map-mask = <0xf800 0 0 7>;
683 interrupt-map = <
684 /* IDSEL 0x0 */
685 0000 0 0 1 &mpic 40 1 0 0
686 0000 0 0 2 &mpic 1 1 0 0
687 0000 0 0 3 &mpic 2 1 0 0
688 0000 0 0 4 &mpic 3 1 0 0
689 >;
690 };
691 };
692
693 pci1: pcie@ffe201000 {
694 compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2";
695 device_type = "pci";
696 #size-cells = <2>;
697 #address-cells = <3>;
698 bus-range = <0 0xff>;
699 clock-frequency = <33333333>;
700 fsl,msi = <&msi1>;
701 interrupts = <16 2 1 14>;
702 pcie@0 {
703 reg = <0 0 0 0 0>;
704 #interrupt-cells = <1>;
705 #size-cells = <2>;
706 #address-cells = <3>;
707 device_type = "pci";
708 interrupts = <16 2 1 14>;
709 interrupt-map-mask = <0xf800 0 0 7>;
710 interrupt-map = <
711 /* IDSEL 0x0 */
712 0000 0 0 1 &mpic 41 1 0 0
713 0000 0 0 2 &mpic 5 1 0 0
714 0000 0 0 3 &mpic 6 1 0 0
715 0000 0 0 4 &mpic 7 1 0 0
716 >;
717 };
718 };
719};
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts
index eb11098bb687..c7916dc28014 100644
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ b/arch/powerpc/boot/dts/p4080ds.dts
@@ -45,6 +45,10 @@
45 device_type = "memory"; 45 device_type = "memory";
46 }; 46 };
47 47
48 dcsr: dcsr@f00000000 {
49 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
50 };
51
48 soc: soc@ffe000000 { 52 soc: soc@ffe000000 {
49 spi@110000 { 53 spi@110000 {
50 flash@0 { 54 flash@0 {
@@ -108,7 +112,8 @@
108 112
109 localbus@ffe124000 { 113 localbus@ffe124000 {
110 reg = <0xf 0xfe124000 0 0x1000>; 114 reg = <0xf 0xfe124000 0 0x1000>;
111 ranges = <0 0 0xf 0xe8000000 0x08000000>; 115 ranges = <0 0 0xf 0xe8000000 0x08000000
116 3 0 0xf 0xffdf0000 0x00008000>;
112 117
113 flash@0,0 { 118 flash@0,0 {
114 compatible = "cfi-flash"; 119 compatible = "cfi-flash";
@@ -116,6 +121,11 @@
116 bank-width = <2>; 121 bank-width = <2>;
117 device-width = <2>; 122 device-width = <2>;
118 }; 123 };
124
125 board-control@3,0 {
126 compatible = "fsl,p4080ds-fpga", "fsl,fpga-ngpixis";
127 reg = <3 0 0x30>;
128 };
119 }; 129 };
120 130
121 pci0: pcie@ffe200000 { 131 pci0: pcie@ffe200000 {
diff --git a/arch/powerpc/boot/dts/p4080si.dtsi b/arch/powerpc/boot/dts/p4080si.dtsi
index b71051f506c1..f20c01ab2473 100644
--- a/arch/powerpc/boot/dts/p4080si.dtsi
+++ b/arch/powerpc/boot/dts/p4080si.dtsi
@@ -42,6 +42,7 @@
42 42
43 aliases { 43 aliases {
44 ccsr = &soc; 44 ccsr = &soc;
45 dcsr = &dcsr;
45 46
46 serial0 = &serial0; 47 serial0 = &serial0;
47 serial1 = &serial1; 48 serial1 = &serial1;
@@ -77,7 +78,7 @@
77 #address-cells = <1>; 78 #address-cells = <1>;
78 #size-cells = <0>; 79 #size-cells = <0>;
79 80
80 cpu0: PowerPC,4080@0 { 81 cpu0: PowerPC,e500mc@0 {
81 device_type = "cpu"; 82 device_type = "cpu";
82 reg = <0>; 83 reg = <0>;
83 next-level-cache = <&L2_0>; 84 next-level-cache = <&L2_0>;
@@ -85,7 +86,7 @@
85 next-level-cache = <&cpc>; 86 next-level-cache = <&cpc>;
86 }; 87 };
87 }; 88 };
88 cpu1: PowerPC,4080@1 { 89 cpu1: PowerPC,e500mc@1 {
89 device_type = "cpu"; 90 device_type = "cpu";
90 reg = <1>; 91 reg = <1>;
91 next-level-cache = <&L2_1>; 92 next-level-cache = <&L2_1>;
@@ -93,7 +94,7 @@
93 next-level-cache = <&cpc>; 94 next-level-cache = <&cpc>;
94 }; 95 };
95 }; 96 };
96 cpu2: PowerPC,4080@2 { 97 cpu2: PowerPC,e500mc@2 {
97 device_type = "cpu"; 98 device_type = "cpu";
98 reg = <2>; 99 reg = <2>;
99 next-level-cache = <&L2_2>; 100 next-level-cache = <&L2_2>;
@@ -101,7 +102,7 @@
101 next-level-cache = <&cpc>; 102 next-level-cache = <&cpc>;
102 }; 103 };
103 }; 104 };
104 cpu3: PowerPC,4080@3 { 105 cpu3: PowerPC,e500mc@3 {
105 device_type = "cpu"; 106 device_type = "cpu";
106 reg = <3>; 107 reg = <3>;
107 next-level-cache = <&L2_3>; 108 next-level-cache = <&L2_3>;
@@ -109,7 +110,7 @@
109 next-level-cache = <&cpc>; 110 next-level-cache = <&cpc>;
110 }; 111 };
111 }; 112 };
112 cpu4: PowerPC,4080@4 { 113 cpu4: PowerPC,e500mc@4 {
113 device_type = "cpu"; 114 device_type = "cpu";
114 reg = <4>; 115 reg = <4>;
115 next-level-cache = <&L2_4>; 116 next-level-cache = <&L2_4>;
@@ -117,7 +118,7 @@
117 next-level-cache = <&cpc>; 118 next-level-cache = <&cpc>;
118 }; 119 };
119 }; 120 };
120 cpu5: PowerPC,4080@5 { 121 cpu5: PowerPC,e500mc@5 {
121 device_type = "cpu"; 122 device_type = "cpu";
122 reg = <5>; 123 reg = <5>;
123 next-level-cache = <&L2_5>; 124 next-level-cache = <&L2_5>;
@@ -125,7 +126,7 @@
125 next-level-cache = <&cpc>; 126 next-level-cache = <&cpc>;
126 }; 127 };
127 }; 128 };
128 cpu6: PowerPC,4080@6 { 129 cpu6: PowerPC,e500mc@6 {
129 device_type = "cpu"; 130 device_type = "cpu";
130 reg = <6>; 131 reg = <6>;
131 next-level-cache = <&L2_6>; 132 next-level-cache = <&L2_6>;
@@ -133,7 +134,7 @@
133 next-level-cache = <&cpc>; 134 next-level-cache = <&cpc>;
134 }; 135 };
135 }; 136 };
136 cpu7: PowerPC,4080@7 { 137 cpu7: PowerPC,e500mc@7 {
137 device_type = "cpu"; 138 device_type = "cpu";
138 reg = <7>; 139 reg = <7>;
139 next-level-cache = <&L2_7>; 140 next-level-cache = <&L2_7>;
@@ -143,6 +144,99 @@
143 }; 144 };
144 }; 145 };
145 146
147 dcsr: dcsr@f00000000 {
148 #address-cells = <1>;
149 #size-cells = <1>;
150 compatible = "fsl,dcsr", "simple-bus";
151
152 dcsr-epu@0 {
153 compatible = "fsl,dcsr-epu";
154 interrupts = <52 2 0 0
155 84 2 0 0
156 85 2 0 0>;
157 interrupt-parent = <&mpic>;
158 reg = <0x0 0x1000>;
159 };
160 dcsr-npc {
161 compatible = "fsl,dcsr-npc";
162 reg = <0x1000 0x1000 0x1000000 0x8000>;
163 };
164 dcsr-nxc@2000 {
165 compatible = "fsl,dcsr-nxc";
166 reg = <0x2000 0x1000>;
167 };
168 dcsr-corenet {
169 compatible = "fsl,dcsr-corenet";
170 reg = <0x8000 0x1000 0xB0000 0x1000>;
171 };
172 dcsr-dpaa@9000 {
173 compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa";
174 reg = <0x9000 0x1000>;
175 };
176 dcsr-ocn@11000 {
177 compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn";
178 reg = <0x11000 0x1000>;
179 };
180 dcsr-ddr@12000 {
181 compatible = "fsl,dcsr-ddr";
182 dev-handle = <&ddr1>;
183 reg = <0x12000 0x1000>;
184 };
185 dcsr-ddr@13000 {
186 compatible = "fsl,dcsr-ddr";
187 dev-handle = <&ddr2>;
188 reg = <0x13000 0x1000>;
189 };
190 dcsr-nal@18000 {
191 compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal";
192 reg = <0x18000 0x1000>;
193 };
194 dcsr-rcpm@22000 {
195 compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm";
196 reg = <0x22000 0x1000>;
197 };
198 dcsr-cpu-sb-proxy@40000 {
199 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
200 cpu-handle = <&cpu0>;
201 reg = <0x40000 0x1000>;
202 };
203 dcsr-cpu-sb-proxy@41000 {
204 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
205 cpu-handle = <&cpu1>;
206 reg = <0x41000 0x1000>;
207 };
208 dcsr-cpu-sb-proxy@42000 {
209 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
210 cpu-handle = <&cpu2>;
211 reg = <0x42000 0x1000>;
212 };
213 dcsr-cpu-sb-proxy@43000 {
214 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
215 cpu-handle = <&cpu3>;
216 reg = <0x43000 0x1000>;
217 };
218 dcsr-cpu-sb-proxy@44000 {
219 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
220 cpu-handle = <&cpu4>;
221 reg = <0x44000 0x1000>;
222 };
223 dcsr-cpu-sb-proxy@45000 {
224 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
225 cpu-handle = <&cpu5>;
226 reg = <0x45000 0x1000>;
227 };
228 dcsr-cpu-sb-proxy@46000 {
229 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
230 cpu-handle = <&cpu6>;
231 reg = <0x46000 0x1000>;
232 };
233 dcsr-cpu-sb-proxy@47000 {
234 compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
235 cpu-handle = <&cpu7>;
236 reg = <0x47000 0x1000>;
237 };
238 };
239
146 soc: soc@ffe000000 { 240 soc: soc@ffe000000 {
147 #address-cells = <1>; 241 #address-cells = <1>;
148 #size-cells = <1>; 242 #size-cells = <1>;
@@ -162,13 +256,13 @@
162 fsl,num-laws = <32>; 256 fsl,num-laws = <32>;
163 }; 257 };
164 258
165 memory-controller@8000 { 259 ddr1: memory-controller@8000 {
166 compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller"; 260 compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller";
167 reg = <0x8000 0x1000>; 261 reg = <0x8000 0x1000>;
168 interrupts = <16 2 1 23>; 262 interrupts = <16 2 1 23>;
169 }; 263 };
170 264
171 memory-controller@9000 { 265 ddr2: memory-controller@9000 {
172 compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller"; 266 compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller";
173 reg = <0x9000 0x1000>; 267 reg = <0x9000 0x1000>;
174 interrupts = <16 2 1 22>; 268 interrupts = <16 2 1 22>;
diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts
index 8366e2fd2fba..e6d40999ccd7 100644
--- a/arch/powerpc/boot/dts/p5020ds.dts
+++ b/arch/powerpc/boot/dts/p5020ds.dts
@@ -45,6 +45,10 @@
45 device_type = "memory"; 45 device_type = "memory";
46 }; 46 };
47 47
48 dcsr: dcsr@f00000000 {
49 ranges = <0x00000000 0xf 0x00000000 0x01008000>;
50 };
51
48 soc: soc@ffe000000 { 52 soc: soc@ffe000000 {
49 spi@110000 { 53 spi@110000 {
50 flash@0 { 54 flash@0 {
@@ -147,8 +151,8 @@
147 }; 151 };
148 152
149 board-control@3,0 { 153 board-control@3,0 {
150 compatible = "fsl,p5020ds-pixis"; 154 compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
151 reg = <3 0 0x20>; 155 reg = <3 0 0x30>;
152 }; 156 };
153 }; 157 };
154 158
diff --git a/arch/powerpc/boot/dts/p5020si.dtsi b/arch/powerpc/boot/dts/p5020si.dtsi
index 5e6048ec55bb..e7948ad71fa3 100644
--- a/arch/powerpc/boot/dts/p5020si.dtsi
+++ b/arch/powerpc/boot/dts/p5020si.dtsi
@@ -42,6 +42,7 @@
42 42
43 aliases { 43 aliases {
44 ccsr = &soc; 44 ccsr = &soc;
45 dcsr = &dcsr;
45 46
46 serial0 = &serial0; 47 serial0 = &serial0;
47 serial1 = &serial1; 48 serial1 = &serial1;
@@ -98,6 +99,69 @@
98 }; 99 };
99 }; 100 };
100 101
102 dcsr: dcsr@f00000000 {
103 #address-cells = <1>;
104 #size-cells = <1>;
105 compatible = "fsl,dcsr", "simple-bus";
106
107 dcsr-epu@0 {
108 compatible = "fsl,dcsr-epu";
109 interrupts = <52 2 0 0
110 84 2 0 0
111 85 2 0 0>;
112 interrupt-parent = <&mpic>;
113 reg = <0x0 0x1000>;
114 };
115 dcsr-npc {
116 compatible = "fsl,dcsr-npc";
117 reg = <0x1000 0x1000 0x1000000 0x8000>;
118 };
119 dcsr-nxc@2000 {
120 compatible = "fsl,dcsr-nxc";
121 reg = <0x2000 0x1000>;
122 };
123 dcsr-corenet {
124 compatible = "fsl,dcsr-corenet";
125 reg = <0x8000 0x1000 0xB0000 0x1000>;
126 };
127 dcsr-dpaa@9000 {
128 compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa";
129 reg = <0x9000 0x1000>;
130 };
131 dcsr-ocn@11000 {
132 compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn";
133 reg = <0x11000 0x1000>;
134 };
135 dcsr-ddr@12000 {
136 compatible = "fsl,dcsr-ddr";
137 dev-handle = <&ddr1>;
138 reg = <0x12000 0x1000>;
139 };
140 dcsr-ddr@13000 {
141 compatible = "fsl,dcsr-ddr";
142 dev-handle = <&ddr2>;
143 reg = <0x13000 0x1000>;
144 };
145 dcsr-nal@18000 {
146 compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal";
147 reg = <0x18000 0x1000>;
148 };
149 dcsr-rcpm@22000 {
150 compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm";
151 reg = <0x22000 0x1000>;
152 };
153 dcsr-cpu-sb-proxy@40000 {
154 compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
155 cpu-handle = <&cpu0>;
156 reg = <0x40000 0x1000>;
157 };
158 dcsr-cpu-sb-proxy@41000 {
159 compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
160 cpu-handle = <&cpu1>;
161 reg = <0x41000 0x1000>;
162 };
163 };
164
101 soc: soc@ffe000000 { 165 soc: soc@ffe000000 {
102 #address-cells = <1>; 166 #address-cells = <1>;
103 #size-cells = <1>; 167 #size-cells = <1>;
@@ -117,13 +181,13 @@
117 fsl,num-laws = <32>; 181 fsl,num-laws = <32>;
118 }; 182 };
119 183
120 memory-controller@8000 { 184 ddr1: memory-controller@8000 {
121 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; 185 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
122 reg = <0x8000 0x1000>; 186 reg = <0x8000 0x1000>;
123 interrupts = <16 2 1 23>; 187 interrupts = <16 2 1 23>;
124 }; 188 };
125 189
126 memory-controller@9000 { 190 ddr2: memory-controller@9000 {
127 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; 191 compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
128 reg = <0x9000 0x1000>; 192 reg = <0x9000 0x1000>;
129 interrupts = <16 2 1 22>; 193 interrupts = <16 2 1 22>;
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts
index 9e13ed8a1193..72078eb15616 100644
--- a/arch/powerpc/boot/dts/sbc8560.dts
+++ b/arch/powerpc/boot/dts/sbc8560.dts
@@ -331,7 +331,7 @@
331 }; 331 };
332 332
333 localbus@ff705000 { 333 localbus@ff705000 {
334 compatible = "fsl,mpc8560-localbus"; 334 compatible = "fsl,mpc8560-localbus", "simple-bus";
335 #address-cells = <2>; 335 #address-cells = <2>;
336 #size-cells = <1>; 336 #size-cells = <1>;
337 reg = <0xff705000 0x100>; // BRx, ORx, etc. 337 reg = <0xff705000 0x100>; // BRx, ORx, etc.
diff --git a/arch/powerpc/boot/dts/yosemite.dts b/arch/powerpc/boot/dts/yosemite.dts
index 64923245f0e5..30bb4753577a 100644
--- a/arch/powerpc/boot/dts/yosemite.dts
+++ b/arch/powerpc/boot/dts/yosemite.dts
@@ -138,6 +138,42 @@
138 clock-frequency = <0>; /* Filled in by zImage */ 138 clock-frequency = <0>; /* Filled in by zImage */
139 interrupts = <0x5 0x1>; 139 interrupts = <0x5 0x1>;
140 interrupt-parent = <&UIC1>; 140 interrupt-parent = <&UIC1>;
141
142 nor_flash@0,0 {
143 compatible = "amd,s29gl256n", "cfi-flash";
144 bank-width = <2>;
145 reg = <0x00000000 0x00000000 0x04000000>;
146 #address-cells = <1>;
147 #size-cells = <1>;
148 partition@0 {
149 label = "kernel";
150 reg = <0x00000000 0x001e0000>;
151 };
152 partition@1e0000 {
153 label = "dtb";
154 reg = <0x001e0000 0x00020000>;
155 };
156 partition@200000 {
157 label = "ramdisk";
158 reg = <0x00200000 0x01400000>;
159 };
160 partition@1600000 {
161 label = "jffs2";
162 reg = <0x01600000 0x00400000>;
163 };
164 partition@1a00000 {
165 label = "user";
166 reg = <0x01a00000 0x02540000>;
167 };
168 partition@3f40000 {
169 label = "env";
170 reg = <0x03f40000 0x00040000>;
171 };
172 partition@3f80000 {
173 label = "u-boot";
174 reg = <0x03f80000 0x00080000>;
175 };
176 };
141 }; 177 };
142 178
143 UART0: serial@ef600300 { 179 UART0: serial@ef600300 {
diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig
deleted file mode 100644
index dba263c1d3a2..000000000000
--- a/arch/powerpc/configs/40x/hcu4_defconfig
+++ /dev/null
@@ -1,81 +0,0 @@
1CONFIG_40x=y
2CONFIG_EXPERIMENTAL=y
3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
5CONFIG_LOG_BUF_SHIFT=14
6CONFIG_BLK_DEV_INITRD=y
7# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
8CONFIG_EXPERT=y
9CONFIG_KALLSYMS_ALL=y
10CONFIG_KALLSYMS_EXTRA_PASS=y
11CONFIG_MODULES=y
12CONFIG_MODULE_UNLOAD=y
13# CONFIG_BLK_DEV_BSG is not set
14CONFIG_HCU4=y
15# CONFIG_WALNUT is not set
16CONFIG_SPARSE_IRQ=y
17CONFIG_PCI=y
18CONFIG_NET=y
19CONFIG_PACKET=y
20CONFIG_UNIX=y
21CONFIG_INET=y
22CONFIG_IP_PNP=y
23CONFIG_IP_PNP_DHCP=y
24CONFIG_IP_PNP_BOOTP=y
25# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
26# CONFIG_INET_XFRM_MODE_TUNNEL is not set
27# CONFIG_INET_XFRM_MODE_BEET is not set
28# CONFIG_INET_LRO is not set
29# CONFIG_IPV6 is not set
30CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
31CONFIG_CONNECTOR=y
32CONFIG_MTD=y
33CONFIG_MTD_PARTITIONS=y
34CONFIG_MTD_CMDLINE_PARTS=y
35CONFIG_MTD_OF_PARTS=y
36CONFIG_MTD_CHAR=y
37CONFIG_MTD_BLOCK=m
38CONFIG_MTD_CFI=y
39CONFIG_MTD_JEDECPROBE=y
40CONFIG_MTD_CFI_AMDSTD=y
41CONFIG_MTD_PHYSMAP_OF=y
42CONFIG_PROC_DEVICETREE=y
43CONFIG_BLK_DEV_RAM=y
44CONFIG_BLK_DEV_RAM_SIZE=35000
45CONFIG_NETDEVICES=y
46CONFIG_ETHERNET=y
47CONFIG_NET_VENDOR_IBM=y
48CONFIG_IBM_EMAC=y
49# CONFIG_INPUT is not set
50# CONFIG_SERIO is not set
51# CONFIG_VT is not set
52CONFIG_SERIAL_8250=y
53CONFIG_SERIAL_8250_CONSOLE=y
54CONFIG_SERIAL_8250_EXTENDED=y
55CONFIG_SERIAL_8250_SHARE_IRQ=y
56CONFIG_SERIAL_OF_PLATFORM=y
57# CONFIG_HW_RANDOM is not set
58# CONFIG_HWMON is not set
59CONFIG_VIDEO_OUTPUT_CONTROL=m
60# CONFIG_USB_SUPPORT is not set
61CONFIG_EXT2_FS=y
62CONFIG_INOTIFY=y
63CONFIG_PROC_KCORE=y
64CONFIG_TMPFS=y
65CONFIG_CRAMFS=y
66CONFIG_NFS_FS=y
67CONFIG_NFS_V3=y
68CONFIG_ROOT_NFS=y
69CONFIG_MAGIC_SYSRQ=y
70CONFIG_DEBUG_FS=y
71CONFIG_DEBUG_KERNEL=y
72CONFIG_DETECT_HUNG_TASK=y
73# CONFIG_RCU_CPU_STALL_DETECTOR is not set
74CONFIG_SYSCTL_SYSCALL_CHECK=y
75CONFIG_CRYPTO=y
76CONFIG_CRYPTO_CBC=y
77CONFIG_CRYPTO_ECB=y
78CONFIG_CRYPTO_PCBC=y
79CONFIG_CRYPTO_MD5=y
80CONFIG_CRYPTO_DES=y
81# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig
index 3ff5a81c709f..c091aaf7685f 100644
--- a/arch/powerpc/configs/85xx/p1023rds_defconfig
+++ b/arch/powerpc/configs/85xx/p1023rds_defconfig
@@ -24,7 +24,7 @@ CONFIG_P1023_RDS=y
24CONFIG_QUICC_ENGINE=y 24CONFIG_QUICC_ENGINE=y
25CONFIG_QE_GPIO=y 25CONFIG_QE_GPIO=y
26CONFIG_CPM2=y 26CONFIG_CPM2=y
27CONFIG_MPC8xxx_GPIO=y 27CONFIG_GPIO_MPC8XXX=y
28CONFIG_HIGHMEM=y 28CONFIG_HIGHMEM=y
29CONFIG_NO_HZ=y 29CONFIG_NO_HZ=y
30CONFIG_HIGH_RES_TIMERS=y 30CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
index 5ea3124518fd..1cd6fcb368e9 100644
--- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
+++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
@@ -20,7 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
20CONFIG_MODVERSIONS=y 20CONFIG_MODVERSIONS=y
21# CONFIG_BLK_DEV_BSG is not set 21# CONFIG_BLK_DEV_BSG is not set
22CONFIG_XES_MPC85xx=y 22CONFIG_XES_MPC85xx=y
23CONFIG_MPC8xxx_GPIO=y 23CONFIG_GPIO_MPC8XXX=y
24CONFIG_HIGHMEM=y 24CONFIG_HIGHMEM=y
25CONFIG_MATH_EMULATION=y 25CONFIG_MATH_EMULATION=y
26CONFIG_SPARSE_IRQ=y 26CONFIG_SPARSE_IRQ=y
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig
index 4311d02a3bfd..f087de6ec03f 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -12,9 +12,7 @@ CONFIG_IKCONFIG=y
12CONFIG_IKCONFIG_PROC=y 12CONFIG_IKCONFIG_PROC=y
13CONFIG_LOG_BUF_SHIFT=14 13CONFIG_LOG_BUF_SHIFT=14
14CONFIG_BLK_DEV_INITRD=y 14CONFIG_BLK_DEV_INITRD=y
15# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
16CONFIG_KALLSYMS_ALL=y 15CONFIG_KALLSYMS_ALL=y
17CONFIG_KALLSYMS_EXTRA_PASS=y
18CONFIG_EMBEDDED=y 16CONFIG_EMBEDDED=y
19CONFIG_PERF_EVENTS=y 17CONFIG_PERF_EVENTS=y
20CONFIG_SLAB=y 18CONFIG_SLAB=y
@@ -23,8 +21,9 @@ CONFIG_MODULE_UNLOAD=y
23CONFIG_MODULE_FORCE_UNLOAD=y 21CONFIG_MODULE_FORCE_UNLOAD=y
24CONFIG_MODVERSIONS=y 22CONFIG_MODVERSIONS=y
25# CONFIG_BLK_DEV_BSG is not set 23# CONFIG_BLK_DEV_BSG is not set
26CONFIG_P2040_RDB=y 24CONFIG_P2041_RDB=y
27CONFIG_P3041_DS=y 25CONFIG_P3041_DS=y
26CONFIG_P3060_QDS=y
28CONFIG_P4080_DS=y 27CONFIG_P4080_DS=y
29CONFIG_P5020_DS=y 28CONFIG_P5020_DS=y
30CONFIG_HIGHMEM=y 29CONFIG_HIGHMEM=y
@@ -69,7 +68,6 @@ CONFIG_IPV6=y
69CONFIG_IP_SCTP=m 68CONFIG_IP_SCTP=m
70CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 69CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
71CONFIG_MTD=y 70CONFIG_MTD=y
72CONFIG_MTD_PARTITIONS=y
73CONFIG_MTD_CMDLINE_PARTS=y 71CONFIG_MTD_CMDLINE_PARTS=y
74CONFIG_MTD_CHAR=y 72CONFIG_MTD_CHAR=y
75CONFIG_MTD_BLOCK=y 73CONFIG_MTD_BLOCK=y
@@ -107,7 +105,6 @@ CONFIG_FSL_PQ_MDIO=y
107# CONFIG_INPUT_MOUSE is not set 105# CONFIG_INPUT_MOUSE is not set
108CONFIG_SERIO_LIBPS2=y 106CONFIG_SERIO_LIBPS2=y
109# CONFIG_LEGACY_PTYS is not set 107# CONFIG_LEGACY_PTYS is not set
110CONFIG_PPC_EPAPR_HV_BYTECHAN=y
111CONFIG_SERIAL_8250=y 108CONFIG_SERIAL_8250=y
112CONFIG_SERIAL_8250_CONSOLE=y 109CONFIG_SERIAL_8250_CONSOLE=y
113CONFIG_SERIAL_8250_EXTENDED=y 110CONFIG_SERIAL_8250_EXTENDED=y
@@ -136,8 +133,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
136CONFIG_USB_STORAGE=y 133CONFIG_USB_STORAGE=y
137CONFIG_MMC=y 134CONFIG_MMC=y
138CONFIG_MMC_SDHCI=y 135CONFIG_MMC_SDHCI=y
139CONFIG_MMC_SDHCI_OF=y
140CONFIG_MMC_SDHCI_OF_ESDHC=y
141CONFIG_EDAC=y 136CONFIG_EDAC=y
142CONFIG_EDAC_MM_EDAC=y 137CONFIG_EDAC_MM_EDAC=y
143CONFIG_EDAC_MPC85XX=y 138CONFIG_EDAC_MPC85XX=y
@@ -146,7 +141,6 @@ CONFIG_RTC_DRV_DS3232=y
146CONFIG_RTC_DRV_CMOS=y 141CONFIG_RTC_DRV_CMOS=y
147CONFIG_UIO=y 142CONFIG_UIO=y
148CONFIG_STAGING=y 143CONFIG_STAGING=y
149# CONFIG_STAGING_EXCLUDE_BUILD is not set
150CONFIG_VIRT_DRIVERS=y 144CONFIG_VIRT_DRIVERS=y
151CONFIG_FSL_HV_MANAGER=y 145CONFIG_FSL_HV_MANAGER=y
152CONFIG_EXT2_FS=y 146CONFIG_EXT2_FS=y
@@ -173,7 +167,6 @@ CONFIG_MAC_PARTITION=y
173CONFIG_NLS_ISO8859_1=y 167CONFIG_NLS_ISO8859_1=y
174CONFIG_NLS_UTF8=m 168CONFIG_NLS_UTF8=m
175CONFIG_MAGIC_SYSRQ=y 169CONFIG_MAGIC_SYSRQ=y
176CONFIG_DEBUG_KERNEL=y
177CONFIG_DEBUG_SHIRQ=y 170CONFIG_DEBUG_SHIRQ=y
178CONFIG_DETECT_HUNG_TASK=y 171CONFIG_DETECT_HUNG_TASK=y
179CONFIG_DEBUG_INFO=y 172CONFIG_DEBUG_INFO=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index c92c204a204b..782822c32d15 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -11,10 +11,8 @@ CONFIG_IKCONFIG=y
11CONFIG_IKCONFIG_PROC=y 11CONFIG_IKCONFIG_PROC=y
12CONFIG_LOG_BUF_SHIFT=14 12CONFIG_LOG_BUF_SHIFT=14
13CONFIG_BLK_DEV_INITRD=y 13CONFIG_BLK_DEV_INITRD=y
14# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
15CONFIG_EXPERT=y 14CONFIG_EXPERT=y
16CONFIG_KALLSYMS_ALL=y 15CONFIG_KALLSYMS_ALL=y
17CONFIG_KALLSYMS_EXTRA_PASS=y
18CONFIG_MODULES=y 16CONFIG_MODULES=y
19CONFIG_MODULE_UNLOAD=y 17CONFIG_MODULE_UNLOAD=y
20CONFIG_MODULE_FORCE_UNLOAD=y 18CONFIG_MODULE_FORCE_UNLOAD=y
@@ -25,7 +23,6 @@ CONFIG_P5020_DS=y
25CONFIG_NO_HZ=y 23CONFIG_NO_HZ=y
26CONFIG_HIGH_RES_TIMERS=y 24CONFIG_HIGH_RES_TIMERS=y
27CONFIG_BINFMT_MISC=m 25CONFIG_BINFMT_MISC=m
28# CONFIG_PCI is not set
29CONFIG_NET=y 26CONFIG_NET=y
30CONFIG_PACKET=y 27CONFIG_PACKET=y
31CONFIG_UNIX=y 28CONFIG_UNIX=y
@@ -93,10 +90,8 @@ CONFIG_CRC_T10DIF=y
93CONFIG_CRC_ITU_T=m 90CONFIG_CRC_ITU_T=m
94CONFIG_FRAME_WARN=1024 91CONFIG_FRAME_WARN=1024
95CONFIG_DEBUG_FS=y 92CONFIG_DEBUG_FS=y
96CONFIG_DEBUG_KERNEL=y
97CONFIG_DETECT_HUNG_TASK=y 93CONFIG_DETECT_HUNG_TASK=y
98CONFIG_DEBUG_INFO=y 94CONFIG_DEBUG_INFO=y
99# CONFIG_RCU_CPU_STALL_DETECTOR is not set
100CONFIG_SYSCTL_SYSCALL_CHECK=y 95CONFIG_SYSCTL_SYSCALL_CHECK=y
101CONFIG_VIRQ_DEBUG=y 96CONFIG_VIRQ_DEBUG=y
102CONFIG_CRYPTO_PCBC=m 97CONFIG_CRYPTO_PCBC=m
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index 6cb588a7d425..0d36b0e1e268 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -1,15 +1,22 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_SWAP is not set
1CONFIG_SYSVIPC=y 3CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y
2CONFIG_SPARSE_IRQ=y 5CONFIG_SPARSE_IRQ=y
3CONFIG_IKCONFIG=y 6CONFIG_IKCONFIG=y
4CONFIG_IKCONFIG_PROC=y 7CONFIG_IKCONFIG_PROC=y
5CONFIG_LOG_BUF_SHIFT=14 8CONFIG_LOG_BUF_SHIFT=14
6CONFIG_BLK_DEV_INITRD=y 9CONFIG_BLK_DEV_INITRD=y
7CONFIG_EXPERT=y 10# CONFIG_RD_GZIP is not set
8CONFIG_KALLSYMS_ALL=y 11CONFIG_KALLSYMS_ALL=y
12# CONFIG_PCSPKR_PLATFORM is not set
13CONFIG_EMBEDDED=y
9CONFIG_SLAB=y 14CONFIG_SLAB=y
10# CONFIG_IOSCHED_CFQ is not set 15# CONFIG_IOSCHED_CFQ is not set
16# CONFIG_PPC_PMAC is not set
11CONFIG_PPC_82xx=y 17CONFIG_PPC_82xx=y
12CONFIG_MGCOGE=y 18CONFIG_MGCOGE=y
19CONFIG_HIGH_RES_TIMERS=y
13CONFIG_BINFMT_MISC=y 20CONFIG_BINFMT_MISC=y
14# CONFIG_SECCOMP is not set 21# CONFIG_SECCOMP is not set
15CONFIG_NET=y 22CONFIG_NET=y
@@ -24,11 +31,10 @@ CONFIG_SYN_COOKIES=y
24# CONFIG_INET_LRO is not set 31# CONFIG_INET_LRO is not set
25# CONFIG_IPV6 is not set 32# CONFIG_IPV6 is not set
26CONFIG_NETFILTER=y 33CONFIG_NETFILTER=y
34CONFIG_TIPC=y
27CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 35CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
28# CONFIG_FW_LOADER is not set 36# CONFIG_FW_LOADER is not set
29CONFIG_MTD=y 37CONFIG_MTD=y
30CONFIG_MTD_CONCAT=y
31CONFIG_MTD_PARTITIONS=y
32CONFIG_MTD_CMDLINE_PARTS=y 38CONFIG_MTD_CMDLINE_PARTS=y
33CONFIG_MTD_CHAR=y 39CONFIG_MTD_CHAR=y
34CONFIG_MTD_BLKDEVS=y 40CONFIG_MTD_BLKDEVS=y
@@ -42,7 +48,6 @@ CONFIG_MTD_PHYSMAP_OF=y
42CONFIG_PROC_DEVICETREE=y 48CONFIG_PROC_DEVICETREE=y
43CONFIG_BLK_DEV_LOOP=y 49CONFIG_BLK_DEV_LOOP=y
44CONFIG_BLK_DEV_RAM=y 50CONFIG_BLK_DEV_RAM=y
45# CONFIG_MACINTOSH_DRIVERS is not set
46CONFIG_NETDEVICES=y 51CONFIG_NETDEVICES=y
47CONFIG_FIXED_PHY=y 52CONFIG_FIXED_PHY=y
48CONFIG_NET_ETHERNET=y 53CONFIG_NET_ETHERNET=y
@@ -50,6 +55,7 @@ CONFIG_FS_ENET=y
50CONFIG_FS_ENET_MDIO_FCC=y 55CONFIG_FS_ENET_MDIO_FCC=y
51# CONFIG_NETDEV_1000 is not set 56# CONFIG_NETDEV_1000 is not set
52# CONFIG_NETDEV_10000 is not set 57# CONFIG_NETDEV_10000 is not set
58# CONFIG_WLAN is not set
53# CONFIG_INPUT is not set 59# CONFIG_INPUT is not set
54# CONFIG_SERIO is not set 60# CONFIG_SERIO is not set
55# CONFIG_VT is not set 61# CONFIG_VT is not set
@@ -57,24 +63,24 @@ CONFIG_SERIAL_CPM=y
57CONFIG_SERIAL_CPM_CONSOLE=y 63CONFIG_SERIAL_CPM_CONSOLE=y
58CONFIG_I2C=y 64CONFIG_I2C=y
59CONFIG_I2C_CHARDEV=y 65CONFIG_I2C_CHARDEV=y
60# CONFIG_I2C_POWERMAC is not set
61CONFIG_I2C_CPM=y 66CONFIG_I2C_CPM=y
62# CONFIG_HWMON is not set 67# CONFIG_HWMON is not set
63# CONFIG_USB_SUPPORT is not set 68CONFIG_USB_GADGET=y
69CONFIG_USB_FSL_USB2=y
70CONFIG_USB_G_SERIAL=y
71CONFIG_UIO=y
72CONFIG_UIO_PDRV=y
64CONFIG_EXT2_FS=y 73CONFIG_EXT2_FS=y
65CONFIG_EXT3_FS=y
66# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
67# CONFIG_EXT3_FS_XATTR is not set
68CONFIG_AUTOFS4_FS=y 74CONFIG_AUTOFS4_FS=y
69CONFIG_PROC_KCORE=y 75CONFIG_PROC_KCORE=y
70CONFIG_TMPFS=y 76CONFIG_TMPFS=y
71CONFIG_JFFS2_FS=y 77CONFIG_JFFS2_FS=y
72CONFIG_CRAMFS=y 78CONFIG_CRAMFS=y
79CONFIG_SQUASHFS=y
73CONFIG_NFS_FS=y 80CONFIG_NFS_FS=y
74CONFIG_NFS_V3=y 81CONFIG_NFS_V3=y
75CONFIG_ROOT_NFS=y 82CONFIG_ROOT_NFS=y
76CONFIG_PARTITION_ADVANCED=y 83CONFIG_PARTITION_ADVANCED=y
77# CONFIG_MAC_PARTITION is not set
78CONFIG_NLS=y 84CONFIG_NLS=y
79CONFIG_NLS_CODEPAGE_437=y 85CONFIG_NLS_CODEPAGE_437=y
80CONFIG_NLS_ASCII=y 86CONFIG_NLS_ASCII=y
@@ -82,7 +88,6 @@ CONFIG_NLS_ISO8859_1=y
82CONFIG_NLS_UTF8=y 88CONFIG_NLS_UTF8=y
83CONFIG_MAGIC_SYSRQ=y 89CONFIG_MAGIC_SYSRQ=y
84CONFIG_DEBUG_FS=y 90CONFIG_DEBUG_FS=y
85CONFIG_DEBUG_KERNEL=y
86# CONFIG_SCHED_DEBUG is not set 91# CONFIG_SCHED_DEBUG is not set
87CONFIG_DEBUG_INFO=y 92CONFIG_DEBUG_INFO=y
88CONFIG_SYSCTL_SYSCALL_CHECK=y 93CONFIG_SYSCTL_SYSCALL_CHECK=y
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
index c02bbb2fddf8..211fcc9ed700 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -1,9 +1,9 @@
1CONFIG_EXPERIMENTAL=y 1CONFIG_EXPERIMENTAL=y
2# CONFIG_SWAP is not set 2# CONFIG_SWAP is not set
3CONFIG_SYSVIPC=y 3CONFIG_SYSVIPC=y
4CONFIG_SPARSE_IRQ=y
4CONFIG_LOG_BUF_SHIFT=16 5CONFIG_LOG_BUF_SHIFT=16
5CONFIG_BLK_DEV_INITRD=y 6CONFIG_BLK_DEV_INITRD=y
6# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
7# CONFIG_COMPAT_BRK is not set 7# CONFIG_COMPAT_BRK is not set
8CONFIG_SLAB=y 8CONFIG_SLAB=y
9CONFIG_MODULES=y 9CONFIG_MODULES=y
@@ -13,10 +13,11 @@ CONFIG_MODULE_UNLOAD=y
13# CONFIG_PPC_CHRP is not set 13# CONFIG_PPC_CHRP is not set
14CONFIG_PPC_MPC512x=y 14CONFIG_PPC_MPC512x=y
15CONFIG_MPC5121_ADS=y 15CONFIG_MPC5121_ADS=y
16CONFIG_MPC5121_GENERIC=y
17CONFIG_PDM360NG=y
16# CONFIG_PPC_PMAC is not set 18# CONFIG_PPC_PMAC is not set
17CONFIG_NO_HZ=y 19CONFIG_NO_HZ=y
18CONFIG_HZ_1000=y 20CONFIG_HZ_1000=y
19CONFIG_SPARSE_IRQ=y
20# CONFIG_MIGRATION is not set 21# CONFIG_MIGRATION is not set
21# CONFIG_SECCOMP is not set 22# CONFIG_SECCOMP is not set
22# CONFIG_PCI is not set 23# CONFIG_PCI is not set
@@ -35,18 +36,16 @@ CONFIG_CAN=y
35CONFIG_CAN_RAW=y 36CONFIG_CAN_RAW=y
36CONFIG_CAN_BCM=y 37CONFIG_CAN_BCM=y
37CONFIG_CAN_VCAN=y 38CONFIG_CAN_VCAN=y
38CONFIG_CAN_DEV=y
39CONFIG_CAN_MSCAN=y 39CONFIG_CAN_MSCAN=y
40CONFIG_CAN_DEBUG_DEVICES=y 40CONFIG_CAN_DEBUG_DEVICES=y
41# CONFIG_WIRELESS is not set 41# CONFIG_WIRELESS is not set
42CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 42CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
43CONFIG_DEVTMPFS=y
44CONFIG_DEVTMPFS_MOUNT=y
43# CONFIG_PREVENT_FIRMWARE_BUILD is not set 45# CONFIG_PREVENT_FIRMWARE_BUILD is not set
44# CONFIG_FIRMWARE_IN_KERNEL is not set 46# CONFIG_FIRMWARE_IN_KERNEL is not set
45CONFIG_MTD=y 47CONFIG_MTD=y
46CONFIG_MTD_CONCAT=y
47CONFIG_MTD_PARTITIONS=y
48CONFIG_MTD_CMDLINE_PARTS=y 48CONFIG_MTD_CMDLINE_PARTS=y
49CONFIG_MTD_OF_PARTS=y
50CONFIG_MTD_CHAR=y 49CONFIG_MTD_CHAR=y
51CONFIG_MTD_BLOCK=y 50CONFIG_MTD_BLOCK=y
52CONFIG_MTD_CFI=y 51CONFIG_MTD_CFI=y
@@ -63,6 +62,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
63CONFIG_BLK_DEV_XIP=y 62CONFIG_BLK_DEV_XIP=y
64CONFIG_MISC_DEVICES=y 63CONFIG_MISC_DEVICES=y
65CONFIG_EEPROM_AT24=y 64CONFIG_EEPROM_AT24=y
65CONFIG_EEPROM_AT25=y
66CONFIG_SCSI=y 66CONFIG_SCSI=y
67# CONFIG_SCSI_PROC_FS is not set 67# CONFIG_SCSI_PROC_FS is not set
68CONFIG_BLK_DEV_SD=y 68CONFIG_BLK_DEV_SD=y
@@ -99,10 +99,14 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
99CONFIG_I2C=y 99CONFIG_I2C=y
100CONFIG_I2C_CHARDEV=y 100CONFIG_I2C_CHARDEV=y
101CONFIG_I2C_MPC=y 101CONFIG_I2C_MPC=y
102CONFIG_SPI=y
103CONFIG_SPI_MPC512x_PSC=y
104CONFIG_GPIOLIB=y
105CONFIG_GPIO_SYSFS=y
106CONFIG_GPIO_MPC8XXX=y
102# CONFIG_HWMON is not set 107# CONFIG_HWMON is not set
103CONFIG_MEDIA_SUPPORT=y 108CONFIG_MEDIA_SUPPORT=y
104CONFIG_VIDEO_DEV=y 109CONFIG_VIDEO_DEV=y
105# CONFIG_VIDEO_ALLOW_V4L1 is not set
106CONFIG_VIDEO_ADV_DEBUG=y 110CONFIG_VIDEO_ADV_DEBUG=y
107# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set 111# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
108CONFIG_VIDEO_SAA711X=y 112CONFIG_VIDEO_SAA711X=y
@@ -132,6 +136,5 @@ CONFIG_NLS_CODEPAGE_437=y
132CONFIG_NLS_ISO8859_1=y 136CONFIG_NLS_ISO8859_1=y
133# CONFIG_ENABLE_WARN_DEPRECATED is not set 137# CONFIG_ENABLE_WARN_DEPRECATED is not set
134# CONFIG_ENABLE_MUST_CHECK is not set 138# CONFIG_ENABLE_MUST_CHECK is not set
135# CONFIG_RCU_CPU_STALL_DETECTOR is not set
136# CONFIG_CRYPTO_ANSI_CPRNG is not set 139# CONFIG_CRYPTO_ANSI_CPRNG is not set
137# CONFIG_CRYPTO_HW is not set 140# CONFIG_CRYPTO_HW is not set
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index e63f537b854a..2a1320fb2723 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -88,6 +88,18 @@ CONFIG_FB_RADEON=y
88# CONFIG_VGA_CONSOLE is not set 88# CONFIG_VGA_CONSOLE is not set
89CONFIG_FRAMEBUFFER_CONSOLE=y 89CONFIG_FRAMEBUFFER_CONSOLE=y
90CONFIG_LOGO=y 90CONFIG_LOGO=y
91CONFIG_SOUND=y
92CONFIG_SND=y
93# CONFIG_SND_SUPPORT_OLD_API is not set
94# CONFIG_SND_DRIVERS is not set
95# CONFIG_SND_PCI is not set
96# CONFIG_SND_PPC is not set
97# CONFIG_SND_SPI is not set
98# CONFIG_SND_USB is not set
99CONFIG_SND_SOC=y
100CONFIG_SND_SOC_MPC5200_I2S=y
101CONFIG_SND_MPC52xx_SOC_PCM030=y
102CONFIG_SND_MPC52xx_SOC_EFIKA=y
91CONFIG_HID_DRAGONRISE=y 103CONFIG_HID_DRAGONRISE=y
92CONFIG_HID_GYRATION=y 104CONFIG_HID_GYRATION=y
93CONFIG_HID_TWINHAN=y 105CONFIG_HID_TWINHAN=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index a3467bfb7671..a1e5a178a4ac 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -10,10 +10,8 @@ CONFIG_IKCONFIG=y
10CONFIG_IKCONFIG_PROC=y 10CONFIG_IKCONFIG_PROC=y
11CONFIG_LOG_BUF_SHIFT=14 11CONFIG_LOG_BUF_SHIFT=14
12CONFIG_BLK_DEV_INITRD=y 12CONFIG_BLK_DEV_INITRD=y
13# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
14CONFIG_EXPERT=y 13CONFIG_EXPERT=y
15CONFIG_KALLSYMS_ALL=y 14CONFIG_KALLSYMS_ALL=y
16CONFIG_KALLSYMS_EXTRA_PASS=y
17CONFIG_MODULES=y 15CONFIG_MODULES=y
18CONFIG_MODULE_UNLOAD=y 16CONFIG_MODULE_UNLOAD=y
19CONFIG_MODULE_FORCE_UNLOAD=y 17CONFIG_MODULE_FORCE_UNLOAD=y
@@ -41,7 +39,6 @@ CONFIG_TQM8560=y
41CONFIG_SBC8548=y 39CONFIG_SBC8548=y
42CONFIG_QUICC_ENGINE=y 40CONFIG_QUICC_ENGINE=y
43CONFIG_QE_GPIO=y 41CONFIG_QE_GPIO=y
44CONFIG_MPC8xxx_GPIO=y
45CONFIG_HIGHMEM=y 42CONFIG_HIGHMEM=y
46CONFIG_NO_HZ=y 43CONFIG_NO_HZ=y
47CONFIG_HIGH_RES_TIMERS=y 44CONFIG_HIGH_RES_TIMERS=y
@@ -123,6 +120,7 @@ CONFIG_NVRAM=y
123CONFIG_I2C=y 120CONFIG_I2C=y
124CONFIG_I2C_CPM=m 121CONFIG_I2C_CPM=m
125CONFIG_I2C_MPC=y 122CONFIG_I2C_MPC=y
123CONFIG_GPIO_MPC8XXX=y
126# CONFIG_HWMON is not set 124# CONFIG_HWMON is not set
127CONFIG_VIDEO_OUTPUT_CONTROL=y 125CONFIG_VIDEO_OUTPUT_CONTROL=y
128CONFIG_FB=y 126CONFIG_FB=y
@@ -206,7 +204,6 @@ CONFIG_PARTITION_ADVANCED=y
206CONFIG_MAC_PARTITION=y 204CONFIG_MAC_PARTITION=y
207CONFIG_CRC_T10DIF=y 205CONFIG_CRC_T10DIF=y
208CONFIG_DEBUG_FS=y 206CONFIG_DEBUG_FS=y
209CONFIG_DEBUG_KERNEL=y
210CONFIG_DETECT_HUNG_TASK=y 207CONFIG_DETECT_HUNG_TASK=y
211CONFIG_DEBUG_INFO=y 208CONFIG_DEBUG_INFO=y
212CONFIG_SYSCTL_SYSCALL_CHECK=y 209CONFIG_SYSCTL_SYSCALL_CHECK=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 9693f6ed3da0..dd1e41386c4c 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -12,10 +12,8 @@ CONFIG_IKCONFIG=y
12CONFIG_IKCONFIG_PROC=y 12CONFIG_IKCONFIG_PROC=y
13CONFIG_LOG_BUF_SHIFT=14 13CONFIG_LOG_BUF_SHIFT=14
14CONFIG_BLK_DEV_INITRD=y 14CONFIG_BLK_DEV_INITRD=y
15# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
16CONFIG_EXPERT=y 15CONFIG_EXPERT=y
17CONFIG_KALLSYMS_ALL=y 16CONFIG_KALLSYMS_ALL=y
18CONFIG_KALLSYMS_EXTRA_PASS=y
19CONFIG_MODULES=y 17CONFIG_MODULES=y
20CONFIG_MODULE_UNLOAD=y 18CONFIG_MODULE_UNLOAD=y
21CONFIG_MODULE_FORCE_UNLOAD=y 19CONFIG_MODULE_FORCE_UNLOAD=y
@@ -42,7 +40,6 @@ CONFIG_TQM8560=y
42CONFIG_SBC8548=y 40CONFIG_SBC8548=y
43CONFIG_QUICC_ENGINE=y 41CONFIG_QUICC_ENGINE=y
44CONFIG_QE_GPIO=y 42CONFIG_QE_GPIO=y
45CONFIG_MPC8xxx_GPIO=y
46CONFIG_HIGHMEM=y 43CONFIG_HIGHMEM=y
47CONFIG_NO_HZ=y 44CONFIG_NO_HZ=y
48CONFIG_HIGH_RES_TIMERS=y 45CONFIG_HIGH_RES_TIMERS=y
@@ -124,6 +121,7 @@ CONFIG_NVRAM=y
124CONFIG_I2C=y 121CONFIG_I2C=y
125CONFIG_I2C_CPM=m 122CONFIG_I2C_CPM=m
126CONFIG_I2C_MPC=y 123CONFIG_I2C_MPC=y
124CONFIG_GPIO_MPC8XXX=y
127# CONFIG_HWMON is not set 125# CONFIG_HWMON is not set
128CONFIG_VIDEO_OUTPUT_CONTROL=y 126CONFIG_VIDEO_OUTPUT_CONTROL=y
129CONFIG_FB=y 127CONFIG_FB=y
@@ -207,10 +205,8 @@ CONFIG_PARTITION_ADVANCED=y
207CONFIG_MAC_PARTITION=y 205CONFIG_MAC_PARTITION=y
208CONFIG_CRC_T10DIF=y 206CONFIG_CRC_T10DIF=y
209CONFIG_DEBUG_FS=y 207CONFIG_DEBUG_FS=y
210CONFIG_DEBUG_KERNEL=y
211CONFIG_DETECT_HUNG_TASK=y 208CONFIG_DETECT_HUNG_TASK=y
212CONFIG_DEBUG_INFO=y 209CONFIG_DEBUG_INFO=y
213# CONFIG_RCU_CPU_STALL_DETECTOR is not set
214CONFIG_SYSCTL_SYSCALL_CHECK=y 210CONFIG_SYSCTL_SYSCALL_CHECK=y
215CONFIG_VIRQ_DEBUG=y 211CONFIG_VIRQ_DEBUG=y
216CONFIG_CRYPTO_PCBC=m 212CONFIG_CRYPTO_PCBC=m
diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig
index 7cb703b948b1..1eb19ac45d09 100644
--- a/arch/powerpc/configs/ppc40x_defconfig
+++ b/arch/powerpc/configs/ppc40x_defconfig
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y
14CONFIG_PPC4xx_GPIO=y 14CONFIG_PPC4xx_GPIO=y
15CONFIG_ACADIA=y 15CONFIG_ACADIA=y
16CONFIG_EP405=y 16CONFIG_EP405=y
17CONFIG_HCU4=y
18CONFIG_HOTFOOT=y 17CONFIG_HOTFOOT=y
19CONFIG_KILAUEA=y 18CONFIG_KILAUEA=y
20CONFIG_MAKALU=y 19CONFIG_MAKALU=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 04360f9b0109..c47f2becfbc3 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -70,7 +70,7 @@ CONFIG_TAU_AVERAGE=y
70CONFIG_QUICC_ENGINE=y 70CONFIG_QUICC_ENGINE=y
71CONFIG_QE_GPIO=y 71CONFIG_QE_GPIO=y
72CONFIG_PPC_BESTCOMM=y 72CONFIG_PPC_BESTCOMM=y
73CONFIG_MPC8xxx_GPIO=y 73CONFIG_GPIO_MPC8XXX=y
74CONFIG_MCU_MPC8349EMITX=m 74CONFIG_MCU_MPC8349EMITX=m
75CONFIG_HIGHMEM=y 75CONFIG_HIGHMEM=y
76CONFIG_NO_HZ=y 76CONFIG_NO_HZ=y
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 16d25c0974be..d57c08acedfc 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -37,4 +37,6 @@ struct pdev_archdata {
37 u64 dma_mask; 37 u64 dma_mask;
38}; 38};
39 39
40#define ARCH_HAS_DMA_GET_REQUIRED_MASK
41
40#endif /* _ASM_POWERPC_DEVICE_H */ 42#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 3a6c586c4e40..14db29b18d0e 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -48,6 +48,8 @@
48#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000) 48#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
49#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) 49#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
50#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000) 50#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
51#define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000)
52#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000)
51 53
52#ifndef __ASSEMBLY__ 54#ifndef __ASSEMBLY__
53 55
@@ -65,6 +67,8 @@ enum {
65 FW_FEATURE_PSERIES_ALWAYS = 0, 67 FW_FEATURE_PSERIES_ALWAYS = 0,
66 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 68 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
67 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 69 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
70 FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
71 FW_FEATURE_POWERNV_ALWAYS = 0,
68 FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, 72 FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
69 FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, 73 FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
70 FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, 74 FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT,
@@ -78,6 +82,9 @@ enum {
78#ifdef CONFIG_PPC_ISERIES 82#ifdef CONFIG_PPC_ISERIES
79 FW_FEATURE_ISERIES_POSSIBLE | 83 FW_FEATURE_ISERIES_POSSIBLE |
80#endif 84#endif
85#ifdef CONFIG_PPC_POWERNV
86 FW_FEATURE_POWERNV_POSSIBLE |
87#endif
81#ifdef CONFIG_PPC_PS3 88#ifdef CONFIG_PPC_PS3
82 FW_FEATURE_PS3_POSSIBLE | 89 FW_FEATURE_PS3_POSSIBLE |
83#endif 90#endif
@@ -95,6 +102,9 @@ enum {
95#ifdef CONFIG_PPC_ISERIES 102#ifdef CONFIG_PPC_ISERIES
96 FW_FEATURE_ISERIES_ALWAYS & 103 FW_FEATURE_ISERIES_ALWAYS &
97#endif 104#endif
105#ifdef CONFIG_PPC_POWERNV
106 FW_FEATURE_POWERNV_ALWAYS &
107#endif
98#ifdef CONFIG_PPC_PS3 108#ifdef CONFIG_PPC_PS3
99 FW_FEATURE_PS3_ALWAYS & 109 FW_FEATURE_PS3_ALWAYS &
100#endif 110#endif
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 5856a66ab404..86004930a78e 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -1,15 +1,60 @@
1#ifndef _ASM_POWERPC_HUGETLB_H 1#ifndef _ASM_POWERPC_HUGETLB_H
2#define _ASM_POWERPC_HUGETLB_H 2#define _ASM_POWERPC_HUGETLB_H
3 3
4#ifdef CONFIG_HUGETLB_PAGE
4#include <asm/page.h> 5#include <asm/page.h>
5 6
7extern struct kmem_cache *hugepte_cache;
8extern void __init reserve_hugetlb_gpages(void);
9
10static inline pte_t *hugepd_page(hugepd_t hpd)
11{
12 BUG_ON(!hugepd_ok(hpd));
13 return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
14}
15
16static inline unsigned int hugepd_shift(hugepd_t hpd)
17{
18 return hpd.pd & HUGEPD_SHIFT_MASK;
19}
20
21static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
22 unsigned pdshift)
23{
24 /*
25 * On 32-bit, we have multiple higher-level table entries that point to
26 * the same hugepte. Just use the first one since they're all
27 * identical. So for that case, idx=0.
28 */
29 unsigned long idx = 0;
30
31 pte_t *dir = hugepd_page(*hpdp);
32#ifdef CONFIG_PPC64
33 idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp);
34#endif
35
36 return dir + idx;
37}
38
6pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, 39pte_t *huge_pte_offset_and_shift(struct mm_struct *mm,
7 unsigned long addr, unsigned *shift); 40 unsigned long addr, unsigned *shift);
8 41
9void flush_dcache_icache_hugepage(struct page *page); 42void flush_dcache_icache_hugepage(struct page *page);
10 43
44#if defined(CONFIG_PPC_MM_SLICES) || defined(CONFIG_PPC_SUBPAGE_PROT)
11int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, 45int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
12 unsigned long len); 46 unsigned long len);
47#else
48static inline int is_hugepage_only_range(struct mm_struct *mm,
49 unsigned long addr,
50 unsigned long len)
51{
52 return 0;
53}
54#endif
55
56void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte);
57void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
13 58
14void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, 59void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
15 unsigned long end, unsigned long floor, 60 unsigned long end, unsigned long floor,
@@ -50,8 +95,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
50static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, 95static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
51 unsigned long addr, pte_t *ptep) 96 unsigned long addr, pte_t *ptep)
52{ 97{
53 unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1); 98#ifdef CONFIG_PPC64
54 return __pte(old); 99 return __pte(pte_update(mm, addr, ptep, ~0UL, 1));
100#else
101 return __pte(pte_update(ptep, ~0UL, 0));
102#endif
55} 103}
56 104
57static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, 105static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -93,4 +141,15 @@ static inline void arch_release_hugepage(struct page *page)
93{ 141{
94} 142}
95 143
144#else /* ! CONFIG_HUGETLB_PAGE */
145static inline void reserve_hugetlb_gpages(void)
146{
147 pr_err("Cannot reserve gpages without hugetlb enabled\n");
148}
149static inline void flush_hugetlb_page(struct vm_area_struct *vma,
150 unsigned long vmaddr)
151{
152}
153#endif
154
96#endif /* _ASM_POWERPC_HUGETLB_H */ 155#endif /* _ASM_POWERPC_HUGETLB_H */
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 8a33698c61bd..f921eb121d39 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -2,7 +2,7 @@
2#define _ASM_POWERPC_KEXEC_H 2#define _ASM_POWERPC_KEXEC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#ifdef CONFIG_FSL_BOOKE 5#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_44x)
6 6
7/* 7/*
8 * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory 8 * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 47cacddb14cf..58fc21623014 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -85,8 +85,9 @@ struct machdep_calls {
85 void (*pci_dma_dev_setup)(struct pci_dev *dev); 85 void (*pci_dma_dev_setup)(struct pci_dev *dev);
86 void (*pci_dma_bus_setup)(struct pci_bus *bus); 86 void (*pci_dma_bus_setup)(struct pci_bus *bus);
87 87
88 /* Platform set_dma_mask override */ 88 /* Platform set_dma_mask and dma_get_required_mask overrides */
89 int (*dma_set_mask)(struct device *dev, u64 dma_mask); 89 int (*dma_set_mask)(struct device *dev, u64 dma_mask);
90 u64 (*dma_get_required_mask)(struct device *dev);
90 91
91 int (*probe)(void); 92 int (*probe)(void);
92 void (*setup_arch)(void); /* Optional, may be NULL */ 93 void (*setup_arch)(void); /* Optional, may be NULL */
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index 3ea0f9a259d8..0260ea5ec3c2 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -66,6 +66,7 @@
66#define MAS2_M 0x00000004 66#define MAS2_M 0x00000004
67#define MAS2_G 0x00000002 67#define MAS2_G 0x00000002
68#define MAS2_E 0x00000001 68#define MAS2_E 0x00000001
69#define MAS2_WIMGE_MASK 0x0000001f
69#define MAS2_EPN_MASK(size) (~0 << (size + 10)) 70#define MAS2_EPN_MASK(size) (~0 << (size + 10))
70#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags)) 71#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags))
71 72
@@ -80,6 +81,7 @@
80#define MAS3_SW 0x00000004 81#define MAS3_SW 0x00000004
81#define MAS3_UR 0x00000002 82#define MAS3_UR 0x00000002
82#define MAS3_SR 0x00000001 83#define MAS3_SR 0x00000001
84#define MAS3_BAP_MASK 0x0000003f
83#define MAS3_SPSIZE 0x0000003e 85#define MAS3_SPSIZE 0x0000003e
84#define MAS3_SPSIZE_SHIFT 1 86#define MAS3_SPSIZE_SHIFT 1
85 87
@@ -212,6 +214,11 @@ typedef struct {
212 unsigned int id; 214 unsigned int id;
213 unsigned int active; 215 unsigned int active;
214 unsigned long vdso_base; 216 unsigned long vdso_base;
217#ifdef CONFIG_PPC_MM_SLICES
218 u64 low_slices_psize; /* SLB page size encodings */
219 u64 high_slices_psize; /* 4 bits per slice for now */
220 u16 user_psize; /* page size index */
221#endif
215} mm_context_t; 222} mm_context_t;
216 223
217/* Page size definitions, common between 32 and 64-bit 224/* Page size definitions, common between 32 and 64-bit
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index b445e0af4c2b..db645ec842bd 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -262,8 +262,7 @@ extern void hash_failure_debug(unsigned long ea, unsigned long access,
262extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, 262extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
263 unsigned long pstart, unsigned long prot, 263 unsigned long pstart, unsigned long prot,
264 int psize, int ssize); 264 int psize, int ssize);
265extern void add_gpage(unsigned long addr, unsigned long page_size, 265extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages);
266 unsigned long number_of_pages);
267extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); 266extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
268 267
269extern void hpte_init_native(void); 268extern void hpte_init_native(void);
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 698b30638681..f0145522cfba 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -175,14 +175,16 @@ extern u64 ppc64_rma_size;
175#define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */ 175#define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */
176#define MMU_PAGE_256K 4 176#define MMU_PAGE_256K 4
177#define MMU_PAGE_1M 5 177#define MMU_PAGE_1M 5
178#define MMU_PAGE_8M 6 178#define MMU_PAGE_4M 6
179#define MMU_PAGE_16M 7 179#define MMU_PAGE_8M 7
180#define MMU_PAGE_256M 8 180#define MMU_PAGE_16M 8
181#define MMU_PAGE_1G 9 181#define MMU_PAGE_64M 9
182#define MMU_PAGE_16G 10 182#define MMU_PAGE_256M 10
183#define MMU_PAGE_64G 11 183#define MMU_PAGE_1G 11
184#define MMU_PAGE_COUNT 12 184#define MMU_PAGE_16G 12
185 185#define MMU_PAGE_64G 13
186
187#define MMU_PAGE_COUNT 14
186 188
187#if defined(CONFIG_PPC_STD_MMU_64) 189#if defined(CONFIG_PPC_STD_MMU_64)
188/* 64-bit classic hash table MMU */ 190/* 64-bit classic hash table MMU */
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index df18989e78d4..e6fae49e0b74 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -273,8 +273,6 @@ struct mpic
273 unsigned int irq_count; 273 unsigned int irq_count;
274 /* Number of sources */ 274 /* Number of sources */
275 unsigned int num_sources; 275 unsigned int num_sources;
276 /* Number of CPUs */
277 unsigned int num_cpus;
278 /* default senses array */ 276 /* default senses array */
279 unsigned char *senses; 277 unsigned char *senses;
280 unsigned int senses_count; 278 unsigned int senses_count;
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
new file mode 100644
index 000000000000..2893e8f5406d
--- /dev/null
+++ b/arch/powerpc/include/asm/opal.h
@@ -0,0 +1,443 @@
1/*
2 * PowerNV OPAL definitions.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef __OPAL_H
13#define __OPAL_H
14
15/****** Takeover interface ********/
16
17/* PAPR H-Call used to querty the HAL existence and/or instanciate
18 * it from within pHyp (tech preview only).
19 *
20 * This is exclusively used in prom_init.c
21 */
22
23#ifndef __ASSEMBLY__
24
25struct opal_takeover_args {
26 u64 k_image; /* r4 */
27 u64 k_size; /* r5 */
28 u64 k_entry; /* r6 */
29 u64 k_entry2; /* r7 */
30 u64 hal_addr; /* r8 */
31 u64 rd_image; /* r9 */
32 u64 rd_size; /* r10 */
33 u64 rd_loc; /* r11 */
34};
35
36extern long opal_query_takeover(u64 *hal_size, u64 *hal_align);
37
38extern long opal_do_takeover(struct opal_takeover_args *args);
39
40struct rtas_args;
41extern int opal_enter_rtas(struct rtas_args *args,
42 unsigned long data,
43 unsigned long entry);
44
45#endif /* __ASSEMBLY__ */
46
47/****** OPAL APIs ******/
48
49/* Return codes */
50#define OPAL_SUCCESS 0
51#define OPAL_PARAMETER -1
52#define OPAL_BUSY -2
53#define OPAL_PARTIAL -3
54#define OPAL_CONSTRAINED -4
55#define OPAL_CLOSED -5
56#define OPAL_HARDWARE -6
57#define OPAL_UNSUPPORTED -7
58#define OPAL_PERMISSION -8
59#define OPAL_NO_MEM -9
60#define OPAL_RESOURCE -10
61#define OPAL_INTERNAL_ERROR -11
62#define OPAL_BUSY_EVENT -12
63#define OPAL_HARDWARE_FROZEN -13
64
65/* API Tokens (in r0) */
66#define OPAL_CONSOLE_WRITE 1
67#define OPAL_CONSOLE_READ 2
68#define OPAL_RTC_READ 3
69#define OPAL_RTC_WRITE 4
70#define OPAL_CEC_POWER_DOWN 5
71#define OPAL_CEC_REBOOT 6
72#define OPAL_READ_NVRAM 7
73#define OPAL_WRITE_NVRAM 8
74#define OPAL_HANDLE_INTERRUPT 9
75#define OPAL_POLL_EVENTS 10
76#define OPAL_PCI_SET_HUB_TCE_MEMORY 11
77#define OPAL_PCI_SET_PHB_TCE_MEMORY 12
78#define OPAL_PCI_CONFIG_READ_BYTE 13
79#define OPAL_PCI_CONFIG_READ_HALF_WORD 14
80#define OPAL_PCI_CONFIG_READ_WORD 15
81#define OPAL_PCI_CONFIG_WRITE_BYTE 16
82#define OPAL_PCI_CONFIG_WRITE_HALF_WORD 17
83#define OPAL_PCI_CONFIG_WRITE_WORD 18
84#define OPAL_SET_XIVE 19
85#define OPAL_GET_XIVE 20
86#define OPAL_GET_COMPLETION_TOKEN_STATUS 21 /* obsolete */
87#define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER 22
88#define OPAL_PCI_EEH_FREEZE_STATUS 23
89#define OPAL_PCI_SHPC 24
90#define OPAL_CONSOLE_WRITE_BUFFER_SPACE 25
91#define OPAL_PCI_EEH_FREEZE_CLEAR 26
92#define OPAL_PCI_PHB_MMIO_ENABLE 27
93#define OPAL_PCI_SET_PHB_MEM_WINDOW 28
94#define OPAL_PCI_MAP_PE_MMIO_WINDOW 29
95#define OPAL_PCI_SET_PHB_TABLE_MEMORY 30
96#define OPAL_PCI_SET_PE 31
97#define OPAL_PCI_SET_PELTV 32
98#define OPAL_PCI_SET_MVE 33
99#define OPAL_PCI_SET_MVE_ENABLE 34
100#define OPAL_PCI_GET_XIVE_REISSUE 35
101#define OPAL_PCI_SET_XIVE_REISSUE 36
102#define OPAL_PCI_SET_XIVE_PE 37
103#define OPAL_GET_XIVE_SOURCE 38
104#define OPAL_GET_MSI_32 39
105#define OPAL_GET_MSI_64 40
106#define OPAL_START_CPU 41
107#define OPAL_QUERY_CPU_STATUS 42
108#define OPAL_WRITE_OPPANEL 43
109#define OPAL_PCI_MAP_PE_DMA_WINDOW 44
110#define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL 45
111#define OPAL_PCI_RESET 49
112
113#ifndef __ASSEMBLY__
114
115/* Other enums */
116enum OpalVendorApiTokens {
117 OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
118};
119enum OpalFreezeState {
120 OPAL_EEH_STOPPED_NOT_FROZEN = 0,
121 OPAL_EEH_STOPPED_MMIO_FREEZE = 1,
122 OPAL_EEH_STOPPED_DMA_FREEZE = 2,
123 OPAL_EEH_STOPPED_MMIO_DMA_FREEZE = 3,
124 OPAL_EEH_STOPPED_RESET = 4,
125 OPAL_EEH_STOPPED_TEMP_UNAVAIL = 5,
126 OPAL_EEH_STOPPED_PERM_UNAVAIL = 6
127};
128enum OpalEehFreezeActionToken {
129 OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1,
130 OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2,
131 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3
132};
133enum OpalPciStatusToken {
134 OPAL_EEH_PHB_NO_ERROR = 0,
135 OPAL_EEH_PHB_FATAL = 1,
136 OPAL_EEH_PHB_RECOVERABLE = 2,
137 OPAL_EEH_PHB_BUS_ERROR = 3,
138 OPAL_EEH_PCI_NO_DEVSEL = 4,
139 OPAL_EEH_PCI_TA = 5,
140 OPAL_EEH_PCIEX_UR = 6,
141 OPAL_EEH_PCIEX_CA = 7,
142 OPAL_EEH_PCI_MMIO_ERROR = 8,
143 OPAL_EEH_PCI_DMA_ERROR = 9
144};
145enum OpalShpcAction {
146 OPAL_SHPC_GET_LINK_STATE = 0,
147 OPAL_SHPC_GET_SLOT_STATE = 1
148};
149enum OpalShpcLinkState {
150 OPAL_SHPC_LINK_DOWN = 0,
151 OPAL_SHPC_LINK_UP = 1
152};
153enum OpalMmioWindowType {
154 OPAL_M32_WINDOW_TYPE = 1,
155 OPAL_M64_WINDOW_TYPE = 2,
156 OPAL_IO_WINDOW_TYPE = 3
157};
158enum OpalShpcSlotState {
159 OPAL_SHPC_DEV_NOT_PRESENT = 0,
160 OPAL_SHPC_DEV_PRESENT = 1
161};
162enum OpalExceptionHandler {
163 OPAL_MACHINE_CHECK_HANDLER = 1,
164 OPAL_HYPERVISOR_MAINTENANCE_HANDLER = 2,
165 OPAL_SOFTPATCH_HANDLER = 3
166};
167enum OpalPendingState {
168 OPAL_EVENT_OPAL_INTERNAL = 0x1,
169 OPAL_EVENT_NVRAM = 0x2,
170 OPAL_EVENT_RTC = 0x4,
171 OPAL_EVENT_CONSOLE_OUTPUT = 0x8,
172 OPAL_EVENT_CONSOLE_INPUT = 0x10
173};
174
175/* Machine check related definitions */
176enum OpalMCE_Version {
177 OpalMCE_V1 = 1,
178};
179
180enum OpalMCE_Severity {
181 OpalMCE_SEV_NO_ERROR = 0,
182 OpalMCE_SEV_WARNING = 1,
183 OpalMCE_SEV_ERROR_SYNC = 2,
184 OpalMCE_SEV_FATAL = 3,
185};
186
187enum OpalMCE_Disposition {
188 OpalMCE_DISPOSITION_RECOVERED = 0,
189 OpalMCE_DISPOSITION_NOT_RECOVERED = 1,
190};
191
192enum OpalMCE_Initiator {
193 OpalMCE_INITIATOR_UNKNOWN = 0,
194 OpalMCE_INITIATOR_CPU = 1,
195};
196
197enum OpalMCE_ErrorType {
198 OpalMCE_ERROR_TYPE_UNKNOWN = 0,
199 OpalMCE_ERROR_TYPE_UE = 1,
200 OpalMCE_ERROR_TYPE_SLB = 2,
201 OpalMCE_ERROR_TYPE_ERAT = 3,
202 OpalMCE_ERROR_TYPE_TLB = 4,
203};
204
205enum OpalMCE_UeErrorType {
206 OpalMCE_UE_ERROR_INDETERMINATE = 0,
207 OpalMCE_UE_ERROR_IFETCH = 1,
208 OpalMCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2,
209 OpalMCE_UE_ERROR_LOAD_STORE = 3,
210 OpalMCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4,
211};
212
213enum OpalMCE_SlbErrorType {
214 OpalMCE_SLB_ERROR_INDETERMINATE = 0,
215 OpalMCE_SLB_ERROR_PARITY = 1,
216 OpalMCE_SLB_ERROR_MULTIHIT = 2,
217};
218
219enum OpalMCE_EratErrorType {
220 OpalMCE_ERAT_ERROR_INDETERMINATE = 0,
221 OpalMCE_ERAT_ERROR_PARITY = 1,
222 OpalMCE_ERAT_ERROR_MULTIHIT = 2,
223};
224
225enum OpalMCE_TlbErrorType {
226 OpalMCE_TLB_ERROR_INDETERMINATE = 0,
227 OpalMCE_TLB_ERROR_PARITY = 1,
228 OpalMCE_TLB_ERROR_MULTIHIT = 2,
229};
230
231enum OpalThreadStatus {
232 OPAL_THREAD_INACTIVE = 0x0,
233 OPAL_THREAD_STARTED = 0x1
234};
235
236enum OpalPciBusCompare {
237 OpalPciBusAny = 0, /* Any bus number match */
238 OpalPciBus3Bits = 2, /* Match top 3 bits of bus number */
239 OpalPciBus4Bits = 3, /* Match top 4 bits of bus number */
240 OpalPciBus5Bits = 4, /* Match top 5 bits of bus number */
241 OpalPciBus6Bits = 5, /* Match top 6 bits of bus number */
242 OpalPciBus7Bits = 6, /* Match top 7 bits of bus number */
243 OpalPciBusAll = 7, /* Match bus number exactly */
244};
245
246enum OpalDeviceCompare {
247 OPAL_IGNORE_RID_DEVICE_NUMBER = 0,
248 OPAL_COMPARE_RID_DEVICE_NUMBER = 1
249};
250
251enum OpalFuncCompare {
252 OPAL_IGNORE_RID_FUNCTION_NUMBER = 0,
253 OPAL_COMPARE_RID_FUNCTION_NUMBER = 1
254};
255
256enum OpalPeAction {
257 OPAL_UNMAP_PE = 0,
258 OPAL_MAP_PE = 1
259};
260
261enum OpalPciResetAndReinitScope {
262 OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3,
263 OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5,
264 OPAL_PCI_IODA_RESET = 6,
265};
266
267enum OpalPciResetState { OPAL_DEASSERT_RESET = 0, OPAL_ASSERT_RESET = 1 };
268
269struct opal_machine_check_event {
270 enum OpalMCE_Version version:8; /* 0x00 */
271 uint8_t in_use; /* 0x01 */
272 enum OpalMCE_Severity severity:8; /* 0x02 */
273 enum OpalMCE_Initiator initiator:8; /* 0x03 */
274 enum OpalMCE_ErrorType error_type:8; /* 0x04 */
275 enum OpalMCE_Disposition disposition:8; /* 0x05 */
276 uint8_t reserved_1[2]; /* 0x06 */
277 uint64_t gpr3; /* 0x08 */
278 uint64_t srr0; /* 0x10 */
279 uint64_t srr1; /* 0x18 */
280 union { /* 0x20 */
281 struct {
282 enum OpalMCE_UeErrorType ue_error_type:8;
283 uint8_t effective_address_provided;
284 uint8_t physical_address_provided;
285 uint8_t reserved_1[5];
286 uint64_t effective_address;
287 uint64_t physical_address;
288 uint8_t reserved_2[8];
289 } ue_error;
290
291 struct {
292 enum OpalMCE_SlbErrorType slb_error_type:8;
293 uint8_t effective_address_provided;
294 uint8_t reserved_1[6];
295 uint64_t effective_address;
296 uint8_t reserved_2[16];
297 } slb_error;
298
299 struct {
300 enum OpalMCE_EratErrorType erat_error_type:8;
301 uint8_t effective_address_provided;
302 uint8_t reserved_1[6];
303 uint64_t effective_address;
304 uint8_t reserved_2[16];
305 } erat_error;
306
307 struct {
308 enum OpalMCE_TlbErrorType tlb_error_type:8;
309 uint8_t effective_address_provided;
310 uint8_t reserved_1[6];
311 uint64_t effective_address;
312 uint8_t reserved_2[16];
313 } tlb_error;
314 } u;
315};
316
317typedef struct oppanel_line {
318 /* XXX */
319} oppanel_line_t;
320
321/* API functions */
322int64_t opal_console_write(int64_t term_number, int64_t *length,
323 const uint8_t *buffer);
324int64_t opal_console_read(int64_t term_number, int64_t *length,
325 uint8_t *buffer);
326int64_t opal_console_write_buffer_space(int64_t term_number,
327 int64_t *length);
328int64_t opal_rtc_read(uint32_t *year_month_day,
329 uint64_t *hour_minute_second_millisecond);
330int64_t opal_rtc_write(uint32_t year_month_day,
331 uint64_t hour_minute_second_millisecond);
332int64_t opal_cec_power_down(uint64_t request);
333int64_t opal_cec_reboot(void);
334int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
335int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
336int64_t opal_handle_interrupt(uint64_t isn, uint64_t *outstanding_event_mask);
337int64_t opal_poll_events(uint64_t *outstanding_event_mask);
338int64_t opal_pci_set_hub_tce_memory(uint64_t hub_id, uint64_t tce_mem_addr,
339 uint64_t tce_mem_size);
340int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr,
341 uint64_t tce_mem_size);
342int64_t opal_pci_config_read_byte(uint64_t phb_id, uint64_t bus_dev_func,
343 uint64_t offset, uint8_t *data);
344int64_t opal_pci_config_read_half_word(uint64_t phb_id, uint64_t bus_dev_func,
345 uint64_t offset, uint16_t *data);
346int64_t opal_pci_config_read_word(uint64_t phb_id, uint64_t bus_dev_func,
347 uint64_t offset, uint32_t *data);
348int64_t opal_pci_config_write_byte(uint64_t phb_id, uint64_t bus_dev_func,
349 uint64_t offset, uint8_t data);
350int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func,
351 uint64_t offset, uint16_t data);
352int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func,
353 uint64_t offset, uint32_t data);
354int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority);
355int64_t opal_get_xive(uint32_t isn, uint16_t *server, uint8_t *priority);
356int64_t opal_register_exception_handler(uint64_t opal_exception,
357 uint64_t handler_address,
358 uint64_t glue_cache_line);
359int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number,
360 uint8_t *freeze_state,
361 uint16_t *pci_error_type,
362 uint64_t *phb_status);
363int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number,
364 uint64_t eeh_action_token);
365int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state);
366
367
368
369int64_t opal_pci_phb_mmio_enable(uint64_t phb_id, uint16_t window_type,
370 uint16_t window_num, uint16_t enable);
371int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type,
372 uint16_t window_num,
373 uint64_t starting_real_address,
374 uint64_t starting_pci_address,
375 uint16_t segment_size);
376int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number,
377 uint16_t window_type, uint16_t window_num,
378 uint16_t segment_num);
379int64_t opal_pci_set_phb_table_memory(uint64_t phb_id, uint64_t rtt_addr,
380 uint64_t ivt_addr, uint64_t ivt_len,
381 uint64_t reject_array_addr,
382 uint64_t peltv_addr);
383int64_t opal_pci_set_pe(uint64_t phb_id, uint64_t pe_number, uint64_t bus_dev_func,
384 uint8_t bus_compare, uint8_t dev_compare, uint8_t func_compare,
385 uint8_t pe_action);
386int64_t opal_pci_set_peltv(uint64_t phb_id, uint32_t parent_pe, uint32_t child_pe,
387 uint8_t state);
388int64_t opal_pci_set_mve(uint64_t phb_id, uint32_t mve_number, uint32_t pe_number);
389int64_t opal_pci_set_mve_enable(uint64_t phb_id, uint32_t mve_number,
390 uint32_t state);
391int64_t opal_pci_get_xive_reissue(uint64_t phb_id, uint32_t xive_number,
392 uint8_t *p_bit, uint8_t *q_bit);
393int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number,
394 uint8_t p_bit, uint8_t q_bit);
395int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number,
396 uint32_t xive_num);
397int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num,
398 int32_t *interrupt_source_number);
399int64_t opal_get_msi_32(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num,
400 uint8_t msi_range, uint32_t *msi_address,
401 uint32_t *message_data);
402int64_t opal_get_msi_64(uint64_t phb_id, uint32_t mve_number,
403 uint32_t xive_num, uint8_t msi_range,
404 uint64_t *msi_address, uint32_t *message_data);
405int64_t opal_start_cpu(uint64_t thread_number, uint64_t start_address);
406int64_t opal_query_cpu_status(uint64_t thread_number, uint8_t *thread_status);
407int64_t opal_write_oppanel(oppanel_line_t *lines, uint64_t num_lines);
408int64_t opal_pci_map_pe_dma_window(uint64_t phb_id, uint16_t pe_number, uint16_t window_id,
409 uint16_t tce_levels, uint64_t tce_table_addr,
410 uint64_t tce_table_size, uint64_t tce_page_size);
411int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id, uint16_t pe_number,
412 uint16_t dma_window_number, uint64_t pci_start_addr,
413 uint64_t pci_mem_size);
414int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope, uint8_t assert_state);
415
416/* Internal functions */
417extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
418
419extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
420extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
421
422extern void hvc_opal_init_early(void);
423
424/* Internal functions */
425extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
426 int depth, void *data);
427
428extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
429extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
430
431extern void hvc_opal_init_early(void);
432
433struct rtc_time;
434extern int opal_set_rtc_time(struct rtc_time *tm);
435extern void opal_get_rtc_time(struct rtc_time *tm);
436extern unsigned long opal_get_boot_time(void);
437extern void opal_nvram_init(void);
438
439extern int opal_machine_check(struct pt_regs *regs);
440
441#endif /* __ASSEMBLY__ */
442
443#endif /* __OPAL_H */
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 516bfb3f47d9..17722c73ba2e 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -43,6 +43,7 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
43#define get_slb_shadow() (get_paca()->slb_shadow_ptr) 43#define get_slb_shadow() (get_paca()->slb_shadow_ptr)
44 44
45struct task_struct; 45struct task_struct;
46struct opal_machine_check_event;
46 47
47/* 48/*
48 * Defines the layout of the paca. 49 * Defines the layout of the paca.
@@ -135,6 +136,13 @@ struct paca_struct {
135 u8 io_sync; /* writel() needs spin_unlock sync */ 136 u8 io_sync; /* writel() needs spin_unlock sync */
136 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ 137 u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
137 138
139#ifdef CONFIG_PPC_POWERNV
140 /* Pointer to OPAL machine check event structure set by the
141 * early exception handler for use by high level C handler
142 */
143 struct opal_machine_check_event *opal_mc_evt;
144#endif
145
138 /* Stuff for accurate time accounting */ 146 /* Stuff for accurate time accounting */
139 u64 user_time; /* accumulated usermode TB ticks */ 147 u64 user_time; /* accumulated usermode TB ticks */
140 u64 system_time; /* accumulated system TB ticks */ 148 u64 system_time; /* accumulated system TB ticks */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 2cd664ef0a5e..dd9c4fd038e0 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -36,6 +36,18 @@
36 36
37#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) 37#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
38 38
39#ifndef __ASSEMBLY__
40#ifdef CONFIG_HUGETLB_PAGE
41extern unsigned int HPAGE_SHIFT;
42#else
43#define HPAGE_SHIFT PAGE_SHIFT
44#endif
45#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
46#define HPAGE_MASK (~(HPAGE_SIZE - 1))
47#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
48#define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1)
49#endif
50
39/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ 51/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
40#define __HAVE_ARCH_GATE_AREA 1 52#define __HAVE_ARCH_GATE_AREA 1
41 53
@@ -158,6 +170,24 @@ extern phys_addr_t kernstart_addr;
158#define is_kernel_addr(x) ((x) >= PAGE_OFFSET) 170#define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
159#endif 171#endif
160 172
173/*
174 * Use the top bit of the higher-level page table entries to indicate whether
175 * the entries we point to contain hugepages. This works because we know that
176 * the page tables live in kernel space. If we ever decide to support having
177 * page tables at arbitrary addresses, this breaks and will have to change.
178 */
179#ifdef CONFIG_PPC64
180#define PD_HUGE 0x8000000000000000
181#else
182#define PD_HUGE 0x80000000
183#endif
184
185/*
186 * Some number of bits at the level of the page table that points to
187 * a hugepte are used to encode the size. This masks those bits.
188 */
189#define HUGEPD_SHIFT_MASK 0x3f
190
161#ifndef __ASSEMBLY__ 191#ifndef __ASSEMBLY__
162 192
163#undef STRICT_MM_TYPECHECKS 193#undef STRICT_MM_TYPECHECKS
@@ -243,7 +273,6 @@ typedef unsigned long pgprot_t;
243#endif 273#endif
244 274
245typedef struct { signed long pd; } hugepd_t; 275typedef struct { signed long pd; } hugepd_t;
246#define HUGEPD_SHIFT_MASK 0x3f
247 276
248#ifdef CONFIG_HUGETLB_PAGE 277#ifdef CONFIG_HUGETLB_PAGE
249static inline int hugepd_ok(hugepd_t hpd) 278static inline int hugepd_ok(hugepd_t hpd)
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index 9356262fd3cc..fb40ede6bc0d 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -64,17 +64,6 @@ extern void copy_page(void *to, void *from);
64/* Log 2 of page table size */ 64/* Log 2 of page table size */
65extern u64 ppc64_pft_size; 65extern u64 ppc64_pft_size;
66 66
67/* Large pages size */
68#ifdef CONFIG_HUGETLB_PAGE
69extern unsigned int HPAGE_SHIFT;
70#else
71#define HPAGE_SHIFT PAGE_SHIFT
72#endif
73#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
74#define HPAGE_MASK (~(HPAGE_SIZE - 1))
75#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
76#define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1)
77
78#endif /* __ASSEMBLY__ */ 67#endif /* __ASSEMBLY__ */
79 68
80#ifdef CONFIG_PPC_MM_SLICES 69#ifdef CONFIG_PPC_MM_SLICES
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
index 082d515930a2..0156702ba24e 100644
--- a/arch/powerpc/include/asm/pte-book3e.h
+++ b/arch/powerpc/include/asm/pte-book3e.h
@@ -72,6 +72,9 @@
72#define PTE_RPN_SHIFT (24) 72#define PTE_RPN_SHIFT (24)
73#endif 73#endif
74 74
75#define PTE_WIMGE_SHIFT (19)
76#define PTE_BAP_SHIFT (2)
77
75/* On 32-bit, we never clear the top part of the PTE */ 78/* On 32-bit, we never clear the top part of the PTE */
76#ifdef CONFIG_PPC32 79#ifdef CONFIG_PPC32
77#define _PTE_NONE_MASK 0xffffffff00000000ULL 80#define _PTE_NONE_MASK 0xffffffff00000000ULL
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 9ec0b39f9ddc..28cdbd9f399c 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -548,6 +548,9 @@
548#define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */ 548#define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */
549#define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */ 549#define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */
550 550
551/* Bit definitions for L1CSR2. */
552#define L1CSR2_DCWS 0x40000000 /* Data Cache write shadow */
553
551/* Bit definitions for L2CSR0. */ 554/* Bit definitions for L2CSR0. */
552#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ 555#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */
553#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ 556#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 58625d1e7802..41f69ae79d4e 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -249,10 +249,12 @@ extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
249#define ERR_FLAG_ALREADY_LOGGED 0x0 249#define ERR_FLAG_ALREADY_LOGGED 0x0
250#define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ 250#define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */
251#define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */ 251#define ERR_TYPE_RTAS_LOG 0x2 /* from rtas event-scan */
252#define ERR_TYPE_KERNEL_PANIC 0x4 /* from panic() */ 252#define ERR_TYPE_KERNEL_PANIC 0x4 /* from die()/panic() */
253#define ERR_TYPE_KERNEL_PANIC_GZ 0x8 /* ditto, compressed */
253 254
254/* All the types and not flags */ 255/* All the types and not flags */
255#define ERR_TYPE_MASK (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC) 256#define ERR_TYPE_MASK \
257 (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC | ERR_TYPE_KERNEL_PANIC_GZ)
256 258
257#define RTAS_DEBUG KERN_DEBUG "RTAS: " 259#define RTAS_DEBUG KERN_DEBUG "RTAS: "
258 260
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 15a70b7f638b..adba970ce918 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -65,6 +65,7 @@ int generic_cpu_disable(void);
65void generic_cpu_die(unsigned int cpu); 65void generic_cpu_die(unsigned int cpu);
66void generic_mach_cpu_die(void); 66void generic_mach_cpu_die(void);
67void generic_set_cpu_dead(unsigned int cpu); 67void generic_set_cpu_dead(unsigned int cpu);
68int generic_check_cpu_restart(unsigned int cpu);
68#endif 69#endif
69 70
70#ifdef CONFIG_PPC64 71#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h
index 54a47ea2c3aa..0c5fa3145615 100644
--- a/arch/powerpc/include/asm/sparsemem.h
+++ b/arch/powerpc/include/asm/sparsemem.h
@@ -16,7 +16,7 @@
16#endif /* CONFIG_SPARSEMEM */ 16#endif /* CONFIG_SPARSEMEM */
17 17
18#ifdef CONFIG_MEMORY_HOTPLUG 18#ifdef CONFIG_MEMORY_HOTPLUG
19extern void create_section_mapping(unsigned long start, unsigned long end); 19extern int create_section_mapping(unsigned long start, unsigned long end);
20extern int remove_section_mapping(unsigned long start, unsigned long end); 20extern int remove_section_mapping(unsigned long start, unsigned long end);
21#ifdef CONFIG_NUMA 21#ifdef CONFIG_NUMA
22extern int hot_add_scn_to_nid(unsigned long scn_addr); 22extern int hot_add_scn_to_nid(unsigned long scn_addr);
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 7ef0d90defc8..1e104af08483 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -19,14 +19,10 @@ struct device_node;
19#define RECLAIM_DISTANCE 10 19#define RECLAIM_DISTANCE 10
20 20
21/* 21/*
22 * Before going off node we want the VM to try and reclaim from the local 22 * Avoid creating an extra level of balancing (SD_ALLNODES) on the largest
23 * node. It does this if the remote distance is larger than RECLAIM_DISTANCE. 23 * POWER7 boxes which have a maximum of 32 nodes.
24 * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of
25 * 20, we never reclaim and go off node straight away.
26 *
27 * To fix this we choose a smaller value of RECLAIM_DISTANCE.
28 */ 24 */
29#define RECLAIM_DISTANCE 10 25#define SD_NODES_PER_DOMAIN 32
30 26
31#include <asm/mmzone.h> 27#include <asm/mmzone.h>
32 28
@@ -69,11 +65,11 @@ static inline int pcibus_to_node(struct pci_bus *bus)
69 .forkexec_idx = 0, \ 65 .forkexec_idx = 0, \
70 \ 66 \
71 .flags = 1*SD_LOAD_BALANCE \ 67 .flags = 1*SD_LOAD_BALANCE \
72 | 1*SD_BALANCE_NEWIDLE \ 68 | 0*SD_BALANCE_NEWIDLE \
73 | 1*SD_BALANCE_EXEC \ 69 | 1*SD_BALANCE_EXEC \
74 | 1*SD_BALANCE_FORK \ 70 | 1*SD_BALANCE_FORK \
75 | 0*SD_BALANCE_WAKE \ 71 | 0*SD_BALANCE_WAKE \
76 | 0*SD_WAKE_AFFINE \ 72 | 1*SD_WAKE_AFFINE \
77 | 0*SD_PREFER_LOCAL \ 73 | 0*SD_PREFER_LOCAL \
78 | 0*SD_SHARE_CPUPOWER \ 74 | 0*SD_SHARE_CPUPOWER \
79 | 0*SD_POWERSAVINGS_BALANCE \ 75 | 0*SD_POWERSAVINGS_BALANCE \
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 5354ae91bdde..8338aef5a4d3 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -55,6 +55,9 @@ extern void __init udbg_init_cpm(void);
55extern void __init udbg_init_usbgecko(void); 55extern void __init udbg_init_usbgecko(void);
56extern void __init udbg_init_wsp(void); 56extern void __init udbg_init_wsp(void);
57extern void __init udbg_init_ehv_bc(void); 57extern void __init udbg_init_ehv_bc(void);
58extern void __init udbg_init_ps3gelic(void);
59extern void __init udbg_init_debug_opal_raw(void);
60extern void __init udbg_init_debug_opal_hvsi(void);
58 61
59#endif /* __KERNEL__ */ 62#endif /* __KERNEL__ */
60#endif /* _ASM_POWERPC_UDBG_H */ 63#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index b183a4062011..bd6c401c0ee5 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -27,10 +27,18 @@
27#define MAX_NUM_PRIORITIES 3 27#define MAX_NUM_PRIORITIES 3
28 28
29/* Native ICP */ 29/* Native ICP */
30#ifdef CONFIG_PPC_ICP_NATIVE
30extern int icp_native_init(void); 31extern int icp_native_init(void);
32#else
33static inline int icp_native_init(void) { return -ENODEV; }
34#endif
31 35
32/* PAPR ICP */ 36/* PAPR ICP */
37#ifdef CONFIG_PPC_ICP_HV
33extern int icp_hv_init(void); 38extern int icp_hv_init(void);
39#else
40static inline int icp_hv_init(void) { return -ENODEV; }
41#endif
34 42
35/* ICP ops */ 43/* ICP ops */
36struct icp_ops { 44struct icp_ops {
@@ -51,7 +59,18 @@ extern const struct icp_ops *icp_ops;
51extern int ics_native_init(void); 59extern int ics_native_init(void);
52 60
53/* RTAS ICS */ 61/* RTAS ICS */
62#ifdef CONFIG_PPC_ICS_RTAS
54extern int ics_rtas_init(void); 63extern int ics_rtas_init(void);
64#else
65static inline int ics_rtas_init(void) { return -ENODEV; }
66#endif
67
68/* HAL ICS */
69#ifdef CONFIG_PPC_POWERNV
70extern int ics_opal_init(void);
71#else
72static inline int ics_opal_init(void) { return -ENODEV; }
73#endif
55 74
56/* ICS instance, hooked up to chip_data of an irq */ 75/* ICS instance, hooked up to chip_data of an irq */
57struct ics { 76struct ics {
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 69f7ffe7f674..7c5324f1ec9c 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -49,6 +49,9 @@
49#ifdef CONFIG_PPC_ISERIES 49#ifdef CONFIG_PPC_ISERIES
50#include <asm/iseries/alpaca.h> 50#include <asm/iseries/alpaca.h>
51#endif 51#endif
52#ifdef CONFIG_PPC_POWERNV
53#include <asm/opal.h>
54#endif
52#if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST) 55#if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST)
53#include <linux/kvm_host.h> 56#include <linux/kvm_host.h>
54#endif 57#endif
@@ -610,5 +613,12 @@ int main(void)
610 arch.timing_last_enter.tv32.tbl)); 613 arch.timing_last_enter.tv32.tbl));
611#endif 614#endif
612 615
616#ifdef CONFIG_PPC_POWERNV
617 DEFINE(OPAL_MC_GPR3, offsetof(struct opal_machine_check_event, gpr3));
618 DEFINE(OPAL_MC_SRR0, offsetof(struct opal_machine_check_event, srr0));
619 DEFINE(OPAL_MC_SRR1, offsetof(struct opal_machine_check_event, srr1));
620 DEFINE(PACA_OPAL_MC_EVT, offsetof(struct paca_struct, opal_mc_evt));
621#endif
622
613 return 0; 623 return 0;
614} 624}
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index e7554154a6de..6f04b9c383a7 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -90,13 +90,27 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
90 return 1; 90 return 1;
91} 91}
92 92
93static u64 dma_iommu_get_required_mask(struct device *dev)
94{
95 struct iommu_table *tbl = get_iommu_table_base(dev);
96 u64 mask;
97 if (!tbl)
98 return 0;
99
100 mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1);
101 mask += mask - 1;
102
103 return mask;
104}
105
93struct dma_map_ops dma_iommu_ops = { 106struct dma_map_ops dma_iommu_ops = {
94 .alloc_coherent = dma_iommu_alloc_coherent, 107 .alloc_coherent = dma_iommu_alloc_coherent,
95 .free_coherent = dma_iommu_free_coherent, 108 .free_coherent = dma_iommu_free_coherent,
96 .map_sg = dma_iommu_map_sg, 109 .map_sg = dma_iommu_map_sg,
97 .unmap_sg = dma_iommu_unmap_sg, 110 .unmap_sg = dma_iommu_unmap_sg,
98 .dma_supported = dma_iommu_dma_supported, 111 .dma_supported = dma_iommu_dma_supported,
99 .map_page = dma_iommu_map_page, 112 .map_page = dma_iommu_map_page,
100 .unmap_page = dma_iommu_unmap_page, 113 .unmap_page = dma_iommu_unmap_page,
114 .get_required_mask = dma_iommu_get_required_mask,
101}; 115};
102EXPORT_SYMBOL(dma_iommu_ops); 116EXPORT_SYMBOL(dma_iommu_ops);
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 4295e0b94b2d..1ebc9189aada 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -24,6 +24,21 @@
24 24
25unsigned int ppc_swiotlb_enable; 25unsigned int ppc_swiotlb_enable;
26 26
27static u64 swiotlb_powerpc_get_required(struct device *dev)
28{
29 u64 end, mask, max_direct_dma_addr = dev->archdata.max_direct_dma_addr;
30
31 end = memblock_end_of_DRAM();
32 if (max_direct_dma_addr && end > max_direct_dma_addr)
33 end = max_direct_dma_addr;
34 end += get_dma_offset(dev);
35
36 mask = 1ULL << (fls64(end) - 1);
37 mask += mask - 1;
38
39 return mask;
40}
41
27/* 42/*
28 * At the moment, all platforms that use this code only require 43 * At the moment, all platforms that use this code only require
29 * swiotlb to be used if we're operating on HIGHMEM. Since 44 * swiotlb to be used if we're operating on HIGHMEM. Since
@@ -44,6 +59,7 @@ struct dma_map_ops swiotlb_dma_ops = {
44 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, 59 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
45 .sync_sg_for_device = swiotlb_sync_sg_for_device, 60 .sync_sg_for_device = swiotlb_sync_sg_for_device,
46 .mapping_error = swiotlb_dma_mapping_error, 61 .mapping_error = swiotlb_dma_mapping_error,
62 .get_required_mask = swiotlb_powerpc_get_required,
47}; 63};
48 64
49void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev) 65void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 4f0959fbfbee..8593f53c4f6c 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -96,6 +96,18 @@ static int dma_direct_dma_supported(struct device *dev, u64 mask)
96#endif 96#endif
97} 97}
98 98
99static u64 dma_direct_get_required_mask(struct device *dev)
100{
101 u64 end, mask;
102
103 end = memblock_end_of_DRAM() + get_dma_offset(dev);
104
105 mask = 1ULL << (fls64(end) - 1);
106 mask += mask - 1;
107
108 return mask;
109}
110
99static inline dma_addr_t dma_direct_map_page(struct device *dev, 111static inline dma_addr_t dma_direct_map_page(struct device *dev,
100 struct page *page, 112 struct page *page,
101 unsigned long offset, 113 unsigned long offset,
@@ -137,13 +149,14 @@ static inline void dma_direct_sync_single(struct device *dev,
137#endif 149#endif
138 150
139struct dma_map_ops dma_direct_ops = { 151struct dma_map_ops dma_direct_ops = {
140 .alloc_coherent = dma_direct_alloc_coherent, 152 .alloc_coherent = dma_direct_alloc_coherent,
141 .free_coherent = dma_direct_free_coherent, 153 .free_coherent = dma_direct_free_coherent,
142 .map_sg = dma_direct_map_sg, 154 .map_sg = dma_direct_map_sg,
143 .unmap_sg = dma_direct_unmap_sg, 155 .unmap_sg = dma_direct_unmap_sg,
144 .dma_supported = dma_direct_dma_supported, 156 .dma_supported = dma_direct_dma_supported,
145 .map_page = dma_direct_map_page, 157 .map_page = dma_direct_map_page,
146 .unmap_page = dma_direct_unmap_page, 158 .unmap_page = dma_direct_unmap_page,
159 .get_required_mask = dma_direct_get_required_mask,
147#ifdef CONFIG_NOT_COHERENT_CACHE 160#ifdef CONFIG_NOT_COHERENT_CACHE
148 .sync_single_for_cpu = dma_direct_sync_single, 161 .sync_single_for_cpu = dma_direct_sync_single,
149 .sync_single_for_device = dma_direct_sync_single, 162 .sync_single_for_device = dma_direct_sync_single,
@@ -170,6 +183,23 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
170} 183}
171EXPORT_SYMBOL(dma_set_mask); 184EXPORT_SYMBOL(dma_set_mask);
172 185
186u64 dma_get_required_mask(struct device *dev)
187{
188 struct dma_map_ops *dma_ops = get_dma_ops(dev);
189
190 if (ppc_md.dma_get_required_mask)
191 return ppc_md.dma_get_required_mask(dev);
192
193 if (unlikely(dma_ops == NULL))
194 return 0;
195
196 if (dma_ops->get_required_mask)
197 return dma_ops->get_required_mask(dev);
198
199 return DMA_BIT_MASK(8 * sizeof(dma_addr_t));
200}
201EXPORT_SYMBOL_GPL(dma_get_required_mask);
202
173static int __init dma_init(void) 203static int __init dma_init(void)
174{ 204{
175 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 205 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 29ddd8b1c274..a54d92fec612 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1133,7 +1133,7 @@ _GLOBAL(do_stab_bolted)
1133 rfid 1133 rfid
1134 b . /* prevent speculative execution */ 1134 b . /* prevent speculative execution */
1135 1135
1136#ifdef CONFIG_PPC_PSERIES 1136#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
1137/* 1137/*
1138 * Data area reserved for FWNMI option. 1138 * Data area reserved for FWNMI option.
1139 * This address (0x7000) is fixed by the RPA. 1139 * This address (0x7000) is fixed by the RPA.
@@ -1141,7 +1141,7 @@ _GLOBAL(do_stab_bolted)
1141 .= 0x7000 1141 .= 0x7000
1142 .globl fwnmi_data_area 1142 .globl fwnmi_data_area
1143fwnmi_data_area: 1143fwnmi_data_area:
1144#endif /* CONFIG_PPC_PSERIES */ 1144#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
1145 1145
1146 /* iSeries does not use the FWNMI stuff, so it is safe to put 1146 /* iSeries does not use the FWNMI stuff, so it is safe to put
1147 * this here, even if we later allow kernels that will boot on 1147 * this here, even if we later allow kernels that will boot on
@@ -1166,9 +1166,12 @@ xLparMap:
1166 1166
1167#endif /* CONFIG_PPC_ISERIES */ 1167#endif /* CONFIG_PPC_ISERIES */
1168 1168
1169#ifdef CONFIG_PPC_PSERIES 1169#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
1170 /* pseries and powernv need to keep the whole page from
1171 * 0x7000 to 0x8000 free for use by the firmware
1172 */
1170 . = 0x8000 1173 . = 0x8000
1171#endif /* CONFIG_PPC_PSERIES */ 1174#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
1172 1175
1173/* 1176/*
1174 * Space for CPU0's segment table. 1177 * Space for CPU0's segment table.
@@ -1183,3 +1186,19 @@ xLparMap:
1183 .globl initial_stab 1186 .globl initial_stab
1184initial_stab: 1187initial_stab:
1185 .space 4096 1188 .space 4096
1189#ifdef CONFIG_PPC_POWERNV
1190_GLOBAL(opal_mc_secondary_handler)
1191 HMT_MEDIUM
1192 SET_SCRATCH0(r13)
1193 GET_PACA(r13)
1194 clrldi r3,r3,2
1195 tovirt(r3,r3)
1196 std r3,PACA_OPAL_MC_EVT(r13)
1197 ld r13,OPAL_MC_SRR0(r3)
1198 mtspr SPRN_SRR0,r13
1199 ld r13,OPAL_MC_SRR1(r3)
1200 mtspr SPRN_SRR1,r13
1201 ld r3,OPAL_MC_GPR3(r3)
1202 GET_SCRATCH0(r13)
1203 b machine_check_pSeries
1204#endif /* CONFIG_PPC_POWERNV */
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index ba250d505e07..0654dba2c1f1 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -139,8 +139,7 @@ __start:
139 trap 139 trap
140#endif /* CONFIG_PPC_PMAC */ 140#endif /* CONFIG_PPC_PMAC */
141 141
1421: mr r31,r3 /* save parameters */ 1421: mr r31,r3 /* save device tree ptr */
143 mr r30,r4
144 li r24,0 /* cpu # */ 143 li r24,0 /* cpu # */
145 144
146/* 145/*
@@ -964,8 +963,8 @@ start_here:
964 * Do early platform-specific initialization, 963 * Do early platform-specific initialization,
965 * and set up the MMU. 964 * and set up the MMU.
966 */ 965 */
967 mr r3,r31 966 li r3,0
968 mr r4,r30 967 mr r4,r31
969 bl machine_init 968 bl machine_init
970 bl __save_cpu_setup 969 bl __save_cpu_setup
971 bl MMU_init 970 bl MMU_init
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index a91626d87fc9..872a6af83bad 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -58,13 +58,7 @@
58_ENTRY(_stext); 58_ENTRY(_stext);
59_ENTRY(_start); 59_ENTRY(_start);
60 60
61 /* Save parameters we are passed. 61 mr r31,r3 /* save device tree ptr */
62 */
63 mr r31,r3
64 mr r30,r4
65 mr r29,r5
66 mr r28,r6
67 mr r27,r7
68 62
69 /* We have to turn on the MMU right away so we get cache modes 63 /* We have to turn on the MMU right away so we get cache modes
70 * set correctly. 64 * set correctly.
@@ -849,11 +843,8 @@ start_here:
849/* 843/*
850 * Decide what sort of machine this is and initialize the MMU. 844 * Decide what sort of machine this is and initialize the MMU.
851 */ 845 */
852 mr r3,r31 846 li r3,0
853 mr r4,r30 847 mr r4,r31
854 mr r5,r29
855 mr r6,r28
856 mr r7,r27
857 bl machine_init 848 bl machine_init
858 bl MMU_init 849 bl MMU_init
859 850
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index f8e971ba94f5..b725dab0f88a 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -61,14 +61,7 @@ _ENTRY(_start);
61 * of abatron_pteptrs 61 * of abatron_pteptrs
62 */ 62 */
63 nop 63 nop
64/* 64 mr r31,r3 /* save device tree ptr */
65 * Save parameters we are passed
66 */
67 mr r31,r3
68 mr r30,r4
69 mr r29,r5
70 mr r28,r6
71 mr r27,r7
72 li r24,0 /* CPU number */ 65 li r24,0 /* CPU number */
73 66
74 bl init_cpu_state 67 bl init_cpu_state
@@ -120,11 +113,8 @@ _ENTRY(_start);
120/* 113/*
121 * Decide what sort of machine this is and initialize the MMU. 114 * Decide what sort of machine this is and initialize the MMU.
122 */ 115 */
123 mr r3,r31 116 li r3,0
124 mr r4,r30 117 mr r4,r31
125 mr r5,r29
126 mr r6,r28
127 mr r7,r27
128 bl machine_init 118 bl machine_init
129 bl MMU_init 119 bl MMU_init
130 120
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 3564c49c683e..06c7251c1bf7 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -51,6 +51,11 @@
51 * For pSeries or server processors: 51 * For pSeries or server processors:
52 * 1. The MMU is off & open firmware is running in real mode. 52 * 1. The MMU is off & open firmware is running in real mode.
53 * 2. The kernel is entered at __start 53 * 2. The kernel is entered at __start
54 * -or- For OPAL entry:
55 * 1. The MMU is off, processor in HV mode, primary CPU enters at 0
56 * with device-tree in gpr3. We also get OPAL base in r8 and
57 * entry in r9 for debugging purposes
58 * 2. Secondary processors enter at 0x60 with PIR in gpr3
54 * 59 *
55 * For iSeries: 60 * For iSeries:
56 * 1. The MMU is on (as it always is for iSeries) 61 * 1. The MMU is on (as it always is for iSeries)
@@ -331,6 +336,11 @@ _GLOBAL(__start_initialization_multiplatform)
331 /* Save parameters */ 336 /* Save parameters */
332 mr r31,r3 337 mr r31,r3
333 mr r30,r4 338 mr r30,r4
339#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
340 /* Save OPAL entry */
341 mr r28,r8
342 mr r29,r9
343#endif
334 344
335#ifdef CONFIG_PPC_BOOK3E 345#ifdef CONFIG_PPC_BOOK3E
336 bl .start_initialization_book3e 346 bl .start_initialization_book3e
@@ -674,9 +684,9 @@ _GLOBAL(enable_64b_mode)
674_GLOBAL(relative_toc) 684_GLOBAL(relative_toc)
675 mflr r0 685 mflr r0
676 bcl 20,31,$+4 686 bcl 20,31,$+4
6770: mflr r9 6870: mflr r11
678 ld r2,(p_toc - 0b)(r9) 688 ld r2,(p_toc - 0b)(r11)
679 add r2,r2,r9 689 add r2,r2,r11
680 mtlr r0 690 mtlr r0
681 blr 691 blr
682 692
@@ -707,6 +717,12 @@ _INIT_STATIC(start_here_multiplatform)
707 bdnz 3b 717 bdnz 3b
7084: 7184:
709 719
720#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
721 /* Setup OPAL entry */
722 std r28,0(r11);
723 std r29,8(r11);
724#endif
725
710#ifndef CONFIG_PPC_BOOK3E 726#ifndef CONFIG_PPC_BOOK3E
711 mfmsr r6 727 mfmsr r6
712 ori r6,r6,MSR_RI 728 ori r6,r6,MSR_RI
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 1cbf64e6b416..b68cb173ba2c 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -76,11 +76,7 @@ _ENTRY(_start);
76 */ 76 */
77 .globl __start 77 .globl __start
78__start: 78__start:
79 mr r31,r3 /* save parameters */ 79 mr r31,r3 /* save device tree ptr */
80 mr r30,r4
81 mr r29,r5
82 mr r28,r6
83 mr r27,r7
84 80
85 /* We have to turn on the MMU right away so we get cache modes 81 /* We have to turn on the MMU right away so we get cache modes
86 * set correctly. 82 * set correctly.
@@ -723,11 +719,8 @@ start_here:
723/* 719/*
724 * Decide what sort of machine this is and initialize the MMU. 720 * Decide what sort of machine this is and initialize the MMU.
725 */ 721 */
726 mr r3,r31 722 li r3,0
727 mr r4,r30 723 mr r4,r31
728 mr r5,r29
729 mr r6,r28
730 mr r7,r27
731 bl machine_init 724 bl machine_init
732 bl MMU_init 725 bl MMU_init
733 726
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 50845924b7d9..9f5d210ddf3f 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -63,17 +63,30 @@ _ENTRY(_start);
63 * of abatron_pteptrs 63 * of abatron_pteptrs
64 */ 64 */
65 nop 65 nop
66/* 66
67 * Save parameters we are passed 67 /* Translate device tree address to physical, save in r30/r31 */
68 */ 68 mfmsr r16
69 mr r31,r3 69 mfspr r17,SPRN_PID
70 mr r30,r4 70 rlwinm r17,r17,16,0x3fff0000 /* turn PID into MAS6[SPID] */
71 mr r29,r5 71 rlwimi r17,r16,28,0x00000001 /* turn MSR[DS] into MAS6[SAS] */
72 mr r28,r6 72 mtspr SPRN_MAS6,r17
73 mr r27,r7 73
74 li r25,0 /* phys kernel start (low) */ 74 tlbsx 0,r3 /* must succeed */
75 li r24,0 /* CPU number */ 75
76 li r23,0 /* phys kernel start (high) */ 76 mfspr r16,SPRN_MAS1
77 mfspr r20,SPRN_MAS3
78 rlwinm r17,r16,25,0x1f /* r17 = log2(page size) */
79 li r18,1024
80 slw r18,r18,r17 /* r18 = page size */
81 addi r18,r18,-1
82 and r19,r3,r18 /* r19 = page offset */
83 andc r31,r20,r18 /* r31 = page base */
84 or r31,r31,r19 /* r31 = devtree phys addr */
85 mfspr r30,SPRN_MAS7
86
87 li r25,0 /* phys kernel start (low) */
88 li r24,0 /* CPU number */
89 li r23,0 /* phys kernel start (high) */
77 90
78/* We try to not make any assumptions about how the boot loader 91/* We try to not make any assumptions about how the boot loader
79 * setup or used the TLBs. We invalidate all mappings from the 92 * setup or used the TLBs. We invalidate all mappings from the
@@ -198,11 +211,8 @@ _ENTRY(__early_start)
198/* 211/*
199 * Decide what sort of machine this is and initialize the MMU. 212 * Decide what sort of machine this is and initialize the MMU.
200 */ 213 */
201 mr r3,r31 214 mr r3,r30
202 mr r4,r30 215 mr r4,r31
203 mr r5,r29
204 mr r6,r28
205 mr r7,r27
206 bl machine_init 216 bl machine_init
207 bl MMU_init 217 bl MMU_init
208 218
@@ -236,8 +246,24 @@ _ENTRY(__early_start)
236 * if we find the pte (fall through): 246 * if we find the pte (fall through):
237 * r11 is low pte word 247 * r11 is low pte word
238 * r12 is pointer to the pte 248 * r12 is pointer to the pte
249 * r10 is the pshift from the PGD, if we're a hugepage
239 */ 250 */
240#ifdef CONFIG_PTE_64BIT 251#ifdef CONFIG_PTE_64BIT
252#ifdef CONFIG_HUGETLB_PAGE
253#define FIND_PTE \
254 rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
255 lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
256 rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
257 blt 1000f; /* Normal non-huge page */ \
258 beq 2f; /* Bail if no table */ \
259 oris r11, r11, PD_HUGE@h; /* Put back address bit */ \
260 andi. r10, r11, HUGEPD_SHIFT_MASK@l; /* extract size field */ \
261 xor r12, r10, r11; /* drop size bits from pointer */ \
262 b 1001f; \
2631000: rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
264 li r10, 0; /* clear r10 */ \
2651001: lwz r11, 4(r12); /* Get pte entry */
266#else
241#define FIND_PTE \ 267#define FIND_PTE \
242 rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ 268 rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
243 lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ 269 lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
@@ -245,7 +271,8 @@ _ENTRY(__early_start)
245 beq 2f; /* Bail if no table */ \ 271 beq 2f; /* Bail if no table */ \
246 rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ 272 rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
247 lwz r11, 4(r12); /* Get pte entry */ 273 lwz r11, 4(r12); /* Get pte entry */
248#else 274#endif /* HUGEPAGE */
275#else /* !PTE_64BIT */
249#define FIND_PTE \ 276#define FIND_PTE \
250 rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ 277 rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
251 lwz r11, 0(r11); /* Get L1 entry */ \ 278 lwz r11, 0(r11); /* Get L1 entry */ \
@@ -402,8 +429,8 @@ interrupt_base:
402 429
403#ifdef CONFIG_PTE_64BIT 430#ifdef CONFIG_PTE_64BIT
404#ifdef CONFIG_SMP 431#ifdef CONFIG_SMP
405 subf r10,r11,r12 /* create false data dep */ 432 subf r13,r11,r12 /* create false data dep */
406 lwzx r13,r11,r10 /* Get upper pte bits */ 433 lwzx r13,r11,r13 /* Get upper pte bits */
407#else 434#else
408 lwz r13,0(r12) /* Get upper pte bits */ 435 lwz r13,0(r12) /* Get upper pte bits */
409#endif 436#endif
@@ -483,8 +510,8 @@ interrupt_base:
483 510
484#ifdef CONFIG_PTE_64BIT 511#ifdef CONFIG_PTE_64BIT
485#ifdef CONFIG_SMP 512#ifdef CONFIG_SMP
486 subf r10,r11,r12 /* create false data dep */ 513 subf r13,r11,r12 /* create false data dep */
487 lwzx r13,r11,r10 /* Get upper pte bits */ 514 lwzx r13,r11,r13 /* Get upper pte bits */
488#else 515#else
489 lwz r13,0(r12) /* Get upper pte bits */ 516 lwz r13,0(r12) /* Get upper pte bits */
490#endif 517#endif
@@ -548,7 +575,7 @@ interrupt_base:
548/* 575/*
549 * Both the instruction and data TLB miss get to this 576 * Both the instruction and data TLB miss get to this
550 * point to load the TLB. 577 * point to load the TLB.
551 * r10 - available to use 578 * r10 - tsize encoding (if HUGETLB_PAGE) or available to use
552 * r11 - TLB (info from Linux PTE) 579 * r11 - TLB (info from Linux PTE)
553 * r12 - available to use 580 * r12 - available to use
554 * r13 - upper bits of PTE (if PTE_64BIT) or available to use 581 * r13 - upper bits of PTE (if PTE_64BIT) or available to use
@@ -558,21 +585,73 @@ interrupt_base:
558 * Upon exit, we reload everything and RFI. 585 * Upon exit, we reload everything and RFI.
559 */ 586 */
560finish_tlb_load: 587finish_tlb_load:
588#ifdef CONFIG_HUGETLB_PAGE
589 cmpwi 6, r10, 0 /* check for huge page */
590 beq 6, finish_tlb_load_cont /* !huge */
591
592 /* Alas, we need more scratch registers for hugepages */
593 mfspr r12, SPRN_SPRG_THREAD
594 stw r14, THREAD_NORMSAVE(4)(r12)
595 stw r15, THREAD_NORMSAVE(5)(r12)
596 stw r16, THREAD_NORMSAVE(6)(r12)
597 stw r17, THREAD_NORMSAVE(7)(r12)
598
599 /* Get the next_tlbcam_idx percpu var */
600#ifdef CONFIG_SMP
601 lwz r12, THREAD_INFO-THREAD(r12)
602 lwz r15, TI_CPU(r12)
603 lis r14, __per_cpu_offset@h
604 ori r14, r14, __per_cpu_offset@l
605 rlwinm r15, r15, 2, 0, 29
606 lwzx r16, r14, r15
607#else
608 li r16, 0
609#endif
610 lis r17, next_tlbcam_idx@h
611 ori r17, r17, next_tlbcam_idx@l
612 add r17, r17, r16 /* r17 = *next_tlbcam_idx */
613 lwz r15, 0(r17) /* r15 = next_tlbcam_idx */
614
615 lis r14, MAS0_TLBSEL(1)@h /* select TLB1 (TLBCAM) */
616 rlwimi r14, r15, 16, 4, 15 /* next_tlbcam_idx entry */
617 mtspr SPRN_MAS0, r14
618
619 /* Extract TLB1CFG(NENTRY) */
620 mfspr r16, SPRN_TLB1CFG
621 andi. r16, r16, 0xfff
622
623 /* Update next_tlbcam_idx, wrapping when necessary */
624 addi r15, r15, 1
625 cmpw r15, r16
626 blt 100f
627 lis r14, tlbcam_index@h
628 ori r14, r14, tlbcam_index@l
629 lwz r15, 0(r14)
630100: stw r15, 0(r17)
631
632 /*
633 * Calc MAS1_TSIZE from r10 (which has pshift encoded)
634 * tlb_enc = (pshift - 10).
635 */
636 subi r15, r10, 10
637 mfspr r16, SPRN_MAS1
638 rlwimi r16, r15, 7, 20, 24
639 mtspr SPRN_MAS1, r16
640
641 /* copy the pshift for use later */
642 mr r14, r10
643
644 /* fall through */
645
646#endif /* CONFIG_HUGETLB_PAGE */
647
561 /* 648 /*
562 * We set execute, because we don't have the granularity to 649 * We set execute, because we don't have the granularity to
563 * properly set this at the page level (Linux problem). 650 * properly set this at the page level (Linux problem).
564 * Many of these bits are software only. Bits we don't set 651 * Many of these bits are software only. Bits we don't set
565 * here we (properly should) assume have the appropriate value. 652 * here we (properly should) assume have the appropriate value.
566 */ 653 */
567 654finish_tlb_load_cont:
568 mfspr r12, SPRN_MAS2
569#ifdef CONFIG_PTE_64BIT
570 rlwimi r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */
571#else
572 rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
573#endif
574 mtspr SPRN_MAS2, r12
575
576#ifdef CONFIG_PTE_64BIT 655#ifdef CONFIG_PTE_64BIT
577 rlwinm r12, r11, 32-2, 26, 31 /* Move in perm bits */ 656 rlwinm r12, r11, 32-2, 26, 31 /* Move in perm bits */
578 andi. r10, r11, _PAGE_DIRTY 657 andi. r10, r11, _PAGE_DIRTY
@@ -581,22 +660,40 @@ finish_tlb_load:
581 andc r12, r12, r10 660 andc r12, r12, r10
5821: rlwimi r12, r13, 20, 0, 11 /* grab RPN[32:43] */ 6611: rlwimi r12, r13, 20, 0, 11 /* grab RPN[32:43] */
583 rlwimi r12, r11, 20, 12, 19 /* grab RPN[44:51] */ 662 rlwimi r12, r11, 20, 12, 19 /* grab RPN[44:51] */
584 mtspr SPRN_MAS3, r12 6632: mtspr SPRN_MAS3, r12
585BEGIN_MMU_FTR_SECTION 664BEGIN_MMU_FTR_SECTION
586 srwi r10, r13, 12 /* grab RPN[12:31] */ 665 srwi r10, r13, 12 /* grab RPN[12:31] */
587 mtspr SPRN_MAS7, r10 666 mtspr SPRN_MAS7, r10
588END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) 667END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
589#else 668#else
590 li r10, (_PAGE_EXEC | _PAGE_PRESENT) 669 li r10, (_PAGE_EXEC | _PAGE_PRESENT)
670 mr r13, r11
591 rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */ 671 rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */
592 and r12, r11, r10 672 and r12, r11, r10
593 andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */ 673 andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
594 slwi r10, r12, 1 674 slwi r10, r12, 1
595 or r10, r10, r12 675 or r10, r10, r12
596 iseleq r12, r12, r10 676 iseleq r12, r12, r10
597 rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ 677 rlwimi r13, r12, 0, 20, 31 /* Get RPN from PTE, merge w/ perms */
598 mtspr SPRN_MAS3, r11 678 mtspr SPRN_MAS3, r13
599#endif 679#endif
680
681 mfspr r12, SPRN_MAS2
682#ifdef CONFIG_PTE_64BIT
683 rlwimi r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */
684#else
685 rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
686#endif
687#ifdef CONFIG_HUGETLB_PAGE
688 beq 6, 3f /* don't mask if page isn't huge */
689 li r13, 1
690 slw r13, r13, r14
691 subi r13, r13, 1
692 rlwinm r13, r13, 0, 0, 19 /* bottom bits used for WIMGE/etc */
693 andc r12, r12, r13 /* mask off ea bits within the page */
694#endif
6953: mtspr SPRN_MAS2, r12
696
600#ifdef CONFIG_E200 697#ifdef CONFIG_E200
601 /* Round robin TLB1 entries assignment */ 698 /* Round robin TLB1 entries assignment */
602 mfspr r12, SPRN_MAS0 699 mfspr r12, SPRN_MAS0
@@ -622,11 +719,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
622 mtspr SPRN_MAS0,r12 719 mtspr SPRN_MAS0,r12
623#endif /* CONFIG_E200 */ 720#endif /* CONFIG_E200 */
624 721
722tlb_write_entry:
625 tlbwe 723 tlbwe
626 724
627 /* Done...restore registers and get out of here. */ 725 /* Done...restore registers and get out of here. */
628 mfspr r10, SPRN_SPRG_THREAD 726 mfspr r10, SPRN_SPRG_THREAD
629 lwz r11, THREAD_NORMSAVE(3)(r10) 727#ifdef CONFIG_HUGETLB_PAGE
728 beq 6, 8f /* skip restore for 4k page faults */
729 lwz r14, THREAD_NORMSAVE(4)(r10)
730 lwz r15, THREAD_NORMSAVE(5)(r10)
731 lwz r16, THREAD_NORMSAVE(6)(r10)
732 lwz r17, THREAD_NORMSAVE(7)(r10)
733#endif
7348: lwz r11, THREAD_NORMSAVE(3)(r10)
630 mtcr r11 735 mtcr r11
631 lwz r13, THREAD_NORMSAVE(2)(r10) 736 lwz r13, THREAD_NORMSAVE(2)(r10)
632 lwz r12, THREAD_NORMSAVE(1)(r10) 737 lwz r12, THREAD_NORMSAVE(1)(r10)
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 28581f1ad2c0..73110fb6bb6c 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -125,17 +125,23 @@ static void ibmebus_unmap_sg(struct device *dev,
125 125
126static int ibmebus_dma_supported(struct device *dev, u64 mask) 126static int ibmebus_dma_supported(struct device *dev, u64 mask)
127{ 127{
128 return 1; 128 return mask == DMA_BIT_MASK(64);
129}
130
131static u64 ibmebus_dma_get_required_mask(struct device *dev)
132{
133 return DMA_BIT_MASK(64);
129} 134}
130 135
131static struct dma_map_ops ibmebus_dma_ops = { 136static struct dma_map_ops ibmebus_dma_ops = {
132 .alloc_coherent = ibmebus_alloc_coherent, 137 .alloc_coherent = ibmebus_alloc_coherent,
133 .free_coherent = ibmebus_free_coherent, 138 .free_coherent = ibmebus_free_coherent,
134 .map_sg = ibmebus_map_sg, 139 .map_sg = ibmebus_map_sg,
135 .unmap_sg = ibmebus_unmap_sg, 140 .unmap_sg = ibmebus_unmap_sg,
136 .dma_supported = ibmebus_dma_supported, 141 .dma_supported = ibmebus_dma_supported,
137 .map_page = ibmebus_map_page, 142 .get_required_mask = ibmebus_dma_get_required_mask,
138 .unmap_page = ibmebus_unmap_page, 143 .map_page = ibmebus_map_page,
144 .unmap_page = ibmebus_unmap_page,
139}; 145};
140 146
141static int ibmebus_match_path(struct device *dev, void *data) 147static int ibmebus_match_path(struct device *dev, void *data)
diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S
index 3e2b95c6ae67..4f0ab85f3788 100644
--- a/arch/powerpc/kernel/idle_e500.S
+++ b/arch/powerpc/kernel/idle_e500.S
@@ -26,7 +26,7 @@ _GLOBAL(e500_idle)
26 ori r4,r4,_TLF_NAPPING /* so when we take an exception */ 26 ori r4,r4,_TLF_NAPPING /* so when we take an exception */
27 stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */ 27 stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */
28 28
29#ifdef CONFIG_E500MC 29#ifdef CONFIG_PPC_E500MC
30 wrteei 1 30 wrteei 1
311: wait 311: wait
32 32
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 961bb03413f3..0cfcf98aafca 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -501,6 +501,14 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
501 tbl->it_map = page_address(page); 501 tbl->it_map = page_address(page);
502 memset(tbl->it_map, 0, sz); 502 memset(tbl->it_map, 0, sz);
503 503
504 /*
505 * Reserve page 0 so it will not be used for any mappings.
506 * This avoids buggy drivers that consider page 0 to be invalid
507 * to crash the machine or even lose data.
508 */
509 if (tbl->it_offset == 0)
510 set_bit(0, tbl->it_map);
511
504 tbl->it_hint = 0; 512 tbl->it_hint = 0;
505 tbl->it_largehint = tbl->it_halfpoint; 513 tbl->it_largehint = tbl->it_halfpoint;
506 spin_lock_init(&tbl->it_lock); 514 spin_lock_init(&tbl->it_lock);
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 2b97b80d6d7d..c7b5afeecaf2 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -6,6 +6,7 @@
6#include <linux/pci.h> 6#include <linux/pci.h>
7#include <linux/of_address.h> 7#include <linux/of_address.h>
8#include <linux/of_device.h> 8#include <linux/of_device.h>
9#include <linux/serial_reg.h>
9#include <asm/io.h> 10#include <asm/io.h>
10#include <asm/mmu.h> 11#include <asm/mmu.h>
11#include <asm/prom.h> 12#include <asm/prom.h>
@@ -47,6 +48,24 @@ static struct __initdata of_device_id legacy_serial_parents[] = {
47static unsigned int legacy_serial_count; 48static unsigned int legacy_serial_count;
48static int legacy_serial_console = -1; 49static int legacy_serial_console = -1;
49 50
51static unsigned int tsi_serial_in(struct uart_port *p, int offset)
52{
53 unsigned int tmp;
54 offset = offset << p->regshift;
55 if (offset == UART_IIR) {
56 tmp = readl(p->membase + (UART_IIR & ~3));
57 return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
58 } else
59 return readb(p->membase + offset);
60}
61
62static void tsi_serial_out(struct uart_port *p, int offset, int value)
63{
64 offset = offset << p->regshift;
65 if (!((offset == UART_IER) && (value & UART_IER_UUE)))
66 writeb(value, p->membase + offset);
67}
68
50static int __init add_legacy_port(struct device_node *np, int want_index, 69static int __init add_legacy_port(struct device_node *np, int want_index,
51 int iotype, phys_addr_t base, 70 int iotype, phys_addr_t base,
52 phys_addr_t taddr, unsigned long irq, 71 phys_addr_t taddr, unsigned long irq,
@@ -102,6 +121,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
102 legacy_serial_ports[index].iobase = base; 121 legacy_serial_ports[index].iobase = base;
103 else 122 else
104 legacy_serial_ports[index].mapbase = base; 123 legacy_serial_ports[index].mapbase = base;
124
105 legacy_serial_ports[index].iotype = iotype; 125 legacy_serial_ports[index].iotype = iotype;
106 legacy_serial_ports[index].uartclk = clock; 126 legacy_serial_ports[index].uartclk = clock;
107 legacy_serial_ports[index].irq = irq; 127 legacy_serial_ports[index].irq = irq;
@@ -112,6 +132,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
112 legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0; 132 legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0;
113 legacy_serial_infos[index].irq_check_parent = irq_check_parent; 133 legacy_serial_infos[index].irq_check_parent = irq_check_parent;
114 134
135 if (iotype == UPIO_TSI) {
136 legacy_serial_ports[index].serial_in = tsi_serial_in;
137 legacy_serial_ports[index].serial_out = tsi_serial_out;
138 }
139
115 printk(KERN_DEBUG "Found legacy serial port %d for %s\n", 140 printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
116 index, np->full_name); 141 index, np->full_name);
117 printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", 142 printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 583af70c4b14..26ccbf77dd41 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -74,8 +74,7 @@ int default_machine_kexec_prepare(struct kimage *image)
74 } 74 }
75 75
76 /* We also should not overwrite the tce tables */ 76 /* We also should not overwrite the tce tables */
77 for (node = of_find_node_by_type(NULL, "pci"); node != NULL; 77 for_each_node_by_type(node, "pci") {
78 node = of_find_node_by_type(node, "pci")) {
79 basep = of_get_property(node, "linux,tce-base", NULL); 78 basep = of_get_property(node, "linux,tce-base", NULL);
80 sizep = of_get_property(node, "linux,tce-size", NULL); 79 sizep = of_get_property(node, "linux,tce-size", NULL);
81 if (basep == NULL || sizep == NULL) 80 if (basep == NULL || sizep == NULL)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 998a10028608..f7d760ab5ca1 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -8,6 +8,8 @@
8 * kexec bits: 8 * kexec bits:
9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> 9 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz 10 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
11 * PPC44x port. Copyright (C) 2011, IBM Corporation
12 * Author: Suzuki Poulose <suzuki@in.ibm.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -736,6 +738,175 @@ relocate_new_kernel:
736 mr r5, r31 738 mr r5, r31
737 739
738 li r0, 0 740 li r0, 0
741#elif defined(CONFIG_44x) && !defined(CONFIG_47x)
742
743/*
744 * Code for setting up 1:1 mapping for PPC440x for KEXEC
745 *
746 * We cannot switch off the MMU on PPC44x.
747 * So we:
748 * 1) Invalidate all the mappings except the one we are running from.
749 * 2) Create a tmp mapping for our code in the other address space(TS) and
750 * jump to it. Invalidate the entry we started in.
751 * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS.
752 * 4) Jump to the 1:1 mapping in original TS.
753 * 5) Invalidate the tmp mapping.
754 *
755 * - Based on the kexec support code for FSL BookE
756 * - Doesn't support 47x yet.
757 *
758 */
759 /* Save our parameters */
760 mr r29, r3
761 mr r30, r4
762 mr r31, r5
763
764 /* Load our MSR_IS and TID to MMUCR for TLB search */
765 mfspr r3,SPRN_PID
766 mfmsr r4
767 andi. r4,r4,MSR_IS@l
768 beq wmmucr
769 oris r3,r3,PPC44x_MMUCR_STS@h
770wmmucr:
771 mtspr SPRN_MMUCR,r3
772 sync
773
774 /*
775 * Invalidate all the TLB entries except the current entry
776 * where we are running from
777 */
778 bl 0f /* Find our address */
7790: mflr r5 /* Make it accessible */
780 tlbsx r23,0,r5 /* Find entry we are in */
781 li r4,0 /* Start at TLB entry 0 */
782 li r3,0 /* Set PAGEID inval value */
7831: cmpw r23,r4 /* Is this our entry? */
784 beq skip /* If so, skip the inval */
785 tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
786skip:
787 addi r4,r4,1 /* Increment */
788 cmpwi r4,64 /* Are we done? */
789 bne 1b /* If not, repeat */
790 isync
791
792 /* Create a temp mapping and jump to it */
793 andi. r6, r23, 1 /* Find the index to use */
794 addi r24, r6, 1 /* r24 will contain 1 or 2 */
795
796 mfmsr r9 /* get the MSR */
797 rlwinm r5, r9, 27, 31, 31 /* Extract the MSR[IS] */
798 xori r7, r5, 1 /* Use the other address space */
799
800 /* Read the current mapping entries */
801 tlbre r3, r23, PPC44x_TLB_PAGEID
802 tlbre r4, r23, PPC44x_TLB_XLAT
803 tlbre r5, r23, PPC44x_TLB_ATTRIB
804
805 /* Save our current XLAT entry */
806 mr r25, r4
807
808 /* Extract the TLB PageSize */
809 li r10, 1 /* r10 will hold PageSize */
810 rlwinm r11, r3, 0, 24, 27 /* bits 24-27 */
811
812 /* XXX: As of now we use 256M, 4K pages */
813 cmpwi r11, PPC44x_TLB_256M
814 bne tlb_4k
815 rotlwi r10, r10, 28 /* r10 = 256M */
816 b write_out
817tlb_4k:
818 cmpwi r11, PPC44x_TLB_4K
819 bne default
820 rotlwi r10, r10, 12 /* r10 = 4K */
821 b write_out
822default:
823 rotlwi r10, r10, 10 /* r10 = 1K */
824
825write_out:
826 /*
827 * Write out the tmp 1:1 mapping for this code in other address space
828 * Fixup EPN = RPN , TS=other address space
829 */
830 insrwi r3, r7, 1, 23 /* Bit 23 is TS for PAGEID field */
831
832 /* Write out the tmp mapping entries */
833 tlbwe r3, r24, PPC44x_TLB_PAGEID
834 tlbwe r4, r24, PPC44x_TLB_XLAT
835 tlbwe r5, r24, PPC44x_TLB_ATTRIB
836
837 subi r11, r10, 1 /* PageOffset Mask = PageSize - 1 */
838 not r10, r11 /* Mask for PageNum */
839
840 /* Switch to other address space in MSR */
841 insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */
842
843 bl 1f
8441: mflr r8
845 addi r8, r8, (2f-1b) /* Find the target offset */
846
847 /* Jump to the tmp mapping */
848 mtspr SPRN_SRR0, r8
849 mtspr SPRN_SRR1, r9
850 rfi
851
8522:
853 /* Invalidate the entry we were executing from */
854 li r3, 0
855 tlbwe r3, r23, PPC44x_TLB_PAGEID
856
857 /* attribute fields. rwx for SUPERVISOR mode */
858 li r5, 0
859 ori r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
860
861 /* Create 1:1 mapping in 256M pages */
862 xori r7, r7, 1 /* Revert back to Original TS */
863
864 li r8, 0 /* PageNumber */
865 li r6, 3 /* TLB Index, start at 3 */
866
867next_tlb:
868 rotlwi r3, r8, 28 /* Create EPN (bits 0-3) */
869 mr r4, r3 /* RPN = EPN */
870 ori r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */
871 insrwi r3, r7, 1, 23 /* Set TS from r7 */
872
873 tlbwe r3, r6, PPC44x_TLB_PAGEID /* PageID field : EPN, V, SIZE */
874 tlbwe r4, r6, PPC44x_TLB_XLAT /* Address translation : RPN */
875 tlbwe r5, r6, PPC44x_TLB_ATTRIB /* Attributes */
876
877 addi r8, r8, 1 /* Increment PN */
878 addi r6, r6, 1 /* Increment TLB Index */
879 cmpwi r8, 8 /* Are we done ? */
880 bne next_tlb
881 isync
882
883 /* Jump to the new mapping 1:1 */
884 li r9,0
885 insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */
886
887 bl 1f
8881: mflr r8
889 and r8, r8, r11 /* Get our offset within page */
890 addi r8, r8, (2f-1b)
891
892 and r5, r25, r10 /* Get our target PageNum */
893 or r8, r8, r5 /* Target jump address */
894
895 mtspr SPRN_SRR0, r8
896 mtspr SPRN_SRR1, r9
897 rfi
8982:
899 /* Invalidate the tmp entry we used */
900 li r3, 0
901 tlbwe r3, r24, PPC44x_TLB_PAGEID
902 sync
903
904 /* Restore the parameters */
905 mr r3, r29
906 mr r4, r30
907 mr r5, r31
908
909 li r0, 0
739#else 910#else
740 li r0, 0 911 li r0, 0
741 912
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 32656f105250..677ecccbe10d 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1730,6 +1730,17 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
1730 1730
1731 if (mode == PCI_PROBE_NORMAL) 1731 if (mode == PCI_PROBE_NORMAL)
1732 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 1732 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
1733
1734 /* Configure PCI Express settings */
1735 if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
1736 struct pci_bus *child;
1737 list_for_each_entry(child, &bus->children, node) {
1738 struct pci_dev *self = child->self;
1739 if (!self)
1740 continue;
1741 pcie_bus_configure_settings(child, self->pcie_mpss);
1742 }
1743 }
1733} 1744}
1734 1745
1735static void fixup_hide_host_resource_fsl(struct pci_dev *dev) 1746static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index 03b95e2c6d65..0bbc901e7efc 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -487,8 +487,8 @@ static int power6_generic_events[] = {
487 */ 487 */
488static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { 488static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
489 [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ 489 [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
490 [C(OP_READ)] = { 0x80082, 0x80080 }, 490 [C(OP_READ)] = { 0x280030, 0x80080 },
491 [C(OP_WRITE)] = { 0x80086, 0x80088 }, 491 [C(OP_WRITE)] = { 0x180032, 0x80088 },
492 [C(OP_PREFETCH)] = { 0x810a4, 0 }, 492 [C(OP_PREFETCH)] = { 0x810a4, 0 },
493 }, 493 },
494 [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */ 494 [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index de83d6060dda..1251e4d7e262 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -297,6 +297,8 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[])
297 297
298static int power7_generic_events[] = { 298static int power7_generic_events[] = {
299 [PERF_COUNT_HW_CPU_CYCLES] = 0x1e, 299 [PERF_COUNT_HW_CPU_CYCLES] = 0x1e,
300 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x100f8, /* GCT_NOSLOT_CYC */
301 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x4000a, /* CMPLU_STALL */
300 [PERF_COUNT_HW_INSTRUCTIONS] = 2, 302 [PERF_COUNT_HW_INSTRUCTIONS] = 2,
301 [PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880, /* LD_REF_L1_LSU*/ 303 [PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880, /* LD_REF_L1_LSU*/
302 [PERF_COUNT_HW_CACHE_MISSES] = 0x400f0, /* LD_MISS_L1 */ 304 [PERF_COUNT_HW_CACHE_MISSES] = 0x400f0, /* LD_MISS_L1 */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 174e1e96175e..8ad825c063c4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -54,6 +54,8 @@
54#include <asm/pci-bridge.h> 54#include <asm/pci-bridge.h>
55#include <asm/phyp_dump.h> 55#include <asm/phyp_dump.h>
56#include <asm/kexec.h> 56#include <asm/kexec.h>
57#include <asm/opal.h>
58
57#include <mm/mmu_decl.h> 59#include <mm/mmu_decl.h>
58 60
59#ifdef DEBUG 61#ifdef DEBUG
@@ -707,11 +709,23 @@ void __init early_init_devtree(void *params)
707 of_scan_flat_dt(early_init_dt_scan_rtas, NULL); 709 of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
708#endif 710#endif
709 711
712#ifdef CONFIG_PPC_POWERNV
713 /* Some machines might need OPAL info for debugging, grab it now. */
714 of_scan_flat_dt(early_init_dt_scan_opal, NULL);
715#endif
716
710#ifdef CONFIG_PHYP_DUMP 717#ifdef CONFIG_PHYP_DUMP
711 /* scan tree to see if dump occurred during last boot */ 718 /* scan tree to see if dump occurred during last boot */
712 of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); 719 of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
713#endif 720#endif
714 721
722 /* Pre-initialize the cmd_line with the content of boot_commmand_line,
723 * which will be empty except when the content of the variable has
724 * been overriden by a bootloading mechanism. This happens typically
725 * with HAL takeover
726 */
727 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
728
715 /* Retrieve various informations from the /chosen node of the 729 /* Retrieve various informations from the /chosen node of the
716 * device-tree, including the platform type, initrd location and 730 * device-tree, including the platform type, initrd location and
717 * size, TCE reserve, and more ... 731 * size, TCE reserve, and more ...
@@ -723,12 +737,15 @@ void __init early_init_devtree(void *params)
723 737
724 of_scan_flat_dt(early_init_dt_scan_root, NULL); 738 of_scan_flat_dt(early_init_dt_scan_root, NULL);
725 of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); 739 of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
726 setup_initial_memory_limit(memstart_addr, first_memblock_size);
727 740
728 /* Save command line for /proc/cmdline and then parse parameters */ 741 /* Save command line for /proc/cmdline and then parse parameters */
729 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); 742 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
730 parse_early_param(); 743 parse_early_param();
731 744
745 /* make sure we've parsed cmdline for mem= before this */
746 if (memory_limit)
747 first_memblock_size = min(first_memblock_size, memory_limit);
748 setup_initial_memory_limit(memstart_addr, first_memblock_size);
732 /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */ 749 /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
733 memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); 750 memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
734 /* If relocatable, reserve first 32k for interrupt vectors etc. */ 751 /* If relocatable, reserve first 32k for interrupt vectors etc. */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index a909f4e9343b..b4fa66127495 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -43,6 +43,7 @@
43#include <asm/btext.h> 43#include <asm/btext.h>
44#include <asm/sections.h> 44#include <asm/sections.h>
45#include <asm/machdep.h> 45#include <asm/machdep.h>
46#include <asm/opal.h>
46 47
47#include <linux/linux_logo.h> 48#include <linux/linux_logo.h>
48 49
@@ -139,7 +140,9 @@ struct mem_map_entry {
139 140
140typedef u32 cell_t; 141typedef u32 cell_t;
141 142
142extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); 143extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
144 unsigned long r6, unsigned long r7, unsigned long r8,
145 unsigned long r9);
143 146
144#ifdef CONFIG_PPC64 147#ifdef CONFIG_PPC64
145extern int enter_prom(struct prom_args *args, unsigned long entry); 148extern int enter_prom(struct prom_args *args, unsigned long entry);
@@ -185,6 +188,7 @@ static unsigned long __initdata prom_tce_alloc_end;
185#define PLATFORM_LPAR 0x0001 188#define PLATFORM_LPAR 0x0001
186#define PLATFORM_POWERMAC 0x0400 189#define PLATFORM_POWERMAC 0x0400
187#define PLATFORM_GENERIC 0x0500 190#define PLATFORM_GENERIC 0x0500
191#define PLATFORM_OPAL 0x0600
188 192
189static int __initdata of_platform; 193static int __initdata of_platform;
190 194
@@ -644,7 +648,7 @@ static void __init early_cmdline_parse(void)
644 } 648 }
645} 649}
646 650
647#ifdef CONFIG_PPC_PSERIES 651#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
648/* 652/*
649 * There are two methods for telling firmware what our capabilities are. 653 * There are two methods for telling firmware what our capabilities are.
650 * Newer machines have an "ibm,client-architecture-support" method on the 654 * Newer machines have an "ibm,client-architecture-support" method on the
@@ -1274,6 +1278,284 @@ static void __init prom_init_mem(void)
1274 prom_printf(" ram_top : %x\n", RELOC(ram_top)); 1278 prom_printf(" ram_top : %x\n", RELOC(ram_top));
1275} 1279}
1276 1280
1281static void __init prom_close_stdin(void)
1282{
1283 struct prom_t *_prom = &RELOC(prom);
1284 ihandle val;
1285
1286 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1287 call_prom("close", 1, 0, val);
1288}
1289
1290#ifdef CONFIG_PPC_POWERNV
1291
1292static u64 __initdata prom_opal_size;
1293static u64 __initdata prom_opal_align;
1294static int __initdata prom_rtas_start_cpu;
1295static u64 __initdata prom_rtas_data;
1296static u64 __initdata prom_rtas_entry;
1297
1298#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1299static u64 __initdata prom_opal_base;
1300static u64 __initdata prom_opal_entry;
1301#endif
1302
1303/* XXX Don't change this structure without updating opal-takeover.S */
1304static struct opal_secondary_data {
1305 s64 ack; /* 0 */
1306 u64 go; /* 8 */
1307 struct opal_takeover_args args; /* 16 */
1308} opal_secondary_data;
1309
1310extern char opal_secondary_entry;
1311
1312static void prom_query_opal(void)
1313{
1314 long rc;
1315
1316 /* We must not query for OPAL presence on a machine that
1317 * supports TNK takeover (970 blades), as this uses the same
1318 * h-call with different arguments and will crash
1319 */
1320 if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
1321 ADDR("/tnk-memory-map")))) {
1322 prom_printf("TNK takeover detected, skipping OPAL check\n");
1323 return;
1324 }
1325
1326 prom_printf("Querying for OPAL presence... ");
1327 rc = opal_query_takeover(&RELOC(prom_opal_size),
1328 &RELOC(prom_opal_align));
1329 prom_debug("(rc = %ld) ", rc);
1330 if (rc != 0) {
1331 prom_printf("not there.\n");
1332 return;
1333 }
1334 RELOC(of_platform) = PLATFORM_OPAL;
1335 prom_printf(" there !\n");
1336 prom_debug(" opal_size = 0x%lx\n", RELOC(prom_opal_size));
1337 prom_debug(" opal_align = 0x%lx\n", RELOC(prom_opal_align));
1338 if (RELOC(prom_opal_align) < 0x10000)
1339 RELOC(prom_opal_align) = 0x10000;
1340}
1341
1342static int prom_rtas_call(int token, int nargs, int nret, int *outputs, ...)
1343{
1344 struct rtas_args rtas_args;
1345 va_list list;
1346 int i;
1347
1348 rtas_args.token = token;
1349 rtas_args.nargs = nargs;
1350 rtas_args.nret = nret;
1351 rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]);
1352 va_start(list, outputs);
1353 for (i = 0; i < nargs; ++i)
1354 rtas_args.args[i] = va_arg(list, rtas_arg_t);
1355 va_end(list);
1356
1357 for (i = 0; i < nret; ++i)
1358 rtas_args.rets[i] = 0;
1359
1360 opal_enter_rtas(&rtas_args, RELOC(prom_rtas_data),
1361 RELOC(prom_rtas_entry));
1362
1363 if (nret > 1 && outputs != NULL)
1364 for (i = 0; i < nret-1; ++i)
1365 outputs[i] = rtas_args.rets[i+1];
1366 return (nret > 0)? rtas_args.rets[0]: 0;
1367}
1368
1369static void __init prom_opal_hold_cpus(void)
1370{
1371 int i, cnt, cpu, rc;
1372 long j;
1373 phandle node;
1374 char type[64];
1375 u32 servers[8];
1376 struct prom_t *_prom = &RELOC(prom);
1377 void *entry = (unsigned long *)&RELOC(opal_secondary_entry);
1378 struct opal_secondary_data *data = &RELOC(opal_secondary_data);
1379
1380 prom_debug("prom_opal_hold_cpus: start...\n");
1381 prom_debug(" - entry = 0x%x\n", entry);
1382 prom_debug(" - data = 0x%x\n", data);
1383
1384 data->ack = -1;
1385 data->go = 0;
1386
1387 /* look for cpus */
1388 for (node = 0; prom_next_node(&node); ) {
1389 type[0] = 0;
1390 prom_getprop(node, "device_type", type, sizeof(type));
1391 if (strcmp(type, RELOC("cpu")) != 0)
1392 continue;
1393
1394 /* Skip non-configured cpus. */
1395 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1396 if (strcmp(type, RELOC("okay")) != 0)
1397 continue;
1398
1399 cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
1400 sizeof(servers));
1401 if (cnt == PROM_ERROR)
1402 break;
1403 cnt >>= 2;
1404 for (i = 0; i < cnt; i++) {
1405 cpu = servers[i];
1406 prom_debug("CPU %d ... ", cpu);
1407 if (cpu == _prom->cpu) {
1408 prom_debug("booted !\n");
1409 continue;
1410 }
1411 prom_debug("starting ... ");
1412
1413 /* Init the acknowledge var which will be reset by
1414 * the secondary cpu when it awakens from its OF
1415 * spinloop.
1416 */
1417 data->ack = -1;
1418 rc = prom_rtas_call(RELOC(prom_rtas_start_cpu), 3, 1,
1419 NULL, cpu, entry, data);
1420 prom_debug("rtas rc=%d ...", rc);
1421
1422 for (j = 0; j < 100000000 && data->ack == -1; j++) {
1423 HMT_low();
1424 mb();
1425 }
1426 HMT_medium();
1427 if (data->ack != -1)
1428 prom_debug("done, PIR=0x%x\n", data->ack);
1429 else
1430 prom_debug("timeout !\n");
1431 }
1432 }
1433 prom_debug("prom_opal_hold_cpus: end...\n");
1434}
1435
1436static void prom_opal_takeover(void)
1437{
1438 struct opal_secondary_data *data = &RELOC(opal_secondary_data);
1439 struct opal_takeover_args *args = &data->args;
1440 u64 align = RELOC(prom_opal_align);
1441 u64 top_addr, opal_addr;
1442
1443 args->k_image = (u64)RELOC(_stext);
1444 args->k_size = _end - _stext;
1445 args->k_entry = 0;
1446 args->k_entry2 = 0x60;
1447
1448 top_addr = _ALIGN_UP(args->k_size, align);
1449
1450 if (RELOC(prom_initrd_start) != 0) {
1451 args->rd_image = RELOC(prom_initrd_start);
1452 args->rd_size = RELOC(prom_initrd_end) - args->rd_image;
1453 args->rd_loc = top_addr;
1454 top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
1455 }
1456
1457 /* Pickup an address for the HAL. We want to go really high
1458 * up to avoid problem with future kexecs. On the other hand
1459 * we don't want to be all over the TCEs on P5IOC2 machines
1460 * which are going to be up there too. We assume the machine
1461 * has plenty of memory, and we ask for the HAL for now to
1462 * be just below the 1G point, or above the initrd
1463 */
1464 opal_addr = _ALIGN_DOWN(0x40000000 - RELOC(prom_opal_size), align);
1465 if (opal_addr < top_addr)
1466 opal_addr = top_addr;
1467 args->hal_addr = opal_addr;
1468
1469 /* Copy the command line to the kernel image */
1470 strlcpy(RELOC(boot_command_line), RELOC(prom_cmd_line),
1471 COMMAND_LINE_SIZE);
1472
1473 prom_debug(" k_image = 0x%lx\n", args->k_image);
1474 prom_debug(" k_size = 0x%lx\n", args->k_size);
1475 prom_debug(" k_entry = 0x%lx\n", args->k_entry);
1476 prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2);
1477 prom_debug(" hal_addr = 0x%lx\n", args->hal_addr);
1478 prom_debug(" rd_image = 0x%lx\n", args->rd_image);
1479 prom_debug(" rd_size = 0x%lx\n", args->rd_size);
1480 prom_debug(" rd_loc = 0x%lx\n", args->rd_loc);
1481 prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
1482 prom_close_stdin();
1483 mb();
1484 data->go = 1;
1485 for (;;)
1486 opal_do_takeover(args);
1487}
1488
1489/*
1490 * Allocate room for and instantiate OPAL
1491 */
1492static void __init prom_instantiate_opal(void)
1493{
1494 phandle opal_node;
1495 ihandle opal_inst;
1496 u64 base, entry;
1497 u64 size = 0, align = 0x10000;
1498 u32 rets[2];
1499
1500 prom_debug("prom_instantiate_opal: start...\n");
1501
1502 opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
1503 prom_debug("opal_node: %x\n", opal_node);
1504 if (!PHANDLE_VALID(opal_node))
1505 return;
1506
1507 prom_getprop(opal_node, "opal-runtime-size", &size, sizeof(size));
1508 if (size == 0)
1509 return;
1510 prom_getprop(opal_node, "opal-runtime-alignment", &align,
1511 sizeof(align));
1512
1513 base = alloc_down(size, align, 0);
1514 if (base == 0) {
1515 prom_printf("OPAL allocation failed !\n");
1516 return;
1517 }
1518
1519 opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
1520 if (!IHANDLE_VALID(opal_inst)) {
1521 prom_printf("opening opal package failed (%x)\n", opal_inst);
1522 return;
1523 }
1524
1525 prom_printf("instantiating opal at 0x%x...", base);
1526
1527 if (call_prom_ret("call-method", 4, 3, rets,
1528 ADDR("load-opal-runtime"),
1529 opal_inst,
1530 base >> 32, base & 0xffffffff) != 0
1531 || (rets[0] == 0 && rets[1] == 0)) {
1532 prom_printf(" failed\n");
1533 return;
1534 }
1535 entry = (((u64)rets[0]) << 32) | rets[1];
1536
1537 prom_printf(" done\n");
1538
1539 reserve_mem(base, size);
1540
1541 prom_debug("opal base = 0x%x\n", base);
1542 prom_debug("opal align = 0x%x\n", align);
1543 prom_debug("opal entry = 0x%x\n", entry);
1544 prom_debug("opal size = 0x%x\n", (long)size);
1545
1546 prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
1547 &base, sizeof(base));
1548 prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
1549 &entry, sizeof(entry));
1550
1551#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1552 RELOC(prom_opal_base) = base;
1553 RELOC(prom_opal_entry) = entry;
1554#endif
1555 prom_debug("prom_instantiate_opal: end...\n");
1556}
1557
1558#endif /* CONFIG_PPC_POWERNV */
1277 1559
1278/* 1560/*
1279 * Allocate room for and instantiate RTAS 1561 * Allocate room for and instantiate RTAS
@@ -1326,6 +1608,12 @@ static void __init prom_instantiate_rtas(void)
1326 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", 1608 prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
1327 &entry, sizeof(entry)); 1609 &entry, sizeof(entry));
1328 1610
1611#ifdef CONFIG_PPC_POWERNV
1612 /* PowerVN takeover hack */
1613 RELOC(prom_rtas_data) = base;
1614 RELOC(prom_rtas_entry) = entry;
1615 prom_getprop(rtas_node, "start-cpu", &RELOC(prom_rtas_start_cpu), 4);
1616#endif
1329 prom_debug("rtas base = 0x%x\n", base); 1617 prom_debug("rtas base = 0x%x\n", base);
1330 prom_debug("rtas entry = 0x%x\n", entry); 1618 prom_debug("rtas entry = 0x%x\n", entry);
1331 prom_debug("rtas size = 0x%x\n", (long)size); 1619 prom_debug("rtas size = 0x%x\n", (long)size);
@@ -1543,7 +1831,7 @@ static void __init prom_hold_cpus(void)
1543 *acknowledge = (unsigned long)-1; 1831 *acknowledge = (unsigned long)-1;
1544 1832
1545 if (reg != _prom->cpu) { 1833 if (reg != _prom->cpu) {
1546 /* Primary Thread of non-boot cpu */ 1834 /* Primary Thread of non-boot cpu or any thread */
1547 prom_printf("starting cpu hw idx %lu... ", reg); 1835 prom_printf("starting cpu hw idx %lu... ", reg);
1548 call_prom("start-cpu", 3, 0, node, 1836 call_prom("start-cpu", 3, 0, node,
1549 secondary_hold, reg); 1837 secondary_hold, reg);
@@ -1652,15 +1940,6 @@ static void __init prom_init_stdout(void)
1652 prom_setprop(val, path, "linux,boot-display", NULL, 0); 1940 prom_setprop(val, path, "linux,boot-display", NULL, 0);
1653} 1941}
1654 1942
1655static void __init prom_close_stdin(void)
1656{
1657 struct prom_t *_prom = &RELOC(prom);
1658 ihandle val;
1659
1660 if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
1661 call_prom("close", 1, 0, val);
1662}
1663
1664static int __init prom_find_machine_type(void) 1943static int __init prom_find_machine_type(void)
1665{ 1944{
1666 struct prom_t *_prom = &RELOC(prom); 1945 struct prom_t *_prom = &RELOC(prom);
@@ -1671,7 +1950,7 @@ static int __init prom_find_machine_type(void)
1671 int x; 1950 int x;
1672#endif 1951#endif
1673 1952
1674 /* Look for a PowerMac */ 1953 /* Look for a PowerMac or a Cell */
1675 len = prom_getprop(_prom->root, "compatible", 1954 len = prom_getprop(_prom->root, "compatible",
1676 compat, sizeof(compat)-1); 1955 compat, sizeof(compat)-1);
1677 if (len > 0) { 1956 if (len > 0) {
@@ -1697,7 +1976,11 @@ static int __init prom_find_machine_type(void)
1697 } 1976 }
1698 } 1977 }
1699#ifdef CONFIG_PPC64 1978#ifdef CONFIG_PPC64
1700 /* If not a mac, try to figure out if it's an IBM pSeries or any other 1979 /* Try to detect OPAL */
1980 if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
1981 return PLATFORM_OPAL;
1982
1983 /* Try to figure out if it's an IBM pSeries or any other
1701 * PAPR compliant platform. We assume it is if : 1984 * PAPR compliant platform. We assume it is if :
1702 * - /device_type is "chrp" (please, do NOT use that for future 1985 * - /device_type is "chrp" (please, do NOT use that for future
1703 * non-IBM designs ! 1986 * non-IBM designs !
@@ -1924,7 +2207,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1924 unsigned long soff; 2207 unsigned long soff;
1925 unsigned char *valp; 2208 unsigned char *valp;
1926 static char pname[MAX_PROPERTY_NAME]; 2209 static char pname[MAX_PROPERTY_NAME];
1927 int l, room; 2210 int l, room, has_phandle = 0;
1928 2211
1929 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end); 2212 dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
1930 2213
@@ -2008,19 +2291,26 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2008 valp = make_room(mem_start, mem_end, l, 4); 2291 valp = make_room(mem_start, mem_end, l, 4);
2009 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l); 2292 call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
2010 *mem_start = _ALIGN(*mem_start, 4); 2293 *mem_start = _ALIGN(*mem_start, 4);
2294
2295 if (!strcmp(RELOC(pname), RELOC("phandle")))
2296 has_phandle = 1;
2011 } 2297 }
2012 2298
2013 /* Add a "linux,phandle" property. */ 2299 /* Add a "linux,phandle" property if no "phandle" property already
2014 soff = dt_find_string(RELOC("linux,phandle")); 2300 * existed (can happen with OPAL)
2015 if (soff == 0) 2301 */
2016 prom_printf("WARNING: Can't find string index for" 2302 if (!has_phandle) {
2017 " <linux-phandle> node %s\n", path); 2303 soff = dt_find_string(RELOC("linux,phandle"));
2018 else { 2304 if (soff == 0)
2019 dt_push_token(OF_DT_PROP, mem_start, mem_end); 2305 prom_printf("WARNING: Can't find string index for"
2020 dt_push_token(4, mem_start, mem_end); 2306 " <linux-phandle> node %s\n", path);
2021 dt_push_token(soff, mem_start, mem_end); 2307 else {
2022 valp = make_room(mem_start, mem_end, 4, 4); 2308 dt_push_token(OF_DT_PROP, mem_start, mem_end);
2023 *(u32 *)valp = node; 2309 dt_push_token(4, mem_start, mem_end);
2310 dt_push_token(soff, mem_start, mem_end);
2311 valp = make_room(mem_start, mem_end, 4, 4);
2312 *(u32 *)valp = node;
2313 }
2024 } 2314 }
2025 2315
2026 /* do all our children */ 2316 /* do all our children */
@@ -2504,6 +2794,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2504#endif /* CONFIG_BLK_DEV_INITRD */ 2794#endif /* CONFIG_BLK_DEV_INITRD */
2505} 2795}
2506 2796
2797
2507/* 2798/*
2508 * We enter here early on, when the Open Firmware prom is still 2799 * We enter here early on, when the Open Firmware prom is still
2509 * handling exceptions and the MMU hash table for us. 2800 * handling exceptions and the MMU hash table for us.
@@ -2553,6 +2844,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2553 * between pSeries SMP and pSeries LPAR 2844 * between pSeries SMP and pSeries LPAR
2554 */ 2845 */
2555 RELOC(of_platform) = prom_find_machine_type(); 2846 RELOC(of_platform) = prom_find_machine_type();
2847 prom_printf("Detected machine type: %x\n", RELOC(of_platform));
2556 2848
2557#ifndef CONFIG_RELOCATABLE 2849#ifndef CONFIG_RELOCATABLE
2558 /* Bail if this is a kdump kernel. */ 2850 /* Bail if this is a kdump kernel. */
@@ -2565,7 +2857,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2565 */ 2857 */
2566 prom_check_initrd(r3, r4); 2858 prom_check_initrd(r3, r4);
2567 2859
2568#ifdef CONFIG_PPC_PSERIES 2860#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
2569 /* 2861 /*
2570 * On pSeries, inform the firmware about our capabilities 2862 * On pSeries, inform the firmware about our capabilities
2571 */ 2863 */
@@ -2611,14 +2903,33 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2611#endif 2903#endif
2612 2904
2613 /* 2905 /*
2614 * On non-powermacs, try to instantiate RTAS and puts all CPUs 2906 * On non-powermacs, try to instantiate RTAS. PowerMacs don't
2615 * in spin-loops. PowerMacs don't have a working RTAS and use 2907 * have a usable RTAS implementation.
2616 * a different way to spin CPUs
2617 */ 2908 */
2618 if (RELOC(of_platform) != PLATFORM_POWERMAC) { 2909 if (RELOC(of_platform) != PLATFORM_POWERMAC &&
2910 RELOC(of_platform) != PLATFORM_OPAL)
2619 prom_instantiate_rtas(); 2911 prom_instantiate_rtas();
2912
2913#ifdef CONFIG_PPC_POWERNV
2914 /* Detect HAL and try instanciating it & doing takeover */
2915 if (RELOC(of_platform) == PLATFORM_PSERIES_LPAR) {
2916 prom_query_opal();
2917 if (RELOC(of_platform) == PLATFORM_OPAL) {
2918 prom_opal_hold_cpus();
2919 prom_opal_takeover();
2920 }
2921 } else if (RELOC(of_platform) == PLATFORM_OPAL)
2922 prom_instantiate_opal();
2923#endif
2924
2925 /*
2926 * On non-powermacs, put all CPUs in spin-loops.
2927 *
2928 * PowerMacs use a different mechanism to spin CPUs
2929 */
2930 if (RELOC(of_platform) != PLATFORM_POWERMAC &&
2931 RELOC(of_platform) != PLATFORM_OPAL)
2620 prom_hold_cpus(); 2932 prom_hold_cpus();
2621 }
2622 2933
2623 /* 2934 /*
2624 * Fill in some infos for use by the kernel later on 2935 * Fill in some infos for use by the kernel later on
@@ -2685,7 +2996,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2685 reloc_got2(-offset); 2996 reloc_got2(-offset);
2686#endif 2997#endif
2687 2998
2688 __start(hdr, kbase, 0); 2999#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
3000 /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
3001 __start(hdr, kbase, 0, 0, 0,
3002 RELOC(prom_opal_base), RELOC(prom_opal_entry));
3003#else
3004 __start(hdr, kbase, 0, 0, 0, 0, 0);
3005#endif
2689 3006
2690 return 0; 3007 return 0;
2691} 3008}
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 9f82f4937892..70f4286eaa7a 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -20,7 +20,9 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
20_end enter_prom memcpy memset reloc_offset __secondary_hold 20_end enter_prom memcpy memset reloc_offset __secondary_hold
21__secondary_hold_acknowledge __secondary_hold_spinloop __start 21__secondary_hold_acknowledge __secondary_hold_spinloop __start
22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
23reloc_got2 kernstart_addr memstart_addr linux_banner" 23reloc_got2 kernstart_addr memstart_addr linux_banner _stext
24opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
25boot_command_line"
24 26
25NM="$1" 27NM="$1"
26OBJ="$2" 28OBJ="$2"
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 05b7dd217f60..18447c4fbad3 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1497,9 +1497,14 @@ long arch_ptrace(struct task_struct *child, long request,
1497 if (index < PT_FPR0) { 1497 if (index < PT_FPR0) {
1498 tmp = ptrace_get_reg(child, (int) index); 1498 tmp = ptrace_get_reg(child, (int) index);
1499 } else { 1499 } else {
1500 unsigned int fpidx = index - PT_FPR0;
1501
1500 flush_fp_to_thread(child); 1502 flush_fp_to_thread(child);
1501 tmp = ((unsigned long *)child->thread.fpr) 1503 if (fpidx < (PT_FPSCR - PT_FPR0))
1502 [TS_FPRWIDTH * (index - PT_FPR0)]; 1504 tmp = ((unsigned long *)child->thread.fpr)
1505 [fpidx * TS_FPRWIDTH];
1506 else
1507 tmp = child->thread.fpscr.val;
1503 } 1508 }
1504 ret = put_user(tmp, datalp); 1509 ret = put_user(tmp, datalp);
1505 break; 1510 break;
@@ -1525,9 +1530,14 @@ long arch_ptrace(struct task_struct *child, long request,
1525 if (index < PT_FPR0) { 1530 if (index < PT_FPR0) {
1526 ret = ptrace_put_reg(child, index, data); 1531 ret = ptrace_put_reg(child, index, data);
1527 } else { 1532 } else {
1533 unsigned int fpidx = index - PT_FPR0;
1534
1528 flush_fp_to_thread(child); 1535 flush_fp_to_thread(child);
1529 ((unsigned long *)child->thread.fpr) 1536 if (fpidx < (PT_FPSCR - PT_FPR0))
1530 [TS_FPRWIDTH * (index - PT_FPR0)] = data; 1537 ((unsigned long *)child->thread.fpr)
1538 [fpidx * TS_FPRWIDTH] = data;
1539 else
1540 child->thread.fpscr.val = data;
1531 ret = 0; 1541 ret = 0;
1532 } 1542 }
1533 break; 1543 break;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 209135af0a40..c1ce86357ecb 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -117,7 +117,7 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
117 * This is called very early on the boot process, after a minimal 117 * This is called very early on the boot process, after a minimal
118 * MMU environment has been set up but before MMU_init is called. 118 * MMU environment has been set up but before MMU_init is called.
119 */ 119 */
120notrace void __init machine_init(unsigned long dt_ptr) 120notrace void __init machine_init(u64 dt_ptr)
121{ 121{
122 lockdep_init(); 122 lockdep_init();
123 123
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index aebef1320ed7..d4168c93098f 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -278,14 +278,14 @@ static void __init initialize_cache_info(void)
278 278
279 DBG(" -> initialize_cache_info()\n"); 279 DBG(" -> initialize_cache_info()\n");
280 280
281 for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) { 281 for_each_node_by_type(np, "cpu") {
282 num_cpus += 1; 282 num_cpus += 1;
283 283
284 /* We're assuming *all* of the CPUs have the same 284 /*
285 * We're assuming *all* of the CPUs have the same
285 * d-cache and i-cache sizes... -Peter 286 * d-cache and i-cache sizes... -Peter
286 */ 287 */
287 288 if (num_cpus == 1) {
288 if ( num_cpus == 1 ) {
289 const u32 *sizep, *lsizep; 289 const u32 *sizep, *lsizep;
290 u32 size, lsize; 290 u32 size, lsize;
291 291
@@ -294,10 +294,13 @@ static void __init initialize_cache_info(void)
294 sizep = of_get_property(np, "d-cache-size", NULL); 294 sizep = of_get_property(np, "d-cache-size", NULL);
295 if (sizep != NULL) 295 if (sizep != NULL)
296 size = *sizep; 296 size = *sizep;
297 lsizep = of_get_property(np, "d-cache-block-size", NULL); 297 lsizep = of_get_property(np, "d-cache-block-size",
298 NULL);
298 /* fallback if block size missing */ 299 /* fallback if block size missing */
299 if (lsizep == NULL) 300 if (lsizep == NULL)
300 lsizep = of_get_property(np, "d-cache-line-size", NULL); 301 lsizep = of_get_property(np,
302 "d-cache-line-size",
303 NULL);
301 if (lsizep != NULL) 304 if (lsizep != NULL)
302 lsize = *lsizep; 305 lsize = *lsizep;
303 if (sizep == 0 || lsizep == 0) 306 if (sizep == 0 || lsizep == 0)
@@ -314,9 +317,12 @@ static void __init initialize_cache_info(void)
314 sizep = of_get_property(np, "i-cache-size", NULL); 317 sizep = of_get_property(np, "i-cache-size", NULL);
315 if (sizep != NULL) 318 if (sizep != NULL)
316 size = *sizep; 319 size = *sizep;
317 lsizep = of_get_property(np, "i-cache-block-size", NULL); 320 lsizep = of_get_property(np, "i-cache-block-size",
321 NULL);
318 if (lsizep == NULL) 322 if (lsizep == NULL)
319 lsizep = of_get_property(np, "i-cache-line-size", NULL); 323 lsizep = of_get_property(np,
324 "i-cache-line-size",
325 NULL);
320 if (lsizep != NULL) 326 if (lsizep != NULL)
321 lsize = *lsizep; 327 lsize = *lsizep;
322 if (sizep == 0 || lsizep == 0) 328 if (sizep == 0 || lsizep == 0)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 7bf2187dfd99..af7e7722ecae 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -70,6 +70,10 @@
70static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); 70static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
71#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) 71#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
72#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) 72#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
73
74/* State of each CPU during hotplug phases */
75static DEFINE_PER_CPU(int, cpu_state) = { 0 };
76
73#else 77#else
74static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; 78static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
75#define get_idle_for_cpu(x) (idle_thread_array[(x)]) 79#define get_idle_for_cpu(x) (idle_thread_array[(x)])
@@ -104,12 +108,25 @@ int __devinit smp_generic_kick_cpu(int nr)
104 * cpu_start field to become non-zero After we set cpu_start, 108 * cpu_start field to become non-zero After we set cpu_start,
105 * the processor will continue on to secondary_start 109 * the processor will continue on to secondary_start
106 */ 110 */
107 paca[nr].cpu_start = 1; 111 if (!paca[nr].cpu_start) {
108 smp_mb(); 112 paca[nr].cpu_start = 1;
113 smp_mb();
114 return 0;
115 }
116
117#ifdef CONFIG_HOTPLUG_CPU
118 /*
119 * Ok it's not there, so it might be soft-unplugged, let's
120 * try to bring it back
121 */
122 per_cpu(cpu_state, nr) = CPU_UP_PREPARE;
123 smp_wmb();
124 smp_send_reschedule(nr);
125#endif /* CONFIG_HOTPLUG_CPU */
109 126
110 return 0; 127 return 0;
111} 128}
112#endif 129#endif /* CONFIG_PPC64 */
113 130
114static irqreturn_t call_function_action(int irq, void *data) 131static irqreturn_t call_function_action(int irq, void *data)
115{ 132{
@@ -357,8 +374,6 @@ void __devinit smp_prepare_boot_cpu(void)
357} 374}
358 375
359#ifdef CONFIG_HOTPLUG_CPU 376#ifdef CONFIG_HOTPLUG_CPU
360/* State of each CPU during hotplug phases */
361static DEFINE_PER_CPU(int, cpu_state) = { 0 };
362 377
363int generic_cpu_disable(void) 378int generic_cpu_disable(void)
364{ 379{
@@ -406,6 +421,11 @@ void generic_set_cpu_dead(unsigned int cpu)
406{ 421{
407 per_cpu(cpu_state, cpu) = CPU_DEAD; 422 per_cpu(cpu_state, cpu) = CPU_DEAD;
408} 423}
424
425int generic_check_cpu_restart(unsigned int cpu)
426{
427 return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
428}
409#endif 429#endif
410 430
411struct create_idle { 431struct create_idle {
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
index aa17b76dd427..641f9adc6205 100644
--- a/arch/powerpc/kernel/swsusp.c
+++ b/arch/powerpc/kernel/swsusp.c
@@ -33,6 +33,6 @@ void save_processor_state(void)
33void restore_processor_state(void) 33void restore_processor_state(void)
34{ 34{
35#ifdef CONFIG_PPC32 35#ifdef CONFIG_PPC32
36 switch_mmu_context(NULL, current->active_mm); 36 switch_mmu_context(current->active_mm, current->active_mm);
37#endif 37#endif
38} 38}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f19d9777d3c1..4e5908264d1a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -457,7 +457,14 @@ int machine_check_e500mc(struct pt_regs *regs)
457 457
458 if (reason & MCSR_DCPERR_MC) { 458 if (reason & MCSR_DCPERR_MC) {
459 printk("Data Cache Parity Error\n"); 459 printk("Data Cache Parity Error\n");
460 recoverable = 0; 460
461 /*
462 * In write shadow mode we auto-recover from the error, but it
463 * may still get logged and cause a machine check. We should
464 * only treat the non-write shadow case as non-recoverable.
465 */
466 if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS))
467 recoverable = 0;
461 } 468 }
462 469
463 if (reason & MCSR_L2MMU_MHIT) { 470 if (reason & MCSR_L2MMU_MHIT) {
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index b4607a91d1f4..57fa2c0a531c 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -69,6 +69,12 @@ void __init udbg_early_init(void)
69 udbg_init_wsp(); 69 udbg_init_wsp();
70#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) 70#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
71 udbg_init_ehv_bc(); 71 udbg_init_ehv_bc();
72#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
73 udbg_init_ps3gelic();
74#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
75 udbg_init_debug_opal_raw();
76#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
77 udbg_init_debug_opal_hvsi();
72#endif 78#endif
73 79
74#ifdef CONFIG_PPC_EARLY_DEBUG 80#ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 1b695fdc362b..34d291d83ec8 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -605,15 +605,20 @@ static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask)
605 return dma_iommu_ops.dma_supported(dev, mask); 605 return dma_iommu_ops.dma_supported(dev, mask);
606} 606}
607 607
608struct dma_map_ops vio_dma_mapping_ops = { 608static u64 vio_dma_get_required_mask(struct device *dev)
609 .alloc_coherent = vio_dma_iommu_alloc_coherent, 609{
610 .free_coherent = vio_dma_iommu_free_coherent, 610 return dma_iommu_ops.get_required_mask(dev);
611 .map_sg = vio_dma_iommu_map_sg, 611}
612 .unmap_sg = vio_dma_iommu_unmap_sg,
613 .map_page = vio_dma_iommu_map_page,
614 .unmap_page = vio_dma_iommu_unmap_page,
615 .dma_supported = vio_dma_iommu_dma_supported,
616 612
613struct dma_map_ops vio_dma_mapping_ops = {
614 .alloc_coherent = vio_dma_iommu_alloc_coherent,
615 .free_coherent = vio_dma_iommu_free_coherent,
616 .map_sg = vio_dma_iommu_map_sg,
617 .unmap_sg = vio_dma_iommu_unmap_sg,
618 .map_page = vio_dma_iommu_map_page,
619 .unmap_page = vio_dma_iommu_unmap_page,
620 .dma_supported = vio_dma_iommu_dma_supported,
621 .get_required_mask = vio_dma_get_required_mask,
617}; 622};
618 623
619/** 624/**
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
index 62279200d965..a73f0884d358 100644
--- a/arch/powerpc/math-emu/math_efp.c
+++ b/arch/powerpc/math-emu/math_efp.c
@@ -171,10 +171,6 @@ static unsigned long insn_type(unsigned long speinsn)
171 case EFDNABS: ret = XA; break; 171 case EFDNABS: ret = XA; break;
172 case EFDNEG: ret = XA; break; 172 case EFDNEG: ret = XA; break;
173 case EFDSUB: ret = AB; break; 173 case EFDSUB: ret = AB; break;
174
175 default:
176 printk(KERN_ERR "\nOoops! SPE instruction no type found.");
177 printk(KERN_ERR "\ninst code: %08lx\n", speinsn);
178 } 174 }
179 175
180 return ret; 176 return ret;
@@ -195,7 +191,7 @@ int do_spe_mathemu(struct pt_regs *regs)
195 191
196 type = insn_type(speinsn); 192 type = insn_type(speinsn);
197 if (type == NOTYPE) 193 if (type == NOTYPE)
198 return -ENOSYS; 194 goto illegal;
199 195
200 func = speinsn & 0x7ff; 196 func = speinsn & 0x7ff;
201 fc = (speinsn >> 21) & 0x1f; 197 fc = (speinsn >> 21) & 0x1f;
@@ -212,12 +208,10 @@ int do_spe_mathemu(struct pt_regs *regs)
212 208
213 __FPU_FPSCR = mfspr(SPRN_SPEFSCR); 209 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
214 210
215#ifdef DEBUG 211 pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
216 printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); 212 pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
217 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); 213 pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]);
218 printk("va: %08x %08x\n", va.wp[0], va.wp[1]); 214 pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
219 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
220#endif
221 215
222 switch (src) { 216 switch (src) {
223 case SPFP: { 217 case SPFP: {
@@ -235,10 +229,8 @@ int do_spe_mathemu(struct pt_regs *regs)
235 break; 229 break;
236 } 230 }
237 231
238#ifdef DEBUG 232 pr_debug("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
239 printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c); 233 pr_debug("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
240 printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
241#endif
242 234
243 switch (func) { 235 switch (func) {
244 case EFSABS: 236 case EFSABS:
@@ -305,10 +297,10 @@ int do_spe_mathemu(struct pt_regs *regs)
305 FP_DECL_D(DB); 297 FP_DECL_D(DB);
306 FP_CLEAR_EXCEPTIONS; 298 FP_CLEAR_EXCEPTIONS;
307 FP_UNPACK_DP(DB, vb.dp); 299 FP_UNPACK_DP(DB, vb.dp);
308#ifdef DEBUG 300
309 printk("DB: %ld %08lx %08lx %ld (%ld)\n", 301 pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
310 DB_s, DB_f1, DB_f0, DB_e, DB_c); 302 DB_s, DB_f1, DB_f0, DB_e, DB_c);
311#endif 303
312 FP_CONV(S, D, 1, 2, SR, DB); 304 FP_CONV(S, D, 1, 2, SR, DB);
313 goto pack_s; 305 goto pack_s;
314 } 306 }
@@ -332,9 +324,8 @@ int do_spe_mathemu(struct pt_regs *regs)
332 break; 324 break;
333 325
334pack_s: 326pack_s:
335#ifdef DEBUG 327 pr_debug("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
336 printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c); 328
337#endif
338 FP_PACK_SP(vc.wp + 1, SR); 329 FP_PACK_SP(vc.wp + 1, SR);
339 goto update_regs; 330 goto update_regs;
340 331
@@ -365,12 +356,10 @@ cmp_s:
365 break; 356 break;
366 } 357 }
367 358
368#ifdef DEBUG 359 pr_debug("DA: %ld %08lx %08lx %ld (%ld)\n",
369 printk("DA: %ld %08lx %08lx %ld (%ld)\n",
370 DA_s, DA_f1, DA_f0, DA_e, DA_c); 360 DA_s, DA_f1, DA_f0, DA_e, DA_c);
371 printk("DB: %ld %08lx %08lx %ld (%ld)\n", 361 pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
372 DB_s, DB_f1, DB_f0, DB_e, DB_c); 362 DB_s, DB_f1, DB_f0, DB_e, DB_c);
373#endif
374 363
375 switch (func) { 364 switch (func) {
376 case EFDABS: 365 case EFDABS:
@@ -438,10 +427,10 @@ cmp_s:
438 FP_DECL_S(SB); 427 FP_DECL_S(SB);
439 FP_CLEAR_EXCEPTIONS; 428 FP_CLEAR_EXCEPTIONS;
440 FP_UNPACK_SP(SB, vb.wp + 1); 429 FP_UNPACK_SP(SB, vb.wp + 1);
441#ifdef DEBUG 430
442 printk("SB: %ld %08lx %ld (%ld)\n", 431 pr_debug("SB: %ld %08lx %ld (%ld)\n",
443 SB_s, SB_f, SB_e, SB_c); 432 SB_s, SB_f, SB_e, SB_c);
444#endif 433
445 FP_CONV(D, S, 2, 1, DR, SB); 434 FP_CONV(D, S, 2, 1, DR, SB);
446 goto pack_d; 435 goto pack_d;
447 } 436 }
@@ -471,10 +460,9 @@ cmp_s:
471 break; 460 break;
472 461
473pack_d: 462pack_d:
474#ifdef DEBUG 463 pr_debug("DR: %ld %08lx %08lx %ld (%ld)\n",
475 printk("DR: %ld %08lx %08lx %ld (%ld)\n",
476 DR_s, DR_f1, DR_f0, DR_e, DR_c); 464 DR_s, DR_f1, DR_f0, DR_e, DR_c);
477#endif 465
478 FP_PACK_DP(vc.dp, DR); 466 FP_PACK_DP(vc.dp, DR);
479 goto update_regs; 467 goto update_regs;
480 468
@@ -511,12 +499,14 @@ cmp_d:
511 break; 499 break;
512 } 500 }
513 501
514#ifdef DEBUG 502 pr_debug("SA0: %ld %08lx %ld (%ld)\n",
515 printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c); 503 SA0_s, SA0_f, SA0_e, SA0_c);
516 printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c); 504 pr_debug("SA1: %ld %08lx %ld (%ld)\n",
517 printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c); 505 SA1_s, SA1_f, SA1_e, SA1_c);
518 printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c); 506 pr_debug("SB0: %ld %08lx %ld (%ld)\n",
519#endif 507 SB0_s, SB0_f, SB0_e, SB0_c);
508 pr_debug("SB1: %ld %08lx %ld (%ld)\n",
509 SB1_s, SB1_f, SB1_e, SB1_c);
520 510
521 switch (func) { 511 switch (func) {
522 case EVFSABS: 512 case EVFSABS:
@@ -605,10 +595,11 @@ cmp_d:
605 break; 595 break;
606 596
607pack_vs: 597pack_vs:
608#ifdef DEBUG 598 pr_debug("SR0: %ld %08lx %ld (%ld)\n",
609 printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c); 599 SR0_s, SR0_f, SR0_e, SR0_c);
610 printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c); 600 pr_debug("SR1: %ld %08lx %ld (%ld)\n",
611#endif 601 SR1_s, SR1_f, SR1_e, SR1_c);
602
612 FP_PACK_SP(vc.wp, SR0); 603 FP_PACK_SP(vc.wp, SR0);
613 FP_PACK_SP(vc.wp + 1, SR1); 604 FP_PACK_SP(vc.wp + 1, SR1);
614 goto update_regs; 605 goto update_regs;
@@ -646,14 +637,12 @@ update_regs:
646 current->thread.evr[fc] = vc.wp[0]; 637 current->thread.evr[fc] = vc.wp[0];
647 regs->gpr[fc] = vc.wp[1]; 638 regs->gpr[fc] = vc.wp[1];
648 639
649#ifdef DEBUG 640 pr_debug("ccr = %08lx\n", regs->ccr);
650 printk("ccr = %08lx\n", regs->ccr); 641 pr_debug("cur exceptions = %08x spefscr = %08lx\n",
651 printk("cur exceptions = %08x spefscr = %08lx\n",
652 FP_CUR_EXCEPTIONS, __FPU_FPSCR); 642 FP_CUR_EXCEPTIONS, __FPU_FPSCR);
653 printk("vc: %08x %08x\n", vc.wp[0], vc.wp[1]); 643 pr_debug("vc: %08x %08x\n", vc.wp[0], vc.wp[1]);
654 printk("va: %08x %08x\n", va.wp[0], va.wp[1]); 644 pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]);
655 printk("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); 645 pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
656#endif
657 646
658 return 0; 647 return 0;
659 648
@@ -661,9 +650,7 @@ illegal:
661 if (have_e500_cpu_a005_erratum) { 650 if (have_e500_cpu_a005_erratum) {
662 /* according to e500 cpu a005 erratum, reissue efp inst */ 651 /* according to e500 cpu a005 erratum, reissue efp inst */
663 regs->nip -= 4; 652 regs->nip -= 4;
664#ifdef DEBUG 653 pr_debug("re-issue efp inst: %08lx\n", speinsn);
665 printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
666#endif
667 return 0; 654 return 0;
668 } 655 }
669 656
@@ -685,13 +672,20 @@ int speround_handler(struct pt_regs *regs)
685 type = insn_type(speinsn & 0x7ff); 672 type = insn_type(speinsn & 0x7ff);
686 if (type == XCR) return -ENOSYS; 673 if (type == XCR) return -ENOSYS;
687 674
675 __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
676 pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
677
678 /* No need to round if the result is exact */
679 if (!(__FPU_FPSCR & FP_EX_INEXACT))
680 return 0;
681
688 fc = (speinsn >> 21) & 0x1f; 682 fc = (speinsn >> 21) & 0x1f;
689 s_lo = regs->gpr[fc] & SIGN_BIT_S; 683 s_lo = regs->gpr[fc] & SIGN_BIT_S;
690 s_hi = current->thread.evr[fc] & SIGN_BIT_S; 684 s_hi = current->thread.evr[fc] & SIGN_BIT_S;
691 fgpr.wp[0] = current->thread.evr[fc]; 685 fgpr.wp[0] = current->thread.evr[fc];
692 fgpr.wp[1] = regs->gpr[fc]; 686 fgpr.wp[1] = regs->gpr[fc];
693 687
694 __FPU_FPSCR = mfspr(SPRN_SPEFSCR); 688 pr_debug("round fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
695 689
696 switch ((speinsn >> 5) & 0x7) { 690 switch ((speinsn >> 5) & 0x7) {
697 /* Since SPE instructions on E500 core can handle round to nearest 691 /* Since SPE instructions on E500 core can handle round to nearest
@@ -731,6 +725,8 @@ int speround_handler(struct pt_regs *regs)
731 current->thread.evr[fc] = fgpr.wp[0]; 725 current->thread.evr[fc] = fgpr.wp[0];
732 regs->gpr[fc] = fgpr.wp[1]; 726 regs->gpr[fc] = fgpr.wp[1];
733 727
728 pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
729
734 return 0; 730 return 0;
735} 731}
736 732
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index bdca46e08382..991ee813d2a8 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o
29ifeq ($(CONFIG_HUGETLB_PAGE),y) 29ifeq ($(CONFIG_HUGETLB_PAGE),y)
30obj-y += hugetlbpage.o 30obj-y += hugetlbpage.o
31obj-$(CONFIG_PPC_STD_MMU_64) += hugetlbpage-hash64.o 31obj-$(CONFIG_PPC_STD_MMU_64) += hugetlbpage-hash64.o
32obj-$(CONFIG_PPC_BOOK3E_MMU) += hugetlbpage-book3e.o
32endif 33endif
33obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o 34obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
34obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o 35obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index f7802c8bba0a..66a6fd38e9cd 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -101,17 +101,17 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
101 101
102/* 102/*
103 * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; 103 * Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
104 * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus 104 * in particular size must be a power of 4 between 4k and the max supported by
105 * that support extended page sizes). Note that while some cpus support a 105 * an implementation; max may further be limited by what can be represented in
106 * page size of 4G, we don't allow its use here. 106 * an unsigned long (for example, 32-bit implementations cannot support a 4GB
107 * size).
107 */ 108 */
108static void settlbcam(int index, unsigned long virt, phys_addr_t phys, 109static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
109 unsigned long size, unsigned long flags, unsigned int pid) 110 unsigned long size, unsigned long flags, unsigned int pid)
110{ 111{
111 unsigned int tsize, lz; 112 unsigned int tsize;
112 113
113 asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (size)); 114 tsize = __ilog2(size) - 10;
114 tsize = 21 - lz;
115 115
116#ifdef CONFIG_SMP 116#ifdef CONFIG_SMP
117 if ((flags & _PAGE_NO_CACHE) == 0) 117 if ((flags & _PAGE_NO_CACHE) == 0)
@@ -146,29 +146,36 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
146 loadcam_entry(index); 146 loadcam_entry(index);
147} 147}
148 148
149unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
150 phys_addr_t phys)
151{
152 unsigned int camsize = __ilog2(ram) & ~1U;
153 unsigned int align = __ffs(virt | phys) & ~1U;
154 unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
155
156 /* Convert (4^max) kB to (2^max) bytes */
157 max_cam = max_cam * 2 + 10;
158
159 if (camsize > align)
160 camsize = align;
161 if (camsize > max_cam)
162 camsize = max_cam;
163
164 return 1UL << camsize;
165}
166
149unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) 167unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
150{ 168{
151 int i; 169 int i;
152 unsigned long virt = PAGE_OFFSET; 170 unsigned long virt = PAGE_OFFSET;
153 phys_addr_t phys = memstart_addr; 171 phys_addr_t phys = memstart_addr;
154 unsigned long amount_mapped = 0; 172 unsigned long amount_mapped = 0;
155 unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
156
157 /* Convert (4^max) kB to (2^max) bytes */
158 max_cam = max_cam * 2 + 10;
159 173
160 /* Calculate CAM values */ 174 /* Calculate CAM values */
161 for (i = 0; ram && i < max_cam_idx; i++) { 175 for (i = 0; ram && i < max_cam_idx; i++) {
162 unsigned int camsize = __ilog2(ram) & ~1U;
163 unsigned int align = __ffs(virt | phys) & ~1U;
164 unsigned long cam_sz; 176 unsigned long cam_sz;
165 177
166 if (camsize > align) 178 cam_sz = calc_cam_sz(ram, virt, phys);
167 camsize = align;
168 if (camsize > max_cam)
169 camsize = max_cam;
170
171 cam_sz = 1UL << camsize;
172 settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0); 179 settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0);
173 180
174 ram -= cam_sz; 181 ram -= cam_sz;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 26b2872b3d00..1628201c8cea 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -105,9 +105,6 @@ int mmu_kernel_ssize = MMU_SEGSIZE_256M;
105int mmu_highuser_ssize = MMU_SEGSIZE_256M; 105int mmu_highuser_ssize = MMU_SEGSIZE_256M;
106u16 mmu_slb_size = 64; 106u16 mmu_slb_size = 64;
107EXPORT_SYMBOL_GPL(mmu_slb_size); 107EXPORT_SYMBOL_GPL(mmu_slb_size);
108#ifdef CONFIG_HUGETLB_PAGE
109unsigned int HPAGE_SHIFT;
110#endif
111#ifdef CONFIG_PPC_64K_PAGES 108#ifdef CONFIG_PPC_64K_PAGES
112int mmu_ci_restrictions; 109int mmu_ci_restrictions;
113#endif 110#endif
@@ -534,11 +531,11 @@ static unsigned long __init htab_get_table_size(void)
534} 531}
535 532
536#ifdef CONFIG_MEMORY_HOTPLUG 533#ifdef CONFIG_MEMORY_HOTPLUG
537void create_section_mapping(unsigned long start, unsigned long end) 534int create_section_mapping(unsigned long start, unsigned long end)
538{ 535{
539 BUG_ON(htab_bolt_mapping(start, end, __pa(start), 536 return htab_bolt_mapping(start, end, __pa(start),
540 pgprot_val(PAGE_KERNEL), mmu_linear_psize, 537 pgprot_val(PAGE_KERNEL), mmu_linear_psize,
541 mmu_kernel_ssize)); 538 mmu_kernel_ssize);
542} 539}
543 540
544int remove_section_mapping(unsigned long start, unsigned long end) 541int remove_section_mapping(unsigned long start, unsigned long end)
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
new file mode 100644
index 000000000000..343ad0b87261
--- /dev/null
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -0,0 +1,121 @@
1/*
2 * PPC Huge TLB Page Support for Book3E MMU
3 *
4 * Copyright (C) 2009 David Gibson, IBM Corporation.
5 * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
6 *
7 */
8#include <linux/mm.h>
9#include <linux/hugetlb.h>
10
11static inline int mmu_get_tsize(int psize)
12{
13 return mmu_psize_defs[psize].enc;
14}
15
16static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid)
17{
18 int found = 0;
19
20 mtspr(SPRN_MAS6, pid << 16);
21 if (mmu_has_feature(MMU_FTR_USE_TLBRSRV)) {
22 asm volatile(
23 "li %0,0\n"
24 "tlbsx. 0,%1\n"
25 "bne 1f\n"
26 "li %0,1\n"
27 "1:\n"
28 : "=&r"(found) : "r"(ea));
29 } else {
30 asm volatile(
31 "tlbsx 0,%1\n"
32 "mfspr %0,0x271\n"
33 "srwi %0,%0,31\n"
34 : "=&r"(found) : "r"(ea));
35 }
36
37 return found;
38}
39
40void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte)
41{
42 unsigned long mas1, mas2;
43 u64 mas7_3;
44 unsigned long psize, tsize, shift;
45 unsigned long flags;
46
47#ifdef CONFIG_PPC_FSL_BOOK3E
48 int index, lz, ncams;
49 struct vm_area_struct *vma;
50#endif
51
52 if (unlikely(is_kernel_addr(ea)))
53 return;
54
55#ifdef CONFIG_PPC_MM_SLICES
56 psize = mmu_get_tsize(get_slice_psize(mm, ea));
57 tsize = mmu_get_psize(psize);
58 shift = mmu_psize_defs[psize].shift;
59#else
60 vma = find_vma(mm, ea);
61 psize = vma_mmu_pagesize(vma); /* returns actual size in bytes */
62 asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (psize));
63 shift = 31 - lz;
64 tsize = 21 - lz;
65#endif
66
67 /*
68 * We can't be interrupted while we're setting up the MAS
69 * regusters or after we've confirmed that no tlb exists.
70 */
71 local_irq_save(flags);
72
73 if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
74 local_irq_restore(flags);
75 return;
76 }
77
78#ifdef CONFIG_PPC_FSL_BOOK3E
79 ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
80
81 /* We have to use the CAM(TLB1) on FSL parts for hugepages */
82 index = __get_cpu_var(next_tlbcam_idx);
83 mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1));
84
85 /* Just round-robin the entries and wrap when we hit the end */
86 if (unlikely(index == ncams - 1))
87 __get_cpu_var(next_tlbcam_idx) = tlbcam_index;
88 else
89 __get_cpu_var(next_tlbcam_idx)++;
90#endif
91 mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize);
92 mas2 = ea & ~((1UL << shift) - 1);
93 mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK;
94 mas7_3 = (u64)pte_pfn(pte) << PAGE_SHIFT;
95 mas7_3 |= (pte_val(pte) >> PTE_BAP_SHIFT) & MAS3_BAP_MASK;
96 if (!pte_dirty(pte))
97 mas7_3 &= ~(MAS3_SW|MAS3_UW);
98
99 mtspr(SPRN_MAS1, mas1);
100 mtspr(SPRN_MAS2, mas2);
101
102 if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) {
103 mtspr(SPRN_MAS7_MAS3, mas7_3);
104 } else {
105 mtspr(SPRN_MAS7, upper_32_bits(mas7_3));
106 mtspr(SPRN_MAS3, lower_32_bits(mas7_3));
107 }
108
109 asm volatile ("tlbwe");
110
111 local_irq_restore(flags);
112}
113
114void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
115{
116 struct hstate *hstate = hstate_file(vma->vm_file);
117 unsigned long tsize = huge_page_shift(hstate) - 10;
118
119 __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
120
121}
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index da5eb3885702..5964371303ac 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * PPC64 (POWER4) Huge TLB Page Support for Kernel. 2 * PPC Huge TLB Page Support for Kernel.
3 * 3 *
4 * Copyright (C) 2003 David Gibson, IBM Corporation. 4 * Copyright (C) 2003 David Gibson, IBM Corporation.
5 * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
5 * 6 *
6 * Based on the IA-32 version: 7 * Based on the IA-32 version:
7 * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com> 8 * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
@@ -11,24 +12,39 @@
11#include <linux/io.h> 12#include <linux/io.h>
12#include <linux/slab.h> 13#include <linux/slab.h>
13#include <linux/hugetlb.h> 14#include <linux/hugetlb.h>
15#include <linux/of_fdt.h>
16#include <linux/memblock.h>
17#include <linux/bootmem.h>
14#include <asm/pgtable.h> 18#include <asm/pgtable.h>
15#include <asm/pgalloc.h> 19#include <asm/pgalloc.h>
16#include <asm/tlb.h> 20#include <asm/tlb.h>
21#include <asm/setup.h>
17 22
18#define PAGE_SHIFT_64K 16 23#define PAGE_SHIFT_64K 16
19#define PAGE_SHIFT_16M 24 24#define PAGE_SHIFT_16M 24
20#define PAGE_SHIFT_16G 34 25#define PAGE_SHIFT_16G 34
21 26
22#define MAX_NUMBER_GPAGES 1024 27unsigned int HPAGE_SHIFT;
23 28
24/* Tracks the 16G pages after the device tree is scanned and before the 29/*
25 * huge_boot_pages list is ready. */ 30 * Tracks gpages after the device tree is scanned and before the
26static unsigned long gpage_freearray[MAX_NUMBER_GPAGES]; 31 * huge_boot_pages list is ready. On 64-bit implementations, this is
32 * just used to track 16G pages and so is a single array. 32-bit
33 * implementations may have more than one gpage size due to limitations
34 * of the memory allocators, so we need multiple arrays
35 */
36#ifdef CONFIG_PPC64
37#define MAX_NUMBER_GPAGES 1024
38static u64 gpage_freearray[MAX_NUMBER_GPAGES];
27static unsigned nr_gpages; 39static unsigned nr_gpages;
28 40#else
29/* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad() 41#define MAX_NUMBER_GPAGES 128
30 * will choke on pointers to hugepte tables, which is handy for 42struct psize_gpages {
31 * catching screwups early. */ 43 u64 gpage_list[MAX_NUMBER_GPAGES];
44 unsigned int nr_gpages;
45};
46static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT];
47#endif
32 48
33static inline int shift_to_mmu_psize(unsigned int shift) 49static inline int shift_to_mmu_psize(unsigned int shift)
34{ 50{
@@ -49,25 +65,6 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
49 65
50#define hugepd_none(hpd) ((hpd).pd == 0) 66#define hugepd_none(hpd) ((hpd).pd == 0)
51 67
52static inline pte_t *hugepd_page(hugepd_t hpd)
53{
54 BUG_ON(!hugepd_ok(hpd));
55 return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | 0xc000000000000000);
56}
57
58static inline unsigned int hugepd_shift(hugepd_t hpd)
59{
60 return hpd.pd & HUGEPD_SHIFT_MASK;
61}
62
63static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift)
64{
65 unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp);
66 pte_t *dir = hugepd_page(*hpdp);
67
68 return dir + idx;
69}
70
71pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) 68pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift)
72{ 69{
73 pgd_t *pg; 70 pgd_t *pg;
@@ -93,7 +90,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
93 if (is_hugepd(pm)) 90 if (is_hugepd(pm))
94 hpdp = (hugepd_t *)pm; 91 hpdp = (hugepd_t *)pm;
95 else if (!pmd_none(*pm)) { 92 else if (!pmd_none(*pm)) {
96 return pte_offset_map(pm, ea); 93 return pte_offset_kernel(pm, ea);
97 } 94 }
98 } 95 }
99 } 96 }
@@ -114,8 +111,18 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
114static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, 111static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
115 unsigned long address, unsigned pdshift, unsigned pshift) 112 unsigned long address, unsigned pdshift, unsigned pshift)
116{ 113{
117 pte_t *new = kmem_cache_zalloc(PGT_CACHE(pdshift - pshift), 114 struct kmem_cache *cachep;
118 GFP_KERNEL|__GFP_REPEAT); 115 pte_t *new;
116
117#ifdef CONFIG_PPC64
118 cachep = PGT_CACHE(pdshift - pshift);
119#else
120 int i;
121 int num_hugepd = 1 << (pshift - pdshift);
122 cachep = hugepte_cache;
123#endif
124
125 new = kmem_cache_zalloc(cachep, GFP_KERNEL|__GFP_REPEAT);
119 126
120 BUG_ON(pshift > HUGEPD_SHIFT_MASK); 127 BUG_ON(pshift > HUGEPD_SHIFT_MASK);
121 BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK); 128 BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK);
@@ -124,10 +131,31 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
124 return -ENOMEM; 131 return -ENOMEM;
125 132
126 spin_lock(&mm->page_table_lock); 133 spin_lock(&mm->page_table_lock);
134#ifdef CONFIG_PPC64
127 if (!hugepd_none(*hpdp)) 135 if (!hugepd_none(*hpdp))
128 kmem_cache_free(PGT_CACHE(pdshift - pshift), new); 136 kmem_cache_free(cachep, new);
129 else 137 else
130 hpdp->pd = ((unsigned long)new & ~0x8000000000000000) | pshift; 138 hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
139#else
140 /*
141 * We have multiple higher-level entries that point to the same
142 * actual pte location. Fill in each as we go and backtrack on error.
143 * We need all of these so the DTLB pgtable walk code can find the
144 * right higher-level entry without knowing if it's a hugepage or not.
145 */
146 for (i = 0; i < num_hugepd; i++, hpdp++) {
147 if (unlikely(!hugepd_none(*hpdp)))
148 break;
149 else
150 hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
151 }
152 /* If we bailed from the for loop early, an error occurred, clean up */
153 if (i < num_hugepd) {
154 for (i = i - 1 ; i >= 0; i--, hpdp--)
155 hpdp->pd = 0;
156 kmem_cache_free(cachep, new);
157 }
158#endif
131 spin_unlock(&mm->page_table_lock); 159 spin_unlock(&mm->page_table_lock);
132 return 0; 160 return 0;
133} 161}
@@ -169,11 +197,132 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz
169 return hugepte_offset(hpdp, addr, pdshift); 197 return hugepte_offset(hpdp, addr, pdshift);
170} 198}
171 199
200#ifdef CONFIG_PPC32
172/* Build list of addresses of gigantic pages. This function is used in early 201/* Build list of addresses of gigantic pages. This function is used in early
173 * boot before the buddy or bootmem allocator is setup. 202 * boot before the buddy or bootmem allocator is setup.
174 */ 203 */
175void add_gpage(unsigned long addr, unsigned long page_size, 204void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
176 unsigned long number_of_pages) 205{
206 unsigned int idx = shift_to_mmu_psize(__ffs(page_size));
207 int i;
208
209 if (addr == 0)
210 return;
211
212 gpage_freearray[idx].nr_gpages = number_of_pages;
213
214 for (i = 0; i < number_of_pages; i++) {
215 gpage_freearray[idx].gpage_list[i] = addr;
216 addr += page_size;
217 }
218}
219
220/*
221 * Moves the gigantic page addresses from the temporary list to the
222 * huge_boot_pages list.
223 */
224int alloc_bootmem_huge_page(struct hstate *hstate)
225{
226 struct huge_bootmem_page *m;
227 int idx = shift_to_mmu_psize(hstate->order + PAGE_SHIFT);
228 int nr_gpages = gpage_freearray[idx].nr_gpages;
229
230 if (nr_gpages == 0)
231 return 0;
232
233#ifdef CONFIG_HIGHMEM
234 /*
235 * If gpages can be in highmem we can't use the trick of storing the
236 * data structure in the page; allocate space for this
237 */
238 m = alloc_bootmem(sizeof(struct huge_bootmem_page));
239 m->phys = gpage_freearray[idx].gpage_list[--nr_gpages];
240#else
241 m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]);
242#endif
243
244 list_add(&m->list, &huge_boot_pages);
245 gpage_freearray[idx].nr_gpages = nr_gpages;
246 gpage_freearray[idx].gpage_list[nr_gpages] = 0;
247 m->hstate = hstate;
248
249 return 1;
250}
251/*
252 * Scan the command line hugepagesz= options for gigantic pages; store those in
253 * a list that we use to allocate the memory once all options are parsed.
254 */
255
256unsigned long gpage_npages[MMU_PAGE_COUNT];
257
258static int __init do_gpage_early_setup(char *param, char *val)
259{
260 static phys_addr_t size;
261 unsigned long npages;
262
263 /*
264 * The hugepagesz and hugepages cmdline options are interleaved. We
265 * use the size variable to keep track of whether or not this was done
266 * properly and skip over instances where it is incorrect. Other
267 * command-line parsing code will issue warnings, so we don't need to.
268 *
269 */
270 if ((strcmp(param, "default_hugepagesz") == 0) ||
271 (strcmp(param, "hugepagesz") == 0)) {
272 size = memparse(val, NULL);
273 } else if (strcmp(param, "hugepages") == 0) {
274 if (size != 0) {
275 if (sscanf(val, "%lu", &npages) <= 0)
276 npages = 0;
277 gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages;
278 size = 0;
279 }
280 }
281 return 0;
282}
283
284
285/*
286 * This function allocates physical space for pages that are larger than the
287 * buddy allocator can handle. We want to allocate these in highmem because
288 * the amount of lowmem is limited. This means that this function MUST be
289 * called before lowmem_end_addr is set up in MMU_init() in order for the lmb
290 * allocate to grab highmem.
291 */
292void __init reserve_hugetlb_gpages(void)
293{
294 static __initdata char cmdline[COMMAND_LINE_SIZE];
295 phys_addr_t size, base;
296 int i;
297
298 strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
299 parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup);
300
301 /*
302 * Walk gpage list in reverse, allocating larger page sizes first.
303 * Skip over unsupported sizes, or sizes that have 0 gpages allocated.
304 * When we reach the point in the list where pages are no longer
305 * considered gpages, we're done.
306 */
307 for (i = MMU_PAGE_COUNT-1; i >= 0; i--) {
308 if (mmu_psize_defs[i].shift == 0 || gpage_npages[i] == 0)
309 continue;
310 else if (mmu_psize_to_shift(i) < (MAX_ORDER + PAGE_SHIFT))
311 break;
312
313 size = (phys_addr_t)(1ULL << mmu_psize_to_shift(i));
314 base = memblock_alloc_base(size * gpage_npages[i], size,
315 MEMBLOCK_ALLOC_ANYWHERE);
316 add_gpage(base, size, gpage_npages[i]);
317 }
318}
319
320#else /* PPC64 */
321
322/* Build list of addresses of gigantic pages. This function is used in early
323 * boot before the buddy or bootmem allocator is setup.
324 */
325void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
177{ 326{
178 if (!addr) 327 if (!addr)
179 return; 328 return;
@@ -199,19 +348,79 @@ int alloc_bootmem_huge_page(struct hstate *hstate)
199 m->hstate = hstate; 348 m->hstate = hstate;
200 return 1; 349 return 1;
201} 350}
351#endif
202 352
203int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) 353int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
204{ 354{
205 return 0; 355 return 0;
206} 356}
207 357
358#ifdef CONFIG_PPC32
359#define HUGEPD_FREELIST_SIZE \
360 ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t))
361
362struct hugepd_freelist {
363 struct rcu_head rcu;
364 unsigned int index;
365 void *ptes[0];
366};
367
368static DEFINE_PER_CPU(struct hugepd_freelist *, hugepd_freelist_cur);
369
370static void hugepd_free_rcu_callback(struct rcu_head *head)
371{
372 struct hugepd_freelist *batch =
373 container_of(head, struct hugepd_freelist, rcu);
374 unsigned int i;
375
376 for (i = 0; i < batch->index; i++)
377 kmem_cache_free(hugepte_cache, batch->ptes[i]);
378
379 free_page((unsigned long)batch);
380}
381
382static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
383{
384 struct hugepd_freelist **batchp;
385
386 batchp = &__get_cpu_var(hugepd_freelist_cur);
387
388 if (atomic_read(&tlb->mm->mm_users) < 2 ||
389 cpumask_equal(mm_cpumask(tlb->mm),
390 cpumask_of(smp_processor_id()))) {
391 kmem_cache_free(hugepte_cache, hugepte);
392 return;
393 }
394
395 if (*batchp == NULL) {
396 *batchp = (struct hugepd_freelist *)__get_free_page(GFP_ATOMIC);
397 (*batchp)->index = 0;
398 }
399
400 (*batchp)->ptes[(*batchp)->index++] = hugepte;
401 if ((*batchp)->index == HUGEPD_FREELIST_SIZE) {
402 call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback);
403 *batchp = NULL;
404 }
405}
406#endif
407
208static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift, 408static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift,
209 unsigned long start, unsigned long end, 409 unsigned long start, unsigned long end,
210 unsigned long floor, unsigned long ceiling) 410 unsigned long floor, unsigned long ceiling)
211{ 411{
212 pte_t *hugepte = hugepd_page(*hpdp); 412 pte_t *hugepte = hugepd_page(*hpdp);
213 unsigned shift = hugepd_shift(*hpdp); 413 int i;
414
214 unsigned long pdmask = ~((1UL << pdshift) - 1); 415 unsigned long pdmask = ~((1UL << pdshift) - 1);
416 unsigned int num_hugepd = 1;
417
418#ifdef CONFIG_PPC64
419 unsigned int shift = hugepd_shift(*hpdp);
420#else
421 /* Note: On 32-bit the hpdp may be the first of several */
422 num_hugepd = (1 << (hugepd_shift(*hpdp) - pdshift));
423#endif
215 424
216 start &= pdmask; 425 start &= pdmask;
217 if (start < floor) 426 if (start < floor)
@@ -224,9 +433,15 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif
224 if (end - 1 > ceiling - 1) 433 if (end - 1 > ceiling - 1)
225 return; 434 return;
226 435
227 hpdp->pd = 0; 436 for (i = 0; i < num_hugepd; i++, hpdp++)
437 hpdp->pd = 0;
438
228 tlb->need_flush = 1; 439 tlb->need_flush = 1;
440#ifdef CONFIG_PPC64
229 pgtable_free_tlb(tlb, hugepte, pdshift - shift); 441 pgtable_free_tlb(tlb, hugepte, pdshift - shift);
442#else
443 hugepd_free(tlb, hugepte);
444#endif
230} 445}
231 446
232static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, 447static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
@@ -331,18 +546,27 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
331 * too. 546 * too.
332 */ 547 */
333 548
334 pgd = pgd_offset(tlb->mm, addr);
335 do { 549 do {
336 next = pgd_addr_end(addr, end); 550 next = pgd_addr_end(addr, end);
551 pgd = pgd_offset(tlb->mm, addr);
337 if (!is_hugepd(pgd)) { 552 if (!is_hugepd(pgd)) {
338 if (pgd_none_or_clear_bad(pgd)) 553 if (pgd_none_or_clear_bad(pgd))
339 continue; 554 continue;
340 hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); 555 hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
341 } else { 556 } else {
557#ifdef CONFIG_PPC32
558 /*
559 * Increment next by the size of the huge mapping since
560 * on 32-bit there may be more than one entry at the pgd
561 * level for a single hugepage, but all of them point to
562 * the same kmem cache that holds the hugepte.
563 */
564 next = addr + (1 << hugepd_shift(*(hugepd_t *)pgd));
565#endif
342 free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT, 566 free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT,
343 addr, next, floor, ceiling); 567 addr, next, floor, ceiling);
344 } 568 }
345 } while (pgd++, addr = next, addr != end); 569 } while (addr = next, addr != end);
346} 570}
347 571
348struct page * 572struct page *
@@ -477,17 +701,35 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
477 unsigned long len, unsigned long pgoff, 701 unsigned long len, unsigned long pgoff,
478 unsigned long flags) 702 unsigned long flags)
479{ 703{
704#ifdef CONFIG_PPC_MM_SLICES
480 struct hstate *hstate = hstate_file(file); 705 struct hstate *hstate = hstate_file(file);
481 int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); 706 int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
482 707
483 return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); 708 return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0);
709#else
710 return get_unmapped_area(file, addr, len, pgoff, flags);
711#endif
484} 712}
485 713
486unsigned long vma_mmu_pagesize(struct vm_area_struct *vma) 714unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
487{ 715{
716#ifdef CONFIG_PPC_MM_SLICES
488 unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start); 717 unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
489 718
490 return 1UL << mmu_psize_to_shift(psize); 719 return 1UL << mmu_psize_to_shift(psize);
720#else
721 if (!is_vm_hugetlb_page(vma))
722 return PAGE_SIZE;
723
724 return huge_page_size(hstate_vma(vma));
725#endif
726}
727
728static inline bool is_power_of_4(unsigned long x)
729{
730 if (is_power_of_2(x))
731 return (__ilog2(x) % 2) ? false : true;
732 return false;
491} 733}
492 734
493static int __init add_huge_page_size(unsigned long long size) 735static int __init add_huge_page_size(unsigned long long size)
@@ -497,9 +739,14 @@ static int __init add_huge_page_size(unsigned long long size)
497 739
498 /* Check that it is a page size supported by the hardware and 740 /* Check that it is a page size supported by the hardware and
499 * that it fits within pagetable and slice limits. */ 741 * that it fits within pagetable and slice limits. */
742#ifdef CONFIG_PPC_FSL_BOOK3E
743 if ((size < PAGE_SIZE) || !is_power_of_4(size))
744 return -EINVAL;
745#else
500 if (!is_power_of_2(size) 746 if (!is_power_of_2(size)
501 || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT)) 747 || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT))
502 return -EINVAL; 748 return -EINVAL;
749#endif
503 750
504 if ((mmu_psize = shift_to_mmu_psize(shift)) < 0) 751 if ((mmu_psize = shift_to_mmu_psize(shift)) < 0)
505 return -EINVAL; 752 return -EINVAL;
@@ -536,6 +783,46 @@ static int __init hugepage_setup_sz(char *str)
536} 783}
537__setup("hugepagesz=", hugepage_setup_sz); 784__setup("hugepagesz=", hugepage_setup_sz);
538 785
786#ifdef CONFIG_FSL_BOOKE
787struct kmem_cache *hugepte_cache;
788static int __init hugetlbpage_init(void)
789{
790 int psize;
791
792 for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
793 unsigned shift;
794
795 if (!mmu_psize_defs[psize].shift)
796 continue;
797
798 shift = mmu_psize_to_shift(psize);
799
800 /* Don't treat normal page sizes as huge... */
801 if (shift != PAGE_SHIFT)
802 if (add_huge_page_size(1ULL << shift) < 0)
803 continue;
804 }
805
806 /*
807 * Create a kmem cache for hugeptes. The bottom bits in the pte have
808 * size information encoded in them, so align them to allow this
809 */
810 hugepte_cache = kmem_cache_create("hugepte-cache", sizeof(pte_t),
811 HUGEPD_SHIFT_MASK + 1, 0, NULL);
812 if (hugepte_cache == NULL)
813 panic("%s: Unable to create kmem cache for hugeptes\n",
814 __func__);
815
816 /* Default hpage size = 4M */
817 if (mmu_psize_defs[MMU_PAGE_4M].shift)
818 HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift;
819 else
820 panic("%s: Unable to set default huge page size\n", __func__);
821
822
823 return 0;
824}
825#else
539static int __init hugetlbpage_init(void) 826static int __init hugetlbpage_init(void)
540{ 827{
541 int psize; 828 int psize;
@@ -578,15 +865,23 @@ static int __init hugetlbpage_init(void)
578 865
579 return 0; 866 return 0;
580} 867}
581 868#endif
582module_init(hugetlbpage_init); 869module_init(hugetlbpage_init);
583 870
584void flush_dcache_icache_hugepage(struct page *page) 871void flush_dcache_icache_hugepage(struct page *page)
585{ 872{
586 int i; 873 int i;
874 void *start;
587 875
588 BUG_ON(!PageCompound(page)); 876 BUG_ON(!PageCompound(page));
589 877
590 for (i = 0; i < (1UL << compound_order(page)); i++) 878 for (i = 0; i < (1UL << compound_order(page)); i++) {
591 __flush_dcache_icache(page_address(page+i)); 879 if (!PageHighMem(page)) {
880 __flush_dcache_icache(page_address(page+i));
881 } else {
882 start = kmap_atomic(page+i, KM_PPC_SYNC_ICACHE);
883 __flush_dcache_icache(start);
884 kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
885 }
886 }
592} 887}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index c77fef56dad6..161cefde5c15 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -32,6 +32,8 @@
32#include <linux/pagemap.h> 32#include <linux/pagemap.h>
33#include <linux/memblock.h> 33#include <linux/memblock.h>
34#include <linux/gfp.h> 34#include <linux/gfp.h>
35#include <linux/slab.h>
36#include <linux/hugetlb.h>
35 37
36#include <asm/pgalloc.h> 38#include <asm/pgalloc.h>
37#include <asm/prom.h> 39#include <asm/prom.h>
@@ -44,6 +46,7 @@
44#include <asm/tlb.h> 46#include <asm/tlb.h>
45#include <asm/sections.h> 47#include <asm/sections.h>
46#include <asm/system.h> 48#include <asm/system.h>
49#include <asm/hugetlb.h>
47 50
48#include "mmu_decl.h" 51#include "mmu_decl.h"
49 52
@@ -123,6 +126,12 @@ void __init MMU_init(void)
123 /* parse args from command line */ 126 /* parse args from command line */
124 MMU_setup(); 127 MMU_setup();
125 128
129 /*
130 * Reserve gigantic pages for hugetlb. This MUST occur before
131 * lowmem_end_addr is initialized below.
132 */
133 reserve_hugetlb_gpages();
134
126 if (memblock.memory.cnt > 1) { 135 if (memblock.memory.cnt > 1) {
127#ifndef CONFIG_WII 136#ifndef CONFIG_WII
128 memblock.memory.cnt = 1; 137 memblock.memory.cnt = 1;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c781bbcf7338..5db316cad47b 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -123,7 +123,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
123 pgdata = NODE_DATA(nid); 123 pgdata = NODE_DATA(nid);
124 124
125 start = (unsigned long)__va(start); 125 start = (unsigned long)__va(start);
126 create_section_mapping(start, start + size); 126 if (create_section_mapping(start, start + size))
127 return -EINVAL;
127 128
128 /* this should work for most non-highmem platforms */ 129 /* this should work for most non-highmem platforms */
129 zone = pgdata->node_zones; 130 zone = pgdata->node_zones;
@@ -548,4 +549,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
548 return; 549 return;
549 hash_preload(vma->vm_mm, address, access, trap); 550 hash_preload(vma->vm_mm, address, access, trap);
550#endif /* CONFIG_PPC_STD_MMU */ 551#endif /* CONFIG_PPC_STD_MMU */
552#if (defined(CONFIG_PPC_BOOK3E_64) || defined(CONFIG_PPC_FSL_BOOK3E)) \
553 && defined(CONFIG_HUGETLB_PAGE)
554 if (is_vm_hugetlb_page(vma))
555 book3e_hugetlb_preload(vma->vm_mm, address, *ptep);
556#endif
551} 557}
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 3bafc3deca6d..4ff587e38250 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -136,8 +136,8 @@ int use_cop(unsigned long acop, struct mm_struct *mm)
136 if (!mm || !acop) 136 if (!mm || !acop)
137 return -EINVAL; 137 return -EINVAL;
138 138
139 /* We need to make sure mm_users doesn't change */ 139 /* The page_table_lock ensures mm_users won't change under us */
140 down_read(&mm->mmap_sem); 140 spin_lock(&mm->page_table_lock);
141 spin_lock(mm->context.cop_lockp); 141 spin_lock(mm->context.cop_lockp);
142 142
143 if (mm->context.cop_pid == COP_PID_NONE) { 143 if (mm->context.cop_pid == COP_PID_NONE) {
@@ -164,7 +164,7 @@ int use_cop(unsigned long acop, struct mm_struct *mm)
164 164
165out: 165out:
166 spin_unlock(mm->context.cop_lockp); 166 spin_unlock(mm->context.cop_lockp);
167 up_read(&mm->mmap_sem); 167 spin_unlock(&mm->page_table_lock);
168 168
169 return ret; 169 return ret;
170} 170}
@@ -185,8 +185,8 @@ void drop_cop(unsigned long acop, struct mm_struct *mm)
185 if (WARN_ON_ONCE(!mm)) 185 if (WARN_ON_ONCE(!mm))
186 return; 186 return;
187 187
188 /* We need to make sure mm_users doesn't change */ 188 /* The page_table_lock ensures mm_users won't change under us */
189 down_read(&mm->mmap_sem); 189 spin_lock(&mm->page_table_lock);
190 spin_lock(mm->context.cop_lockp); 190 spin_lock(mm->context.cop_lockp);
191 191
192 mm->context.acop &= ~acop; 192 mm->context.acop &= ~acop;
@@ -213,7 +213,7 @@ void drop_cop(unsigned long acop, struct mm_struct *mm)
213 } 213 }
214 214
215 spin_unlock(mm->context.cop_lockp); 215 spin_unlock(mm->context.cop_lockp);
216 up_read(&mm->mmap_sem); 216 spin_unlock(&mm->page_table_lock);
217} 217}
218EXPORT_SYMBOL_GPL(drop_cop); 218EXPORT_SYMBOL_GPL(drop_cop);
219 219
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 336807de550e..5b63bd3da4a9 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -292,6 +292,11 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
292 mm->context.id = MMU_NO_CONTEXT; 292 mm->context.id = MMU_NO_CONTEXT;
293 mm->context.active = 0; 293 mm->context.active = 0;
294 294
295#ifdef CONFIG_PPC_MM_SLICES
296 if (slice_mm_new_context(mm))
297 slice_set_user_psize(mm, mmu_virtual_psize);
298#endif
299
295 return 0; 300 return 0;
296} 301}
297 302
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index dd0a2589591d..83eb5d5f53d5 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -142,6 +142,8 @@ extern unsigned long mmu_mapin_ram(unsigned long top);
142 142
143#elif defined(CONFIG_PPC_FSL_BOOK3E) 143#elif defined(CONFIG_PPC_FSL_BOOK3E)
144extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); 144extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
145extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
146 phys_addr_t phys);
145#ifdef CONFIG_PPC32 147#ifdef CONFIG_PPC32
146extern void MMU_init_hw(void); 148extern void MMU_init_hw(void);
147extern unsigned long mmu_mapin_ram(unsigned long top); 149extern unsigned long mmu_mapin_ram(unsigned long top);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 2164006fe170..0bfb90c50571 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -709,8 +709,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
709 709
710static int __init parse_numa_properties(void) 710static int __init parse_numa_properties(void)
711{ 711{
712 struct device_node *cpu = NULL; 712 struct device_node *memory;
713 struct device_node *memory = NULL;
714 int default_nid = 0; 713 int default_nid = 0;
715 unsigned long i; 714 unsigned long i;
716 715
@@ -732,6 +731,7 @@ static int __init parse_numa_properties(void)
732 * each node to be onlined must have NODE_DATA etc backing it. 731 * each node to be onlined must have NODE_DATA etc backing it.
733 */ 732 */
734 for_each_present_cpu(i) { 733 for_each_present_cpu(i) {
734 struct device_node *cpu;
735 int nid; 735 int nid;
736 736
737 cpu = of_get_cpu_node(i, NULL); 737 cpu = of_get_cpu_node(i, NULL);
@@ -750,8 +750,8 @@ static int __init parse_numa_properties(void)
750 } 750 }
751 751
752 get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); 752 get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
753 memory = NULL; 753
754 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 754 for_each_node_by_type(memory, "memory") {
755 unsigned long start; 755 unsigned long start;
756 unsigned long size; 756 unsigned long size;
757 int nid; 757 int nid;
@@ -800,8 +800,9 @@ new_range:
800 } 800 }
801 801
802 /* 802 /*
803 * Now do the same thing for each MEMBLOCK listed in the ibm,dynamic-memory 803 * Now do the same thing for each MEMBLOCK listed in the
804 * property in the ibm,dynamic-reconfiguration-memory node. 804 * ibm,dynamic-memory property in the
805 * ibm,dynamic-reconfiguration-memory node.
805 */ 806 */
806 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 807 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
807 if (memory) 808 if (memory)
@@ -1187,10 +1188,10 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
1187 */ 1188 */
1188int hot_add_node_scn_to_nid(unsigned long scn_addr) 1189int hot_add_node_scn_to_nid(unsigned long scn_addr)
1189{ 1190{
1190 struct device_node *memory = NULL; 1191 struct device_node *memory;
1191 int nid = -1; 1192 int nid = -1;
1192 1193
1193 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 1194 for_each_node_by_type(memory, "memory") {
1194 unsigned long start, size; 1195 unsigned long start, size;
1195 int ranges; 1196 int ranges;
1196 const unsigned int *memcell_buf; 1197 const unsigned int *memcell_buf;
@@ -1214,11 +1215,12 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr)
1214 break; 1215 break;
1215 } 1216 }
1216 1217
1217 of_node_put(memory);
1218 if (nid >= 0) 1218 if (nid >= 0)
1219 break; 1219 break;
1220 } 1220 }
1221 1221
1222 of_node_put(memory);
1223
1222 return nid; 1224 return nid;
1223} 1225}
1224 1226
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index af40c8768a78..214130a4edc6 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/percpu.h> 28#include <linux/percpu.h>
29#include <linux/hardirq.h> 29#include <linux/hardirq.h>
30#include <linux/hugetlb.h>
30#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
31#include <asm/tlbflush.h> 32#include <asm/tlbflush.h>
32#include <asm/tlb.h> 33#include <asm/tlb.h>
@@ -212,7 +213,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
212 entry = set_access_flags_filter(entry, vma, dirty); 213 entry = set_access_flags_filter(entry, vma, dirty);
213 changed = !pte_same(*(ptep), entry); 214 changed = !pte_same(*(ptep), entry);
214 if (changed) { 215 if (changed) {
215 if (!(vma->vm_flags & VM_HUGETLB)) 216 if (!is_vm_hugetlb_page(vma))
216 assert_pte_locked(vma->vm_mm, address); 217 assert_pte_locked(vma->vm_mm, address);
217 __ptep_set_access_flags(ptep, entry); 218 __ptep_set_access_flags(ptep, entry);
218 flush_tlb_page_nohash(vma, address); 219 flush_tlb_page_nohash(vma, address);
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 4ebb34bc01d6..dc4a5f385e41 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -553,24 +553,24 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
553 rldicl r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3 553 rldicl r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3
554 clrrdi r10,r11,3 554 clrrdi r10,r11,3
555 ldx r15,r10,r15 555 ldx r15,r10,r15
556 cmpldi cr0,r15,0 556 cmpdi cr0,r15,0
557 beq virt_page_table_tlb_miss_fault 557 bge virt_page_table_tlb_miss_fault
558 558
559#ifndef CONFIG_PPC_64K_PAGES 559#ifndef CONFIG_PPC_64K_PAGES
560 /* Get to PUD entry */ 560 /* Get to PUD entry */
561 rldicl r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3 561 rldicl r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3
562 clrrdi r10,r11,3 562 clrrdi r10,r11,3
563 ldx r15,r10,r15 563 ldx r15,r10,r15
564 cmpldi cr0,r15,0 564 cmpdi cr0,r15,0
565 beq virt_page_table_tlb_miss_fault 565 bge virt_page_table_tlb_miss_fault
566#endif /* CONFIG_PPC_64K_PAGES */ 566#endif /* CONFIG_PPC_64K_PAGES */
567 567
568 /* Get to PMD entry */ 568 /* Get to PMD entry */
569 rldicl r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3 569 rldicl r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3
570 clrrdi r10,r11,3 570 clrrdi r10,r11,3
571 ldx r15,r10,r15 571 ldx r15,r10,r15
572 cmpldi cr0,r15,0 572 cmpdi cr0,r15,0
573 beq virt_page_table_tlb_miss_fault 573 bge virt_page_table_tlb_miss_fault
574 574
575 /* Ok, we're all right, we can now create a kernel translation for 575 /* Ok, we're all right, we can now create a kernel translation for
576 * a 4K or 64K page from r16 -> r15. 576 * a 4K or 64K page from r16 -> r15.
@@ -802,24 +802,24 @@ htw_tlb_miss:
802 rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3 802 rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
803 clrrdi r10,r11,3 803 clrrdi r10,r11,3
804 ldx r15,r10,r15 804 ldx r15,r10,r15
805 cmpldi cr0,r15,0 805 cmpdi cr0,r15,0
806 beq htw_tlb_miss_fault 806 bge htw_tlb_miss_fault
807 807
808#ifndef CONFIG_PPC_64K_PAGES 808#ifndef CONFIG_PPC_64K_PAGES
809 /* Get to PUD entry */ 809 /* Get to PUD entry */
810 rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3 810 rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
811 clrrdi r10,r11,3 811 clrrdi r10,r11,3
812 ldx r15,r10,r15 812 ldx r15,r10,r15
813 cmpldi cr0,r15,0 813 cmpdi cr0,r15,0
814 beq htw_tlb_miss_fault 814 bge htw_tlb_miss_fault
815#endif /* CONFIG_PPC_64K_PAGES */ 815#endif /* CONFIG_PPC_64K_PAGES */
816 816
817 /* Get to PMD entry */ 817 /* Get to PMD entry */
818 rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3 818 rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
819 clrrdi r10,r11,3 819 clrrdi r10,r11,3
820 ldx r15,r10,r15 820 ldx r15,r10,r15
821 cmpldi cr0,r15,0 821 cmpdi cr0,r15,0
822 beq htw_tlb_miss_fault 822 bge htw_tlb_miss_fault
823 823
824 /* Ok, we're all right, we can now create an indirect entry for 824 /* Ok, we're all right, we can now create an indirect entry for
825 * a 1M or 256M page. 825 * a 1M or 256M page.
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index d32ec643c231..6c2eabf707b7 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -36,14 +36,49 @@
36#include <linux/spinlock.h> 36#include <linux/spinlock.h>
37#include <linux/memblock.h> 37#include <linux/memblock.h>
38#include <linux/of_fdt.h> 38#include <linux/of_fdt.h>
39#include <linux/hugetlb.h>
39 40
40#include <asm/tlbflush.h> 41#include <asm/tlbflush.h>
41#include <asm/tlb.h> 42#include <asm/tlb.h>
42#include <asm/code-patching.h> 43#include <asm/code-patching.h>
44#include <asm/hugetlb.h>
43 45
44#include "mmu_decl.h" 46#include "mmu_decl.h"
45 47
46#ifdef CONFIG_PPC_BOOK3E 48/*
49 * This struct lists the sw-supported page sizes. The hardawre MMU may support
50 * other sizes not listed here. The .ind field is only used on MMUs that have
51 * indirect page table entries.
52 */
53#ifdef CONFIG_PPC_BOOK3E_MMU
54#ifdef CONFIG_FSL_BOOKE
55struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
56 [MMU_PAGE_4K] = {
57 .shift = 12,
58 .enc = BOOK3E_PAGESZ_4K,
59 },
60 [MMU_PAGE_4M] = {
61 .shift = 22,
62 .enc = BOOK3E_PAGESZ_4M,
63 },
64 [MMU_PAGE_16M] = {
65 .shift = 24,
66 .enc = BOOK3E_PAGESZ_16M,
67 },
68 [MMU_PAGE_64M] = {
69 .shift = 26,
70 .enc = BOOK3E_PAGESZ_64M,
71 },
72 [MMU_PAGE_256M] = {
73 .shift = 28,
74 .enc = BOOK3E_PAGESZ_256M,
75 },
76 [MMU_PAGE_1G] = {
77 .shift = 30,
78 .enc = BOOK3E_PAGESZ_1GB,
79 },
80};
81#else
47struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { 82struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
48 [MMU_PAGE_4K] = { 83 [MMU_PAGE_4K] = {
49 .shift = 12, 84 .shift = 12,
@@ -77,6 +112,8 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
77 .enc = BOOK3E_PAGESZ_1GB, 112 .enc = BOOK3E_PAGESZ_1GB,
78 }, 113 },
79}; 114};
115#endif /* CONFIG_FSL_BOOKE */
116
80static inline int mmu_get_tsize(int psize) 117static inline int mmu_get_tsize(int psize)
81{ 118{
82 return mmu_psize_defs[psize].enc; 119 return mmu_psize_defs[psize].enc;
@@ -87,7 +124,7 @@ static inline int mmu_get_tsize(int psize)
87 /* This isn't used on !Book3E for now */ 124 /* This isn't used on !Book3E for now */
88 return 0; 125 return 0;
89} 126}
90#endif 127#endif /* CONFIG_PPC_BOOK3E_MMU */
91 128
92/* The variables below are currently only used on 64-bit Book3E 129/* The variables below are currently only used on 64-bit Book3E
93 * though this will probably be made common with other nohash 130 * though this will probably be made common with other nohash
@@ -266,6 +303,11 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
266 303
267void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) 304void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
268{ 305{
306#ifdef CONFIG_HUGETLB_PAGE
307 if (is_vm_hugetlb_page(vma))
308 flush_hugetlb_page(vma, vmaddr);
309#endif
310
269 __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, 311 __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr,
270 mmu_get_tsize(mmu_virtual_psize), 0); 312 mmu_get_tsize(mmu_virtual_psize), 0);
271} 313}
@@ -600,13 +642,28 @@ void __cpuinit early_init_mmu_secondary(void)
600void setup_initial_memory_limit(phys_addr_t first_memblock_base, 642void setup_initial_memory_limit(phys_addr_t first_memblock_base,
601 phys_addr_t first_memblock_size) 643 phys_addr_t first_memblock_size)
602{ 644{
603 /* On Embedded 64-bit, we adjust the RMA size to match 645 /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
604 * the bolted TLB entry. We know for now that only 1G 646 * the bolted TLB entry. We know for now that only 1G
605 * entries are supported though that may eventually 647 * entries are supported though that may eventually
606 * change. We crop it to the size of the first MEMBLOCK to 648 * change.
649 *
650 * on FSL Embedded 64-bit, we adjust the RMA size to match the
651 * first bolted TLB entry size. We still limit max to 1G even if
652 * the TLB could cover more. This is due to what the early init
653 * code is setup to do.
654 *
655 * We crop it to the size of the first MEMBLOCK to
607 * avoid going over total available memory just in case... 656 * avoid going over total available memory just in case...
608 */ 657 */
609 ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); 658#ifdef CONFIG_PPC_FSL_BOOK3E
659 if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
660 unsigned long linear_sz;
661 linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET,
662 first_memblock_base);
663 ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
664 } else
665#endif
666 ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
610 667
611 /* Finally limit subsequent allocations */ 668 /* Finally limit subsequent allocations */
612 memblock_set_current_limit(first_memblock_base + ppc64_rma_size); 669 memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index b5d87067a58b..8f9c3e245cff 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -32,14 +32,6 @@ config EP405
32 help 32 help
33 This option enables support for the EP405/EP405PC boards. 33 This option enables support for the EP405/EP405PC boards.
34 34
35config HCU4
36 bool "Hcu4"
37 depends on 40x
38 default n
39 select 405GPR
40 help
41 This option enables support for the Nestal Maschinen HCU4 board.
42
43config HOTFOOT 35config HOTFOOT
44 bool "Hotfoot" 36 bool "Hotfoot"
45 depends on 40x 37 depends on 40x
diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile
index 56e89004c468..88c22de0c850 100644
--- a/arch/powerpc/platforms/40x/Makefile
+++ b/arch/powerpc/platforms/40x/Makefile
@@ -1,4 +1,3 @@
1obj-$(CONFIG_HCU4) += hcu4.o
2obj-$(CONFIG_WALNUT) += walnut.o 1obj-$(CONFIG_WALNUT) += walnut.o
3obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o 2obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o
4obj-$(CONFIG_EP405) += ep405.o 3obj-$(CONFIG_EP405) += ep405.o
diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c
deleted file mode 100644
index 60b2afecab75..000000000000
--- a/arch/powerpc/platforms/40x/hcu4.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 * Architecture- / platform-specific boot-time initialization code for
3 * IBM PowerPC 4xx based boards. Adapted from original
4 * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
5 * <dan@net4x.com>.
6 *
7 * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
8 *
9 * Rewritten and ported to the merged powerpc tree:
10 * Copyright 2007 IBM Corporation
11 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
12 *
13 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
14 * the terms of the GNU General Public License version 2. This program
15 * is licensed "as is" without any warranty of any kind, whether express
16 * or implied.
17 */
18
19#include <linux/init.h>
20#include <linux/of_platform.h>
21
22#include <asm/machdep.h>
23#include <asm/prom.h>
24#include <asm/udbg.h>
25#include <asm/time.h>
26#include <asm/uic.h>
27#include <asm/ppc4xx.h>
28
29static __initdata struct of_device_id hcu4_of_bus[] = {
30 { .compatible = "ibm,plb3", },
31 { .compatible = "ibm,opb", },
32 { .compatible = "ibm,ebc", },
33 {},
34};
35
36static int __init hcu4_device_probe(void)
37{
38 of_platform_bus_probe(NULL, hcu4_of_bus, NULL);
39 return 0;
40}
41machine_device_initcall(hcu4, hcu4_device_probe);
42
43static int __init hcu4_probe(void)
44{
45 unsigned long root = of_get_flat_dt_root();
46
47 if (!of_flat_dt_is_compatible(root, "netstal,hcu4"))
48 return 0;
49
50 return 1;
51}
52
53define_machine(hcu4) {
54 .name = "HCU4",
55 .probe = hcu4_probe,
56 .progress = udbg_progress,
57 .init_IRQ = uic_init_tree,
58 .get_irq = uic_get_irq,
59 .restart = ppc4xx_reset_system,
60 .calibrate_decr = generic_calibrate_decr,
61};
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 27b0651221d1..b3ebce1aec07 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -6,6 +6,7 @@ config PPC_MPC512x
6 select PPC_CLOCK 6 select PPC_CLOCK
7 select PPC_PCI_CHOICE 7 select PPC_PCI_CHOICE
8 select FSL_PCI if PCI 8 select FSL_PCI if PCI
9 select ARCH_WANT_OPTIONAL_GPIOLIB
9 10
10config MPC5121_ADS 11config MPC5121_ADS
11 bool "Freescale MPC5121E ADS" 12 bool "Freescale MPC5121E ADS"
diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c
index 428c5e0a0e75..3661bcdc326a 100644
--- a/arch/powerpc/platforms/82xx/km82xx.c
+++ b/arch/powerpc/platforms/82xx/km82xx.c
@@ -49,6 +49,9 @@ struct cpm_pin {
49}; 49};
50 50
51static __initdata struct cpm_pin km82xx_pins[] = { 51static __initdata struct cpm_pin km82xx_pins[] = {
52 /* SMC1 */
53 {2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
54 {2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
52 55
53 /* SMC2 */ 56 /* SMC2 */
54 {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 57 {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
@@ -137,6 +140,7 @@ static void __init init_ioports(void)
137 } 140 }
138 141
139 cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8); 142 cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
143 cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7);
140 cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX); 144 cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX);
141 cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX); 145 cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX);
142 cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX); 146 cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX);
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 73f4135f3a1a..670a033264c0 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -114,18 +114,21 @@ config KMETER1
114 114
115endif 115endif
116 116
117# used for usb 117# used for usb & gpio
118config PPC_MPC831x 118config PPC_MPC831x
119 bool 119 bool
120 select ARCH_WANT_OPTIONAL_GPIOLIB
120 121
121# used for math-emu 122# used for math-emu
122config PPC_MPC832x 123config PPC_MPC832x
123 bool 124 bool
124 125
125# used for usb 126# used for usb & gpio
126config PPC_MPC834x 127config PPC_MPC834x
127 bool 128 bool
129 select ARCH_WANT_OPTIONAL_GPIOLIB
128 130
129# used for usb 131# used for usb & gpio
130config PPC_MPC837x 132config PPC_MPC837x
131 bool 133 bool
134 select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
index 70798ac911ef..ef6537b8ed33 100644
--- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
+++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
@@ -21,6 +21,8 @@
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_gpio.h> 22#include <linux/of_gpio.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/kthread.h>
25#include <linux/reboot.h>
24#include <asm/prom.h> 26#include <asm/prom.h>
25#include <asm/machdep.h> 27#include <asm/machdep.h>
26 28
@@ -30,6 +32,7 @@
30 */ 32 */
31#define MCU_REG_CTRL 0x20 33#define MCU_REG_CTRL 0x20
32#define MCU_CTRL_POFF 0x40 34#define MCU_CTRL_POFF 0x40
35#define MCU_CTRL_BTN 0x80
33 36
34#define MCU_NUM_GPIO 2 37#define MCU_NUM_GPIO 2
35 38
@@ -42,13 +45,55 @@ struct mcu {
42 45
43static struct mcu *glob_mcu; 46static struct mcu *glob_mcu;
44 47
48struct task_struct *shutdown_thread;
49static int shutdown_thread_fn(void *data)
50{
51 int ret;
52 struct mcu *mcu = glob_mcu;
53
54 while (!kthread_should_stop()) {
55 ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
56 if (ret < 0)
57 pr_err("MCU status reg read failed.\n");
58 mcu->reg_ctrl = ret;
59
60
61 if (mcu->reg_ctrl & MCU_CTRL_BTN) {
62 i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL,
63 mcu->reg_ctrl & ~MCU_CTRL_BTN);
64
65 ctrl_alt_del();
66 }
67
68 set_current_state(TASK_INTERRUPTIBLE);
69 schedule_timeout(HZ);
70 }
71
72 return 0;
73}
74
75static ssize_t show_status(struct device *d,
76 struct device_attribute *attr, char *buf)
77{
78 int ret;
79 struct mcu *mcu = glob_mcu;
80
81 ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
82 if (ret < 0)
83 return -ENODEV;
84 mcu->reg_ctrl = ret;
85
86 return sprintf(buf, "%02x\n", ret);
87}
88static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
89
45static void mcu_power_off(void) 90static void mcu_power_off(void)
46{ 91{
47 struct mcu *mcu = glob_mcu; 92 struct mcu *mcu = glob_mcu;
48 93
49 pr_info("Sending power-off request to the MCU...\n"); 94 pr_info("Sending power-off request to the MCU...\n");
50 mutex_lock(&mcu->lock); 95 mutex_lock(&mcu->lock);
51 i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, 96 i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL,
52 mcu->reg_ctrl | MCU_CTRL_POFF); 97 mcu->reg_ctrl | MCU_CTRL_POFF);
53 mutex_unlock(&mcu->lock); 98 mutex_unlock(&mcu->lock);
54} 99}
@@ -130,6 +175,13 @@ static int __devinit mcu_probe(struct i2c_client *client,
130 dev_info(&client->dev, "will provide power-off service\n"); 175 dev_info(&client->dev, "will provide power-off service\n");
131 } 176 }
132 177
178 if (device_create_file(&client->dev, &dev_attr_status))
179 dev_err(&client->dev,
180 "couldn't create device file for status\n");
181
182 shutdown_thread = kthread_run(shutdown_thread_fn, NULL,
183 "mcu-i2c-shdn");
184
133 return 0; 185 return 0;
134err: 186err:
135 kfree(mcu); 187 kfree(mcu);
@@ -141,6 +193,10 @@ static int __devexit mcu_remove(struct i2c_client *client)
141 struct mcu *mcu = i2c_get_clientdata(client); 193 struct mcu *mcu = i2c_get_clientdata(client);
142 int ret; 194 int ret;
143 195
196 kthread_stop(shutdown_thread);
197
198 device_remove_file(&client->dev, &dev_attr_status);
199
144 if (glob_mcu == mcu) { 200 if (glob_mcu == mcu) {
145 ppc_md.power_off = NULL; 201 ppc_md.power_off = NULL;
146 glob_mcu = NULL; 202 glob_mcu = NULL;
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 12f5932dadc9..45023e26aea3 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -171,17 +171,18 @@ config SBC8560
171 help 171 help
172 This option enables support for the Wind River SBC8560 board 172 This option enables support for the Wind River SBC8560 board
173 173
174config P2040_RDB 174config P2041_RDB
175 bool "Freescale P2040 RDB" 175 bool "Freescale P2041 RDB"
176 select DEFAULT_UIMAGE 176 select DEFAULT_UIMAGE
177 select PPC_E500MC 177 select PPC_E500MC
178 select PHYS_64BIT 178 select PHYS_64BIT
179 select SWIOTLB 179 select SWIOTLB
180 select MPC8xxx_GPIO 180 select ARCH_REQUIRE_GPIOLIB
181 select GPIO_MPC8XXX
181 select HAS_RAPIDIO 182 select HAS_RAPIDIO
182 select PPC_EPAPR_HV_PIC 183 select PPC_EPAPR_HV_PIC
183 help 184 help
184 This option enables support for the P2040 RDB board 185 This option enables support for the P2041 RDB board
185 186
186config P3041_DS 187config P3041_DS
187 bool "Freescale P3041 DS" 188 bool "Freescale P3041 DS"
@@ -189,19 +190,33 @@ config P3041_DS
189 select PPC_E500MC 190 select PPC_E500MC
190 select PHYS_64BIT 191 select PHYS_64BIT
191 select SWIOTLB 192 select SWIOTLB
192 select MPC8xxx_GPIO 193 select ARCH_REQUIRE_GPIOLIB
194 select GPIO_MPC8XXX
193 select HAS_RAPIDIO 195 select HAS_RAPIDIO
194 select PPC_EPAPR_HV_PIC 196 select PPC_EPAPR_HV_PIC
195 help 197 help
196 This option enables support for the P3041 DS board 198 This option enables support for the P3041 DS board
197 199
200config P3060_QDS
201 bool "Freescale P3060 QDS"
202 select DEFAULT_UIMAGE
203 select PPC_E500MC
204 select PHYS_64BIT
205 select SWIOTLB
206 select MPC8xxx_GPIO
207 select HAS_RAPIDIO
208 select PPC_EPAPR_HV_PIC
209 help
210 This option enables support for the P3060 QDS board
211
198config P4080_DS 212config P4080_DS
199 bool "Freescale P4080 DS" 213 bool "Freescale P4080 DS"
200 select DEFAULT_UIMAGE 214 select DEFAULT_UIMAGE
201 select PPC_E500MC 215 select PPC_E500MC
202 select PHYS_64BIT 216 select PHYS_64BIT
203 select SWIOTLB 217 select SWIOTLB
204 select MPC8xxx_GPIO 218 select ARCH_REQUIRE_GPIOLIB
219 select GPIO_MPC8XXX
205 select HAS_RAPIDIO 220 select HAS_RAPIDIO
206 select PPC_EPAPR_HV_PIC 221 select PPC_EPAPR_HV_PIC
207 help 222 help
@@ -216,7 +231,8 @@ config P5020_DS
216 select PPC_E500MC 231 select PPC_E500MC
217 select PHYS_64BIT 232 select PHYS_64BIT
218 select SWIOTLB 233 select SWIOTLB
219 select MPC8xxx_GPIO 234 select ARCH_REQUIRE_GPIOLIB
235 select GPIO_MPC8XXX
220 select HAS_RAPIDIO 236 select HAS_RAPIDIO
221 select PPC_EPAPR_HV_PIC 237 select PPC_EPAPR_HV_PIC
222 help 238 help
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index a971b32c5c0a..bc5acb95917a 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -13,8 +13,9 @@ obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
13obj-$(CONFIG_P1010_RDB) += p1010rdb.o 13obj-$(CONFIG_P1010_RDB) += p1010rdb.o
14obj-$(CONFIG_P1022_DS) += p1022_ds.o 14obj-$(CONFIG_P1022_DS) += p1022_ds.o
15obj-$(CONFIG_P1023_RDS) += p1023_rds.o 15obj-$(CONFIG_P1023_RDS) += p1023_rds.o
16obj-$(CONFIG_P2040_RDB) += p2040_rdb.o corenet_ds.o 16obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o
17obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o 17obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o
18obj-$(CONFIG_P3060_QDS) += p3060_qds.o corenet_ds.o
18obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o 19obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
19obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o 20obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o
20obj-$(CONFIG_STX_GP3) += stx_gp3.o 21obj-$(CONFIG_STX_GP3) += stx_gp3.o
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index c01c7277888c..fda15716fada 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -129,17 +129,20 @@ static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
129 */ 129 */
130static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) 130static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
131{ 131{
132 struct device_node *pixis_node; 132 struct device_node *np;
133 void __iomem *pixis; 133 void __iomem *pixis;
134 u8 __iomem *brdcfg1; 134 u8 __iomem *brdcfg1;
135 135
136 pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis"); 136 np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga");
137 if (!pixis_node) { 137 if (!np)
138 /* older device trees used "fsl,p1022ds-pixis" */
139 np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis");
140 if (!np) {
138 pr_err("p1022ds: missing ngPIXIS node\n"); 141 pr_err("p1022ds: missing ngPIXIS node\n");
139 return; 142 return;
140 } 143 }
141 144
142 pixis = of_iomap(pixis_node, 0); 145 pixis = of_iomap(np, 0);
143 if (!pixis) { 146 if (!pixis) {
144 pr_err("p1022ds: could not map ngPIXIS registers\n"); 147 pr_err("p1022ds: could not map ngPIXIS registers\n");
145 return; 148 return;
diff --git a/arch/powerpc/platforms/85xx/p2040_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c
index 32b56ac73dfb..eda6ed5683e1 100644
--- a/arch/powerpc/platforms/85xx/p2040_rdb.c
+++ b/arch/powerpc/platforms/85xx/p2041_rdb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * P2040 RDB Setup 2 * P2041 RDB Setup
3 * 3 *
4 * Copyright 2011 Freescale Semiconductor Inc. 4 * Copyright 2011 Freescale Semiconductor Inc.
5 * 5 *
@@ -35,18 +35,18 @@
35/* 35/*
36 * Called very early, device-tree isn't unflattened 36 * Called very early, device-tree isn't unflattened
37 */ 37 */
38static int __init p2040_rdb_probe(void) 38static int __init p2041_rdb_probe(void)
39{ 39{
40 unsigned long root = of_get_flat_dt_root(); 40 unsigned long root = of_get_flat_dt_root();
41#ifdef CONFIG_SMP 41#ifdef CONFIG_SMP
42 extern struct smp_ops_t smp_85xx_ops; 42 extern struct smp_ops_t smp_85xx_ops;
43#endif 43#endif
44 44
45 if (of_flat_dt_is_compatible(root, "fsl,P2040RDB")) 45 if (of_flat_dt_is_compatible(root, "fsl,P2041RDB"))
46 return 1; 46 return 1;
47 47
48 /* Check if we're running under the Freescale hypervisor */ 48 /* Check if we're running under the Freescale hypervisor */
49 if (of_flat_dt_is_compatible(root, "fsl,P2040RDB-hv")) { 49 if (of_flat_dt_is_compatible(root, "fsl,P2041RDB-hv")) {
50 ppc_md.init_IRQ = ehv_pic_init; 50 ppc_md.init_IRQ = ehv_pic_init;
51 ppc_md.get_irq = ehv_pic_get_irq; 51 ppc_md.get_irq = ehv_pic_get_irq;
52 ppc_md.restart = fsl_hv_restart; 52 ppc_md.restart = fsl_hv_restart;
@@ -66,9 +66,9 @@ static int __init p2040_rdb_probe(void)
66 return 0; 66 return 0;
67} 67}
68 68
69define_machine(p2040_rdb) { 69define_machine(p2041_rdb) {
70 .name = "P2040 RDB", 70 .name = "P2041 RDB",
71 .probe = p2040_rdb_probe, 71 .probe = p2041_rdb_probe,
72 .setup_arch = corenet_ds_setup_arch, 72 .setup_arch = corenet_ds_setup_arch,
73 .init_IRQ = corenet_ds_pic_init, 73 .init_IRQ = corenet_ds_pic_init,
74#ifdef CONFIG_PCI 74#ifdef CONFIG_PCI
@@ -81,8 +81,8 @@ define_machine(p2040_rdb) {
81 .power_save = e500_idle, 81 .power_save = e500_idle,
82}; 82};
83 83
84machine_device_initcall(p2040_rdb, corenet_ds_publish_devices); 84machine_device_initcall(p2041_rdb, corenet_ds_publish_devices);
85 85
86#ifdef CONFIG_SWIOTLB 86#ifdef CONFIG_SWIOTLB
87machine_arch_initcall(p2040_rdb, swiotlb_setup_bus_notifier); 87machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier);
88#endif 88#endif
diff --git a/arch/powerpc/platforms/85xx/p3060_qds.c b/arch/powerpc/platforms/85xx/p3060_qds.c
new file mode 100644
index 000000000000..01dcf44871e9
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p3060_qds.c
@@ -0,0 +1,77 @@
1/*
2 * P3060 QDS Setup
3 *
4 * Copyright 2011 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/interrupt.h>
14#include <linux/phy.h>
15#include <asm/machdep.h>
16#include <asm/udbg.h>
17#include <asm/mpic.h>
18#include <linux/of_platform.h>
19#include <sysdev/fsl_soc.h>
20#include <sysdev/fsl_pci.h>
21#include <asm/ehv_pic.h>
22#include "corenet_ds.h"
23
24/*
25 * Called very early, device-tree isn't unflattened
26 */
27static int __init p3060_qds_probe(void)
28{
29 unsigned long root = of_get_flat_dt_root();
30#ifdef CONFIG_SMP
31 extern struct smp_ops_t smp_85xx_ops;
32#endif
33
34 if (of_flat_dt_is_compatible(root, "fsl,P3060QDS"))
35 return 1;
36
37 /* Check if we're running under the Freescale hypervisor */
38 if (of_flat_dt_is_compatible(root, "fsl,P3060QDS-hv")) {
39 ppc_md.init_IRQ = ehv_pic_init;
40 ppc_md.get_irq = ehv_pic_get_irq;
41 ppc_md.restart = fsl_hv_restart;
42 ppc_md.power_off = fsl_hv_halt;
43 ppc_md.halt = fsl_hv_halt;
44#ifdef CONFIG_SMP
45 /*
46 * Disable the timebase sync operations because we can't write
47 * to the timebase registers under the hypervisor.
48 */
49 smp_85xx_ops.give_timebase = NULL;
50 smp_85xx_ops.take_timebase = NULL;
51#endif
52 return 1;
53 }
54
55 return 0;
56}
57
58define_machine(p3060_qds) {
59 .name = "P3060 QDS",
60 .probe = p3060_qds_probe,
61 .setup_arch = corenet_ds_setup_arch,
62 .init_IRQ = corenet_ds_pic_init,
63#ifdef CONFIG_PCI
64 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
65#endif
66 .get_irq = mpic_get_coreint_irq,
67 .restart = fsl_rstcr_restart,
68 .calibrate_decr = generic_calibrate_decr,
69 .progress = udbg_progress,
70 .power_save = e500_idle,
71};
72
73machine_device_initcall(p3060_qds, declare_of_platform_devices);
74
75#ifdef CONFIG_SWIOTLB
76machine_arch_initcall(p3060_qds, swiotlb_setup_bus_notifier);
77#endif
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index 09ced7221750..cebd786dc334 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -283,7 +283,7 @@ static int __init sbc8560_bdrstcr_init(void)
283 283
284 of_address_to_resource(np, 0, &res); 284 of_address_to_resource(np, 0, &res);
285 285
286 printk(KERN_INFO "sbc8560: Found BRSTCR at i/o 0x%x\n", res.start); 286 printk(KERN_INFO "sbc8560: Found BRSTCR at %pR\n", &res);
287 287
288 brstcr = ioremap(res.start, resource_size(&res)); 288 brstcr = ioremap(res.start, resource_size(&res));
289 if(!brstcr) 289 if(!brstcr)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 5b9b901f6443..2df4785ffd4e 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -48,10 +48,11 @@ smp_85xx_kick_cpu(int nr)
48 const u64 *cpu_rel_addr; 48 const u64 *cpu_rel_addr;
49 __iomem u32 *bptr_vaddr; 49 __iomem u32 *bptr_vaddr;
50 struct device_node *np; 50 struct device_node *np;
51 int n = 0; 51 int n = 0, hw_cpu = get_hard_smp_processor_id(nr);
52 int ioremappable; 52 int ioremappable;
53 53
54 WARN_ON (nr < 0 || nr >= NR_CPUS); 54 WARN_ON(nr < 0 || nr >= NR_CPUS);
55 WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
55 56
56 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); 57 pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
57 58
@@ -79,7 +80,7 @@ smp_85xx_kick_cpu(int nr)
79 80
80 local_irq_save(flags); 81 local_irq_save(flags);
81 82
82 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); 83 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
83#ifdef CONFIG_PPC32 84#ifdef CONFIG_PPC32
84 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); 85 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
85 86
@@ -88,7 +89,7 @@ smp_85xx_kick_cpu(int nr)
88 (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); 89 (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
89 90
90 /* Wait a bit for the CPU to ack. */ 91 /* Wait a bit for the CPU to ack. */
91 while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) 92 while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000))
92 mdelay(1); 93 mdelay(1);
93#else 94#else
94 smp_generic_kick_cpu(nr); 95 smp_generic_kick_cpu(nr);
@@ -206,7 +207,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
206 if ( !timeout ) 207 if ( !timeout )
207 printk(KERN_ERR "Unable to bring down secondary cpu(s)"); 208 printk(KERN_ERR "Unable to bring down secondary cpu(s)");
208 209
209 for (i = 0; i < num_cpus; i++) 210 for_each_online_cpu(i)
210 { 211 {
211 if ( i == smp_processor_id() ) continue; 212 if ( i == smp_processor_id() ) continue;
212 mpic_reset_core(i); 213 mpic_reset_core(i);
@@ -243,6 +244,7 @@ void __init mpc85xx_smp_init(void)
243 * If left NULL, .message_pass defaults to 244 * If left NULL, .message_pass defaults to
244 * smp_muxed_ipi_message_pass 245 * smp_muxed_ipi_message_pass
245 */ 246 */
247 smp_85xx_ops.message_pass = NULL;
246 smp_85xx_ops.cause_ipi = doorbell_cause_ipi; 248 smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
247 } 249 }
248 250
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index a0b5638c5dc8..8d6599d54ea6 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -4,6 +4,7 @@ menuconfig PPC_86xx
4 depends on 6xx 4 depends on 6xx
5 select FSL_SOC 5 select FSL_SOC
6 select ALTIVEC 6 select ALTIVEC
7 select ARCH_WANT_OPTIONAL_GPIOLIB
7 help 8 help
8 The Freescale E600 SoCs have 74xx cores. 9 The Freescale E600 SoCs have 74xx cores.
9 10
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index b9ba86191aed..e4588721ef34 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -1,5 +1,6 @@
1menu "Platform support" 1menu "Platform support"
2 2
3source "arch/powerpc/platforms/powernv/Kconfig"
3source "arch/powerpc/platforms/pseries/Kconfig" 4source "arch/powerpc/platforms/pseries/Kconfig"
4source "arch/powerpc/platforms/iseries/Kconfig" 5source "arch/powerpc/platforms/iseries/Kconfig"
5source "arch/powerpc/platforms/chrp/Kconfig" 6source "arch/powerpc/platforms/chrp/Kconfig"
@@ -333,16 +334,6 @@ config OF_RTC
333 334
334source "arch/powerpc/sysdev/bestcomm/Kconfig" 335source "arch/powerpc/sysdev/bestcomm/Kconfig"
335 336
336config MPC8xxx_GPIO
337 bool "MPC512x/MPC8xxx GPIO support"
338 depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
339 FSL_SOC_BOOKE || PPC_86xx
340 select GENERIC_GPIO
341 select ARCH_REQUIRE_GPIOLIB
342 help
343 Say Y here if you're going to use hardware that connects to the
344 MPC512x/831x/834x/837x/8572/8610 GPIOs.
345
346config SIMPLE_GPIO 337config SIMPLE_GPIO
347 bool "Support for simple, memory-mapped GPIO controllers" 338 bool "Support for simple, memory-mapped GPIO controllers"
348 depends on PPC 339 depends on PPC
@@ -355,7 +346,7 @@ config SIMPLE_GPIO
355 on-board peripherals. 346 on-board peripherals.
356 347
357config MCU_MPC8349EMITX 348config MCU_MPC8349EMITX
358 tristate "MPC8349E-mITX MCU driver" 349 bool "MPC8349E-mITX MCU driver"
359 depends on I2C && PPC_83xx 350 depends on I2C && PPC_83xx
360 select GENERIC_GPIO 351 select GENERIC_GPIO
361 select ARCH_REQUIRE_GPIOLIB 352 select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index e06e39589a09..a85990c886e9 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -69,6 +69,7 @@ config PPC_BOOK3S_64
69 bool "Server processors" 69 bool "Server processors"
70 select PPC_FPU 70 select PPC_FPU
71 select PPC_HAVE_PMU_SUPPORT 71 select PPC_HAVE_PMU_SUPPORT
72 select SYS_SUPPORTS_HUGETLBFS
72 73
73config PPC_BOOK3E_64 74config PPC_BOOK3E_64
74 bool "Embedded processors" 75 bool "Embedded processors"
@@ -173,6 +174,7 @@ config BOOKE
173config FSL_BOOKE 174config FSL_BOOKE
174 bool 175 bool
175 depends on (E200 || E500) && PPC32 176 depends on (E200 || E500) && PPC32
177 select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT
176 default y 178 default y
177 179
178# this is for common code between PPC32 & PPC64 FSL BOOKE 180# this is for common code between PPC32 & PPC64 FSL BOOKE
@@ -296,7 +298,7 @@ config PPC_BOOK3E_MMU
296 298
297config PPC_MM_SLICES 299config PPC_MM_SLICES
298 bool 300 bool
299 default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES) 301 default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES)
300 default n 302 default n
301 303
302config VIRT_CPU_ACCOUNTING 304config VIRT_CPU_ACCOUNTING
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 73e2116cfeed..2635a22bade2 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PPC_82xx) += 82xx/
14obj-$(CONFIG_PPC_83xx) += 83xx/ 14obj-$(CONFIG_PPC_83xx) += 83xx/
15obj-$(CONFIG_FSL_SOC_BOOKE) += 85xx/ 15obj-$(CONFIG_FSL_SOC_BOOKE) += 85xx/
16obj-$(CONFIG_PPC_86xx) += 86xx/ 16obj-$(CONFIG_PPC_86xx) += 86xx/
17obj-$(CONFIG_PPC_POWERNV) += powernv/
17obj-$(CONFIG_PPC_PSERIES) += pseries/ 18obj-$(CONFIG_PPC_PSERIES) += pseries/
18obj-$(CONFIG_PPC_ISERIES) += iseries/ 19obj-$(CONFIG_PPC_ISERIES) += iseries/
19obj-$(CONFIG_PPC_MAPLE) += maple/ 20obj-$(CONFIG_PPC_MAPLE) += maple/
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 26a067122a54..fc46fcac3921 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1159,6 +1159,26 @@ static int __init setup_iommu_fixed(char *str)
1159} 1159}
1160__setup("iommu_fixed=", setup_iommu_fixed); 1160__setup("iommu_fixed=", setup_iommu_fixed);
1161 1161
1162static u64 cell_dma_get_required_mask(struct device *dev)
1163{
1164 struct dma_map_ops *dma_ops;
1165
1166 if (!dev->dma_mask)
1167 return 0;
1168
1169 if (!iommu_fixed_disabled &&
1170 cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR)
1171 return DMA_BIT_MASK(64);
1172
1173 dma_ops = get_dma_ops(dev);
1174 if (dma_ops->get_required_mask)
1175 return dma_ops->get_required_mask(dev);
1176
1177 WARN_ONCE(1, "no get_required_mask in %p ops", dma_ops);
1178
1179 return DMA_BIT_MASK(64);
1180}
1181
1162static int __init cell_iommu_init(void) 1182static int __init cell_iommu_init(void)
1163{ 1183{
1164 struct device_node *np; 1184 struct device_node *np;
@@ -1175,6 +1195,7 @@ static int __init cell_iommu_init(void)
1175 1195
1176 /* Setup various ppc_md. callbacks */ 1196 /* Setup various ppc_md. callbacks */
1177 ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; 1197 ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
1198 ppc_md.dma_get_required_mask = cell_dma_get_required_mask;
1178 ppc_md.tce_build = tce_build_cell; 1199 ppc_md.tce_build = tce_build_cell;
1179 ppc_md.tce_free = tce_free_cell; 1200 ppc_md.tce_free = tce_free_cell;
1180 1201
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
new file mode 100644
index 000000000000..74fea5c21839
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -0,0 +1,16 @@
1config PPC_POWERNV
2 depends on PPC64 && PPC_BOOK3S
3 bool "IBM PowerNV (Non-Virtualized) platform support"
4 select PPC_NATIVE
5 select PPC_XICS
6 select PPC_ICP_NATIVE
7 select PPC_P7_NAP
8 select PPC_PCI_CHOICE if EMBEDDED
9 default y
10
11config PPC_POWERNV_RTAS
12 depends on PPC_POWERNV
13 bool "Support for RTAS based PowerNV platforms such as BML"
14 default y
15 select PPC_ICS_RTAS
16 select PPC_RTAS
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
new file mode 100644
index 000000000000..31853008b418
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -0,0 +1,5 @@
1obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o
2obj-y += opal-rtc.o opal-nvram.o
3
4obj-$(CONFIG_SMP) += smp.o
5obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c
new file mode 100644
index 000000000000..3f83e1ae26ac
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -0,0 +1,88 @@
1/*
2 * PowerNV nvram code.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#define DEBUG
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/of.h>
17
18#include <asm/opal.h>
19#include <asm/machdep.h>
20
21static unsigned int nvram_size;
22
23static ssize_t opal_nvram_size(void)
24{
25 return nvram_size;
26}
27
28static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index)
29{
30 s64 rc;
31 int off;
32
33 if (*index >= nvram_size)
34 return 0;
35 off = *index;
36 if ((off + count) > nvram_size)
37 count = nvram_size - off;
38 rc = opal_read_nvram(__pa(buf), count, off);
39 if (rc != OPAL_SUCCESS)
40 return -EIO;
41 *index += count;
42 return count;
43}
44
45static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
46{
47 s64 rc = OPAL_BUSY;
48 int off;
49
50 if (*index >= nvram_size)
51 return 0;
52 off = *index;
53 if ((off + count) > nvram_size)
54 count = nvram_size - off;
55
56 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
57 rc = opal_write_nvram(__pa(buf), count, off);
58 if (rc == OPAL_BUSY_EVENT)
59 opal_poll_events(NULL);
60 }
61 *index += count;
62 return count;
63}
64
65void __init opal_nvram_init(void)
66{
67 struct device_node *np;
68 const u32 *nbytes_p;
69
70 np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram");
71 if (np == NULL)
72 return;
73
74 nbytes_p = of_get_property(np, "#bytes", NULL);
75 if (!nbytes_p) {
76 of_node_put(np);
77 return;
78 }
79 nvram_size = *nbytes_p;
80
81 printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size);
82 of_node_put(np);
83
84 ppc_md.nvram_read = opal_nvram_read;
85 ppc_md.nvram_write = opal_nvram_write;
86 ppc_md.nvram_size = opal_nvram_size;
87}
88
diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c
new file mode 100644
index 000000000000..2aa7641aac9b
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-rtc.c
@@ -0,0 +1,97 @@
1/*
2 * PowerNV Real Time Clock.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12
13#include <linux/kernel.h>
14#include <linux/time.h>
15#include <linux/bcd.h>
16#include <linux/rtc.h>
17#include <linux/delay.h>
18
19#include <asm/opal.h>
20#include <asm/firmware.h>
21
22static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm)
23{
24 tm->tm_year = ((bcd2bin(y_m_d >> 24) * 100) +
25 bcd2bin((y_m_d >> 16) & 0xff)) - 1900;
26 tm->tm_mon = bcd2bin((y_m_d >> 8) & 0xff) - 1;
27 tm->tm_mday = bcd2bin(y_m_d & 0xff);
28 tm->tm_hour = bcd2bin((h_m_s_ms >> 56) & 0xff);
29 tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff);
30 tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff);
31
32 GregorianDay(tm);
33}
34
35unsigned long __init opal_get_boot_time(void)
36{
37 struct rtc_time tm;
38 u32 y_m_d;
39 u64 h_m_s_ms;
40 long rc = OPAL_BUSY;
41
42 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
43 rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
44 if (rc == OPAL_BUSY_EVENT)
45 opal_poll_events(NULL);
46 else
47 mdelay(10);
48 }
49 if (rc != OPAL_SUCCESS)
50 return 0;
51 opal_to_tm(y_m_d, h_m_s_ms, &tm);
52 return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
53 tm.tm_hour, tm.tm_min, tm.tm_sec);
54}
55
56void opal_get_rtc_time(struct rtc_time *tm)
57{
58 long rc = OPAL_BUSY;
59 u32 y_m_d;
60 u64 h_m_s_ms;
61
62 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
63 rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
64 if (rc == OPAL_BUSY_EVENT)
65 opal_poll_events(NULL);
66 else
67 mdelay(10);
68 }
69 if (rc != OPAL_SUCCESS)
70 return;
71 opal_to_tm(y_m_d, h_m_s_ms, tm);
72}
73
74int opal_set_rtc_time(struct rtc_time *tm)
75{
76 long rc = OPAL_BUSY;
77 u32 y_m_d = 0;
78 u64 h_m_s_ms = 0;
79
80 y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24;
81 y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16;
82 y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8;
83 y_m_d |= ((u32)bin2bcd(tm->tm_mday));
84
85 h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56;
86 h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48;
87 h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40;
88
89 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
90 rc = opal_rtc_write(y_m_d, h_m_s_ms);
91 if (rc == OPAL_BUSY_EVENT)
92 opal_poll_events(NULL);
93 else
94 mdelay(10);
95 }
96 return rc == OPAL_SUCCESS ? 0 : -EIO;
97}
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S
new file mode 100644
index 000000000000..77b48b2b9309
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-takeover.S
@@ -0,0 +1,140 @@
1/*
2 * PowerNV OPAL takeover assembly code, for use by prom_init.c
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <asm/ppc_asm.h>
13#include <asm/hvcall.h>
14#include <asm/asm-offsets.h>
15#include <asm/opal.h>
16
17#define STK_PARAM(i) (48 + ((i)-3)*8)
18
19#define H_HAL_TAKEOVER 0x5124
20#define H_HAL_TAKEOVER_QUERY_MAGIC -1
21
22 .text
23_GLOBAL(opal_query_takeover)
24 mfcr r0
25 stw r0,8(r1)
26 std r3,STK_PARAM(r3)(r1)
27 std r4,STK_PARAM(r4)(r1)
28 li r3,H_HAL_TAKEOVER
29 li r4,H_HAL_TAKEOVER_QUERY_MAGIC
30 HVSC
31 ld r10,STK_PARAM(r3)(r1)
32 std r4,0(r10)
33 ld r10,STK_PARAM(r4)(r1)
34 std r5,0(r10)
35 lwz r0,8(r1)
36 mtcrf 0xff,r0
37 blr
38
39_GLOBAL(opal_do_takeover)
40 mfcr r0
41 stw r0,8(r1)
42 mflr r0
43 std r0,16(r1)
44 bl __opal_do_takeover
45 ld r0,16(r1)
46 mtlr r0
47 lwz r0,8(r1)
48 mtcrf 0xff,r0
49 blr
50
51__opal_do_takeover:
52 ld r4,0(r3)
53 ld r5,0x8(r3)
54 ld r6,0x10(r3)
55 ld r7,0x18(r3)
56 ld r8,0x20(r3)
57 ld r9,0x28(r3)
58 ld r10,0x30(r3)
59 ld r11,0x38(r3)
60 li r3,H_HAL_TAKEOVER
61 HVSC
62 blr
63
64 .globl opal_secondary_entry
65opal_secondary_entry:
66 mr r31,r3
67 mfmsr r11
68 li r12,(MSR_SF | MSR_ISF)@highest
69 sldi r12,r12,48
70 or r11,r11,r12
71 mtmsrd r11
72 isync
73 mfspr r4,SPRN_PIR
74 std r4,0(r3)
751: HMT_LOW
76 ld r4,8(r3)
77 cmpli cr0,r4,0
78 beq 1b
79 HMT_MEDIUM
801: addi r3,r31,16
81 bl __opal_do_takeover
82 b 1b
83
84_GLOBAL(opal_enter_rtas)
85 mflr r0
86 std r0,16(r1)
87 stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
88
89 /* Because PROM is running in 32b mode, it clobbers the high order half
90 * of all registers that it saves. We therefore save those registers
91 * PROM might touch to the stack. (r0, r3-r13 are caller saved)
92 */
93 SAVE_GPR(2, r1)
94 SAVE_GPR(13, r1)
95 SAVE_8GPRS(14, r1)
96 SAVE_10GPRS(22, r1)
97 mfcr r10
98 mfmsr r11
99 std r10,_CCR(r1)
100 std r11,_MSR(r1)
101
102 /* Get the PROM entrypoint */
103 mtlr r5
104
105 /* Switch MSR to 32 bits mode
106 */
107 li r12,1
108 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
109 andc r11,r11,r12
110 li r12,1
111 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
112 andc r11,r11,r12
113 mtmsrd r11
114 isync
115
116 /* Enter RTAS here... */
117 blrl
118
119 /* Just make sure that r1 top 32 bits didn't get
120 * corrupt by OF
121 */
122 rldicl r1,r1,0,32
123
124 /* Restore the MSR (back to 64 bits) */
125 ld r0,_MSR(r1)
126 MTMSRD(r0)
127 isync
128
129 /* Restore other registers */
130 REST_GPR(2, r1)
131 REST_GPR(13, r1)
132 REST_8GPRS(14, r1)
133 REST_10GPRS(22, r1)
134 ld r4,_CCR(r1)
135 mtcr r4
136
137 addi r1,r1,PROM_FRAME_SIZE
138 ld r0,16(r1)
139 mtlr r0
140 blr
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
new file mode 100644
index 000000000000..4a3f46d8533e
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -0,0 +1,101 @@
1/*
2 * PowerNV OPAL API wrappers
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <asm/ppc_asm.h>
13#include <asm/hvcall.h>
14#include <asm/asm-offsets.h>
15#include <asm/opal.h>
16
17/* TODO:
18 *
19 * - Trace irqs in/off (needs saving/restoring all args, argh...)
20 * - Get r11 feed up by Dave so I can have better register usage
21 */
22#define OPAL_CALL(name, token) \
23 _GLOBAL(name); \
24 mflr r0; \
25 mfcr r12; \
26 std r0,16(r1); \
27 std r12,8(r1); \
28 std r1,PACAR1(r13); \
29 li r0,0; \
30 mfmsr r12; \
31 ori r0,r0,MSR_EE; \
32 std r12,PACASAVEDMSR(r13); \
33 andc r12,r12,r0; \
34 mtmsrd r12,1; \
35 LOAD_REG_ADDR(r0,.opal_return); \
36 mtlr r0; \
37 li r0,MSR_DR|MSR_IR; \
38 andc r12,r12,r0; \
39 li r0,token; \
40 mtspr SPRN_HSRR1,r12; \
41 LOAD_REG_ADDR(r11,opal); \
42 ld r12,8(r11); \
43 ld r2,0(r11); \
44 mtspr SPRN_HSRR0,r12; \
45 hrfid
46
47_STATIC(opal_return)
48 ld r2,PACATOC(r13);
49 ld r4,8(r1);
50 ld r5,16(r1);
51 ld r6,PACASAVEDMSR(r13);
52 mtspr SPRN_SRR0,r5;
53 mtspr SPRN_SRR1,r6;
54 mtcr r4;
55 rfid
56
57OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE);
58OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ);
59OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE);
60OPAL_CALL(opal_rtc_read, OPAL_RTC_READ);
61OPAL_CALL(opal_rtc_write, OPAL_RTC_WRITE);
62OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN);
63OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT);
64OPAL_CALL(opal_read_nvram, OPAL_READ_NVRAM);
65OPAL_CALL(opal_write_nvram, OPAL_WRITE_NVRAM);
66OPAL_CALL(opal_handle_interrupt, OPAL_HANDLE_INTERRUPT);
67OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS);
68OPAL_CALL(opal_pci_set_hub_tce_memory, OPAL_PCI_SET_HUB_TCE_MEMORY);
69OPAL_CALL(opal_pci_set_phb_tce_memory, OPAL_PCI_SET_PHB_TCE_MEMORY);
70OPAL_CALL(opal_pci_config_read_byte, OPAL_PCI_CONFIG_READ_BYTE);
71OPAL_CALL(opal_pci_config_read_half_word, OPAL_PCI_CONFIG_READ_HALF_WORD);
72OPAL_CALL(opal_pci_config_read_word, OPAL_PCI_CONFIG_READ_WORD);
73OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE);
74OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD);
75OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD);
76OPAL_CALL(opal_set_xive, OPAL_SET_XIVE);
77OPAL_CALL(opal_get_xive, OPAL_GET_XIVE);
78OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER);
79OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS);
80OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR);
81OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC);
82OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE);
83OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW);
84OPAL_CALL(opal_pci_map_pe_mmio_window, OPAL_PCI_MAP_PE_MMIO_WINDOW);
85OPAL_CALL(opal_pci_set_phb_table_memory, OPAL_PCI_SET_PHB_TABLE_MEMORY);
86OPAL_CALL(opal_pci_set_pe, OPAL_PCI_SET_PE);
87OPAL_CALL(opal_pci_set_peltv, OPAL_PCI_SET_PELTV);
88OPAL_CALL(opal_pci_set_mve, OPAL_PCI_SET_MVE);
89OPAL_CALL(opal_pci_set_mve_enable, OPAL_PCI_SET_MVE_ENABLE);
90OPAL_CALL(opal_pci_get_xive_reissue, OPAL_PCI_GET_XIVE_REISSUE);
91OPAL_CALL(opal_pci_set_xive_reissue, OPAL_PCI_SET_XIVE_REISSUE);
92OPAL_CALL(opal_pci_set_xive_pe, OPAL_PCI_SET_XIVE_PE);
93OPAL_CALL(opal_get_xive_source, OPAL_GET_XIVE_SOURCE);
94OPAL_CALL(opal_get_msi_32, OPAL_GET_MSI_32);
95OPAL_CALL(opal_get_msi_64, OPAL_GET_MSI_64);
96OPAL_CALL(opal_start_cpu, OPAL_START_CPU);
97OPAL_CALL(opal_query_cpu_status, OPAL_QUERY_CPU_STATUS);
98OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL);
99OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW);
100OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL);
101OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
new file mode 100644
index 000000000000..aaa0dba49471
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -0,0 +1,322 @@
1/*
2 * PowerNV OPAL high level interfaces
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#undef DEBUG
13
14#include <linux/types.h>
15#include <linux/of.h>
16#include <linux/of_platform.h>
17#include <linux/interrupt.h>
18#include <asm/opal.h>
19#include <asm/firmware.h>
20
21#include "powernv.h"
22
23struct opal {
24 u64 base;
25 u64 entry;
26} opal;
27
28static struct device_node *opal_node;
29static DEFINE_SPINLOCK(opal_write_lock);
30extern u64 opal_mc_secondary_handler[];
31
32int __init early_init_dt_scan_opal(unsigned long node,
33 const char *uname, int depth, void *data)
34{
35 const void *basep, *entryp;
36 unsigned long basesz, entrysz;
37 u64 glue;
38
39 if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
40 return 0;
41
42 basep = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
43 entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
44
45 if (!basep || !entryp)
46 return 1;
47
48 opal.base = of_read_number(basep, basesz/4);
49 opal.entry = of_read_number(entryp, entrysz/4);
50
51 pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%ld)\n",
52 opal.base, basep, basesz);
53 pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n",
54 opal.entry, entryp, entrysz);
55
56 powerpc_firmware_features |= FW_FEATURE_OPAL;
57 if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
58 powerpc_firmware_features |= FW_FEATURE_OPALv2;
59 printk("OPAL V2 detected !\n");
60 } else {
61 printk("OPAL V1 detected !\n");
62 }
63
64 /* Hookup some exception handlers. We use the fwnmi area at 0x7000
65 * to provide the glue space to OPAL
66 */
67 glue = 0x7000;
68 opal_register_exception_handler(OPAL_MACHINE_CHECK_HANDLER,
69 __pa(opal_mc_secondary_handler[0]),
70 glue);
71 glue += 128;
72 opal_register_exception_handler(OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
73 0, glue);
74 glue += 128;
75 opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
76
77 return 1;
78}
79
80int opal_get_chars(uint32_t vtermno, char *buf, int count)
81{
82 s64 len, rc;
83 u64 evt;
84
85 if (!opal.entry)
86 return -ENODEV;
87 opal_poll_events(&evt);
88 if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0)
89 return 0;
90 len = count;
91 rc = opal_console_read(vtermno, &len, buf);
92 if (rc == OPAL_SUCCESS)
93 return len;
94 return 0;
95}
96
97int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
98{
99 int written = 0;
100 s64 len, rc;
101 unsigned long flags;
102 u64 evt;
103
104 if (!opal.entry)
105 return -ENODEV;
106
107 /* We want put_chars to be atomic to avoid mangling of hvsi
108 * packets. To do that, we first test for room and return
109 * -EAGAIN if there isn't enough.
110 *
111 * Unfortunately, opal_console_write_buffer_space() doesn't
112 * appear to work on opal v1, so we just assume there is
113 * enough room and be done with it
114 */
115 spin_lock_irqsave(&opal_write_lock, flags);
116 if (firmware_has_feature(FW_FEATURE_OPALv2)) {
117 rc = opal_console_write_buffer_space(vtermno, &len);
118 if (rc || len < total_len) {
119 spin_unlock_irqrestore(&opal_write_lock, flags);
120 /* Closed -> drop characters */
121 if (rc)
122 return total_len;
123 opal_poll_events(&evt);
124 return -EAGAIN;
125 }
126 }
127
128 /* We still try to handle partial completions, though they
129 * should no longer happen.
130 */
131 rc = OPAL_BUSY;
132 while(total_len > 0 && (rc == OPAL_BUSY ||
133 rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
134 len = total_len;
135 rc = opal_console_write(vtermno, &len, data);
136 if (rc == OPAL_SUCCESS) {
137 total_len -= len;
138 data += len;
139 written += len;
140 }
141 /* This is a bit nasty but we need that for the console to
142 * flush when there aren't any interrupts. We will clean
143 * things a bit later to limit that to synchronous path
144 * such as the kernel console and xmon/udbg
145 */
146 do
147 opal_poll_events(&evt);
148 while(rc == OPAL_SUCCESS && (evt & OPAL_EVENT_CONSOLE_OUTPUT));
149 }
150 spin_unlock_irqrestore(&opal_write_lock, flags);
151 return written;
152}
153
154int opal_machine_check(struct pt_regs *regs)
155{
156 struct opal_machine_check_event *opal_evt = get_paca()->opal_mc_evt;
157 struct opal_machine_check_event evt;
158 const char *level, *sevstr, *subtype;
159 static const char *opal_mc_ue_types[] = {
160 "Indeterminate",
161 "Instruction fetch",
162 "Page table walk ifetch",
163 "Load/Store",
164 "Page table walk Load/Store",
165 };
166 static const char *opal_mc_slb_types[] = {
167 "Indeterminate",
168 "Parity",
169 "Multihit",
170 };
171 static const char *opal_mc_erat_types[] = {
172 "Indeterminate",
173 "Parity",
174 "Multihit",
175 };
176 static const char *opal_mc_tlb_types[] = {
177 "Indeterminate",
178 "Parity",
179 "Multihit",
180 };
181
182 /* Copy the event structure and release the original */
183 evt = *opal_evt;
184 opal_evt->in_use = 0;
185
186 /* Print things out */
187 if (evt.version != OpalMCE_V1) {
188 pr_err("Machine Check Exception, Unknown event version %d !\n",
189 evt.version);
190 return 0;
191 }
192 switch(evt.severity) {
193 case OpalMCE_SEV_NO_ERROR:
194 level = KERN_INFO;
195 sevstr = "Harmless";
196 break;
197 case OpalMCE_SEV_WARNING:
198 level = KERN_WARNING;
199 sevstr = "";
200 break;
201 case OpalMCE_SEV_ERROR_SYNC:
202 level = KERN_ERR;
203 sevstr = "Severe";
204 break;
205 case OpalMCE_SEV_FATAL:
206 default:
207 level = KERN_ERR;
208 sevstr = "Fatal";
209 break;
210 }
211
212 printk("%s%s Machine check interrupt [%s]\n", level, sevstr,
213 evt.disposition == OpalMCE_DISPOSITION_RECOVERED ?
214 "Recovered" : "[Not recovered");
215 printk("%s Initiator: %s\n", level,
216 evt.initiator == OpalMCE_INITIATOR_CPU ? "CPU" : "Unknown");
217 switch(evt.error_type) {
218 case OpalMCE_ERROR_TYPE_UE:
219 subtype = evt.u.ue_error.ue_error_type <
220 ARRAY_SIZE(opal_mc_ue_types) ?
221 opal_mc_ue_types[evt.u.ue_error.ue_error_type]
222 : "Unknown";
223 printk("%s Error type: UE [%s]\n", level, subtype);
224 if (evt.u.ue_error.effective_address_provided)
225 printk("%s Effective address: %016llx\n",
226 level, evt.u.ue_error.effective_address);
227 if (evt.u.ue_error.physical_address_provided)
228 printk("%s Physial address: %016llx\n",
229 level, evt.u.ue_error.physical_address);
230 break;
231 case OpalMCE_ERROR_TYPE_SLB:
232 subtype = evt.u.slb_error.slb_error_type <
233 ARRAY_SIZE(opal_mc_slb_types) ?
234 opal_mc_slb_types[evt.u.slb_error.slb_error_type]
235 : "Unknown";
236 printk("%s Error type: SLB [%s]\n", level, subtype);
237 if (evt.u.slb_error.effective_address_provided)
238 printk("%s Effective address: %016llx\n",
239 level, evt.u.slb_error.effective_address);
240 break;
241 case OpalMCE_ERROR_TYPE_ERAT:
242 subtype = evt.u.erat_error.erat_error_type <
243 ARRAY_SIZE(opal_mc_erat_types) ?
244 opal_mc_erat_types[evt.u.erat_error.erat_error_type]
245 : "Unknown";
246 printk("%s Error type: ERAT [%s]\n", level, subtype);
247 if (evt.u.erat_error.effective_address_provided)
248 printk("%s Effective address: %016llx\n",
249 level, evt.u.erat_error.effective_address);
250 break;
251 case OpalMCE_ERROR_TYPE_TLB:
252 subtype = evt.u.tlb_error.tlb_error_type <
253 ARRAY_SIZE(opal_mc_tlb_types) ?
254 opal_mc_tlb_types[evt.u.tlb_error.tlb_error_type]
255 : "Unknown";
256 printk("%s Error type: TLB [%s]\n", level, subtype);
257 if (evt.u.tlb_error.effective_address_provided)
258 printk("%s Effective address: %016llx\n",
259 level, evt.u.tlb_error.effective_address);
260 break;
261 default:
262 case OpalMCE_ERROR_TYPE_UNKNOWN:
263 printk("%s Error type: Unknown\n", level);
264 break;
265 }
266 return evt.severity == OpalMCE_SEV_FATAL ? 0 : 1;
267}
268
269static irqreturn_t opal_interrupt(int irq, void *data)
270{
271 uint64_t events;
272
273 opal_handle_interrupt(virq_to_hw(irq), &events);
274
275 /* XXX TODO: Do something with the events */
276
277 return IRQ_HANDLED;
278}
279
280static int __init opal_init(void)
281{
282 struct device_node *np, *consoles;
283 const u32 *irqs;
284 int rc, i, irqlen;
285
286 opal_node = of_find_node_by_path("/ibm,opal");
287 if (!opal_node) {
288 pr_warn("opal: Node not found\n");
289 return -ENODEV;
290 }
291 if (firmware_has_feature(FW_FEATURE_OPALv2))
292 consoles = of_find_node_by_path("/ibm,opal/consoles");
293 else
294 consoles = of_node_get(opal_node);
295
296 /* Register serial ports */
297 for_each_child_of_node(consoles, np) {
298 if (strcmp(np->name, "serial"))
299 continue;
300 of_platform_device_create(np, NULL, NULL);
301 }
302 of_node_put(consoles);
303
304 /* Find all OPAL interrupts and request them */
305 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
306 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
307 irqs ? (irqlen / 4) : 0);
308 for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
309 unsigned int hwirq = be32_to_cpup(irqs);
310 unsigned int irq = irq_create_mapping(NULL, hwirq);
311 if (irq == NO_IRQ) {
312 pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
313 continue;
314 }
315 rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
316 if (rc)
317 pr_warning("opal: Error %d requesting irq %d"
318 " (0x%x)\n", rc, irq, hwirq);
319 }
320 return 0;
321}
322subsys_initcall(opal_init);
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
new file mode 100644
index 000000000000..4c80f7c77d56
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -0,0 +1,234 @@
1/*
2 * Support PCI/PCIe on PowerNV platforms
3 *
4 * Currently supports only P5IOC2
5 *
6 * Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/string.h>
18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/irq.h>
21#include <linux/io.h>
22#include <linux/msi.h>
23
24#include <asm/sections.h>
25#include <asm/io.h>
26#include <asm/prom.h>
27#include <asm/pci-bridge.h>
28#include <asm/machdep.h>
29#include <asm/ppc-pci.h>
30#include <asm/opal.h>
31#include <asm/iommu.h>
32#include <asm/tce.h>
33#include <asm/abs_addr.h>
34
35#include "powernv.h"
36#include "pci.h"
37
38/* For now, use a fixed amount of TCE memory for each p5ioc2
39 * hub, 16M will do
40 */
41#define P5IOC2_TCE_MEMORY 0x01000000
42
43#ifdef CONFIG_PCI_MSI
44static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
45 unsigned int hwirq, unsigned int is_64,
46 struct msi_msg *msg)
47{
48 if (WARN_ON(!is_64))
49 return -ENXIO;
50 msg->data = hwirq - phb->msi_base;
51 msg->address_hi = 0x10000000;
52 msg->address_lo = 0;
53
54 return 0;
55}
56
57static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
58{
59 unsigned int bmap_size;
60 const __be32 *prop = of_get_property(phb->hose->dn,
61 "ibm,opal-msi-ranges", NULL);
62 if (!prop)
63 return;
64
65 /* Don't do MSI's on p5ioc2 PCI-X are they are not properly
66 * verified in HW
67 */
68 if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix"))
69 return;
70 phb->msi_base = be32_to_cpup(prop);
71 phb->msi_count = be32_to_cpup(prop + 1);
72 bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long);
73 phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL);
74 if (!phb->msi_map) {
75 pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
76 phb->hose->global_number);
77 return;
78 }
79 phb->msi_setup = pnv_pci_p5ioc2_msi_setup;
80 phb->msi32_support = 0;
81 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
82 phb->msi_count, phb->msi_base);
83}
84#else
85static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { }
86#endif /* CONFIG_PCI_MSI */
87
88static void __devinit pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
89 struct pci_dev *pdev)
90{
91 if (phb->p5ioc2.iommu_table.it_map == NULL)
92 iommu_init_table(&phb->p5ioc2.iommu_table, phb->hose->node);
93
94 set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table);
95}
96
97static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np,
98 void *tce_mem, u64 tce_size)
99{
100 struct pnv_phb *phb;
101 const u64 *prop64;
102 u64 phb_id;
103 int64_t rc;
104 static int primary = 1;
105
106 pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name);
107
108 prop64 = of_get_property(np, "ibm,opal-phbid", NULL);
109 if (!prop64) {
110 pr_err(" Missing \"ibm,opal-phbid\" property !\n");
111 return;
112 }
113 phb_id = be64_to_cpup(prop64);
114 pr_devel(" PHB-ID : 0x%016llx\n", phb_id);
115 pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem));
116 pr_devel(" TCE SZ : 0x%016llx\n", tce_size);
117
118 rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size);
119 if (rc != OPAL_SUCCESS) {
120 pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc);
121 return;
122 }
123
124 phb = alloc_bootmem(sizeof(struct pnv_phb));
125 if (phb) {
126 memset(phb, 0, sizeof(struct pnv_phb));
127 phb->hose = pcibios_alloc_controller(np);
128 }
129 if (!phb || !phb->hose) {
130 pr_err(" Failed to allocate PCI controller\n");
131 return;
132 }
133
134 spin_lock_init(&phb->lock);
135 phb->hose->first_busno = 0;
136 phb->hose->last_busno = 0xff;
137 phb->hose->private_data = phb;
138 phb->opal_id = phb_id;
139 phb->type = PNV_PHB_P5IOC2;
140
141 phb->regs = of_iomap(np, 0);
142
143 if (phb->regs == NULL)
144 pr_err(" Failed to map registers !\n");
145 else {
146 pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100));
147 pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0));
148 pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0));
149 pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0));
150 pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190));
151 pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0));
152 pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0));
153 pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0));
154 pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0));
155 pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0));
156 pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0));
157 }
158
159 /* Interpret the "ranges" property */
160 /* This also maps the I/O region and sets isa_io/mem_base */
161 pci_process_bridge_OF_ranges(phb->hose, np, primary);
162 primary = 0;
163
164 phb->hose->ops = &pnv_pci_ops;
165
166 /* Setup MSI support */
167 pnv_pci_init_p5ioc2_msis(phb);
168
169 /* Setup TCEs */
170 phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup;
171 pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table,
172 tce_mem, tce_size, 0);
173}
174
175void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
176{
177 struct device_node *phbn;
178 const u64 *prop64;
179 u64 hub_id;
180 void *tce_mem;
181 uint64_t tce_per_phb;
182 int64_t rc;
183 int phb_count = 0;
184
185 pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name);
186
187 prop64 = of_get_property(np, "ibm,opal-hubid", NULL);
188 if (!prop64) {
189 pr_err(" Missing \"ibm,opal-hubid\" property !\n");
190 return;
191 }
192 hub_id = be64_to_cpup(prop64);
193 pr_info(" HUB-ID : 0x%016llx\n", hub_id);
194
195 /* Currently allocate 16M of TCE memory for every Hub
196 *
197 * XXX TODO: Make it chip local if possible
198 */
199 tce_mem = __alloc_bootmem(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY,
200 __pa(MAX_DMA_ADDRESS));
201 if (!tce_mem) {
202 pr_err(" Failed to allocate TCE Memory !\n");
203 return;
204 }
205 pr_debug(" TCE : 0x%016lx..0x%016lx\n",
206 __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1);
207 rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem),
208 P5IOC2_TCE_MEMORY);
209 if (rc != OPAL_SUCCESS) {
210 pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc);
211 return;
212 }
213
214 /* Count child PHBs */
215 for_each_child_of_node(np, phbn) {
216 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
217 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
218 phb_count++;
219 }
220
221 /* Calculate how much TCE space we can give per PHB */
222 tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
223 pr_info(" Allocating %lld MB of TCE memory per PHB\n",
224 tce_per_phb >> 20);
225
226 /* Initialize PHBs */
227 for_each_child_of_node(np, phbn) {
228 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
229 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) {
230 pnv_pci_init_p5ioc2_phb(phbn, tce_mem, tce_per_phb);
231 tce_mem += tce_per_phb;
232 }
233 }
234}
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
new file mode 100644
index 000000000000..85bb66d7f933
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -0,0 +1,427 @@
1/*
2 * Support PCI/PCIe on PowerNV platforms
3 *
4 * Currently supports only P5IOC2
5 *
6 * Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/string.h>
18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/irq.h>
21#include <linux/io.h>
22#include <linux/msi.h>
23
24#include <asm/sections.h>
25#include <asm/io.h>
26#include <asm/prom.h>
27#include <asm/pci-bridge.h>
28#include <asm/machdep.h>
29#include <asm/ppc-pci.h>
30#include <asm/opal.h>
31#include <asm/iommu.h>
32#include <asm/tce.h>
33#include <asm/abs_addr.h>
34
35#include "powernv.h"
36#include "pci.h"
37
38/* Delay in usec */
39#define PCI_RESET_DELAY_US 3000000
40
41#define cfg_dbg(fmt...) do { } while(0)
42//#define cfg_dbg(fmt...) printk(fmt)
43
44#ifdef CONFIG_PCI_MSI
45static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
46{
47 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
48 struct pnv_phb *phb = hose->private_data;
49
50 return (phb && phb->msi_map) ? 0 : -ENODEV;
51}
52
53static unsigned int pnv_get_one_msi(struct pnv_phb *phb)
54{
55 unsigned int id;
56
57 spin_lock(&phb->lock);
58 id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next);
59 if (id >= phb->msi_count && phb->msi_next)
60 id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0);
61 if (id >= phb->msi_count) {
62 spin_unlock(&phb->lock);
63 return 0;
64 }
65 __set_bit(id, phb->msi_map);
66 spin_unlock(&phb->lock);
67 return id + phb->msi_base;
68}
69
70static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq)
71{
72 unsigned int id;
73
74 if (WARN_ON(hwirq < phb->msi_base ||
75 hwirq >= (phb->msi_base + phb->msi_count)))
76 return;
77 id = hwirq - phb->msi_base;
78 spin_lock(&phb->lock);
79 __clear_bit(id, phb->msi_map);
80 spin_unlock(&phb->lock);
81}
82
83static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
84{
85 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
86 struct pnv_phb *phb = hose->private_data;
87 struct msi_desc *entry;
88 struct msi_msg msg;
89 unsigned int hwirq, virq;
90 int rc;
91
92 if (WARN_ON(!phb))
93 return -ENODEV;
94
95 list_for_each_entry(entry, &pdev->msi_list, list) {
96 if (!entry->msi_attrib.is_64 && !phb->msi32_support) {
97 pr_warn("%s: Supports only 64-bit MSIs\n",
98 pci_name(pdev));
99 return -ENXIO;
100 }
101 hwirq = pnv_get_one_msi(phb);
102 if (!hwirq) {
103 pr_warn("%s: Failed to find a free MSI\n",
104 pci_name(pdev));
105 return -ENOSPC;
106 }
107 virq = irq_create_mapping(NULL, hwirq);
108 if (virq == NO_IRQ) {
109 pr_warn("%s: Failed to map MSI to linux irq\n",
110 pci_name(pdev));
111 pnv_put_msi(phb, hwirq);
112 return -ENOMEM;
113 }
114 rc = phb->msi_setup(phb, pdev, hwirq, entry->msi_attrib.is_64,
115 &msg);
116 if (rc) {
117 pr_warn("%s: Failed to setup MSI\n", pci_name(pdev));
118 irq_dispose_mapping(virq);
119 pnv_put_msi(phb, hwirq);
120 return rc;
121 }
122 irq_set_msi_desc(virq, entry);
123 write_msi_msg(virq, &msg);
124 }
125 return 0;
126}
127
128static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
129{
130 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
131 struct pnv_phb *phb = hose->private_data;
132 struct msi_desc *entry;
133
134 if (WARN_ON(!phb))
135 return;
136
137 list_for_each_entry(entry, &pdev->msi_list, list) {
138 if (entry->irq == NO_IRQ)
139 continue;
140 irq_set_msi_desc(entry->irq, NULL);
141 pnv_put_msi(phb, virq_to_hw(entry->irq));
142 irq_dispose_mapping(entry->irq);
143 }
144}
145#endif /* CONFIG_PCI_MSI */
146
147static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus,
148 u32 bdfn)
149{
150 s64 rc;
151 u8 fstate;
152 u16 pcierr;
153 u32 pe_no;
154
155 /* Get PE# if we support IODA */
156 pe_no = phb->bdfn_to_pe ? phb->bdfn_to_pe(phb, bus, bdfn & 0xff) : 0;
157
158 /* Read freeze status */
159 rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
160 NULL);
161 if (rc) {
162 pr_warning("PCI %d: Failed to read EEH status for PE#%d,"
163 " err %lld\n", phb->hose->global_number, pe_no, rc);
164 return;
165 }
166 cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n",
167 bdfn, pe_no, fstate);
168 if (fstate != 0) {
169 rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
170 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
171 if (rc) {
172 pr_warning("PCI %d: Failed to clear EEH freeze state"
173 " for PE#%d, err %lld\n",
174 phb->hose->global_number, pe_no, rc);
175 }
176 }
177}
178
179static int pnv_pci_read_config(struct pci_bus *bus,
180 unsigned int devfn,
181 int where, int size, u32 *val)
182{
183 struct pci_controller *hose = pci_bus_to_host(bus);
184 struct pnv_phb *phb = hose->private_data;
185 u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
186 s64 rc;
187
188 if (hose == NULL)
189 return PCIBIOS_DEVICE_NOT_FOUND;
190
191 switch (size) {
192 case 1: {
193 u8 v8;
194 rc = opal_pci_config_read_byte(phb->opal_id, bdfn, where, &v8);
195 *val = (rc == OPAL_SUCCESS) ? v8 : 0xff;
196 break;
197 }
198 case 2: {
199 u16 v16;
200 rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where,
201 &v16);
202 *val = (rc == OPAL_SUCCESS) ? v16 : 0xffff;
203 break;
204 }
205 case 4: {
206 u32 v32;
207 rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32);
208 *val = (rc == OPAL_SUCCESS) ? v32 : 0xffffffff;
209 break;
210 }
211 default:
212 return PCIBIOS_FUNC_NOT_SUPPORTED;
213 }
214 cfg_dbg("pnv_pci_read_config bus: %x devfn: %x +%x/%x -> %08x\n",
215 bus->number, devfn, where, size, *val);
216
217 /* Check if the PHB got frozen due to an error (no response) */
218 pnv_pci_config_check_eeh(phb, bus, bdfn);
219
220 return PCIBIOS_SUCCESSFUL;
221}
222
223static int pnv_pci_write_config(struct pci_bus *bus,
224 unsigned int devfn,
225 int where, int size, u32 val)
226{
227 struct pci_controller *hose = pci_bus_to_host(bus);
228 struct pnv_phb *phb = hose->private_data;
229 u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
230
231 if (hose == NULL)
232 return PCIBIOS_DEVICE_NOT_FOUND;
233
234 cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n",
235 bus->number, devfn, where, size, val);
236 switch (size) {
237 case 1:
238 opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
239 break;
240 case 2:
241 opal_pci_config_write_half_word(phb->opal_id, bdfn, where, val);
242 break;
243 case 4:
244 opal_pci_config_write_word(phb->opal_id, bdfn, where, val);
245 break;
246 default:
247 return PCIBIOS_FUNC_NOT_SUPPORTED;
248 }
249 /* Check if the PHB got frozen due to an error (no response) */
250 pnv_pci_config_check_eeh(phb, bus, bdfn);
251
252 return PCIBIOS_SUCCESSFUL;
253}
254
255struct pci_ops pnv_pci_ops = {
256 .read = pnv_pci_read_config,
257 .write = pnv_pci_write_config,
258};
259
260static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
261 unsigned long uaddr, enum dma_data_direction direction,
262 struct dma_attrs *attrs)
263{
264 u64 proto_tce;
265 u64 *tcep;
266 u64 rpn;
267
268 proto_tce = TCE_PCI_READ; // Read allowed
269
270 if (direction != DMA_TO_DEVICE)
271 proto_tce |= TCE_PCI_WRITE;
272
273 tcep = ((u64 *)tbl->it_base) + index;
274
275 while (npages--) {
276 /* can't move this out since we might cross LMB boundary */
277 rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
278 *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
279
280 uaddr += TCE_PAGE_SIZE;
281 tcep++;
282 }
283 return 0;
284}
285
286static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
287{
288 u64 *tcep = ((u64 *)tbl->it_base) + index;
289
290 while (npages--)
291 *(tcep++) = 0;
292}
293
294void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
295 void *tce_mem, u64 tce_size,
296 u64 dma_offset)
297{
298 tbl->it_blocksize = 16;
299 tbl->it_base = (unsigned long)tce_mem;
300 tbl->it_offset = dma_offset >> IOMMU_PAGE_SHIFT;
301 tbl->it_index = 0;
302 tbl->it_size = tce_size >> 3;
303 tbl->it_busno = 0;
304 tbl->it_type = TCE_PCI;
305}
306
307static struct iommu_table * __devinit
308pnv_pci_setup_bml_iommu(struct pci_controller *hose)
309{
310 struct iommu_table *tbl;
311 const __be64 *basep;
312 const __be32 *sizep;
313
314 basep = of_get_property(hose->dn, "linux,tce-base", NULL);
315 sizep = of_get_property(hose->dn, "linux,tce-size", NULL);
316 if (basep == NULL || sizep == NULL) {
317 pr_err("PCI: %s has missing tce entries !\n", hose->dn->full_name);
318 return NULL;
319 }
320 tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node);
321 if (WARN_ON(!tbl))
322 return NULL;
323 pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)),
324 be32_to_cpup(sizep), 0);
325 iommu_init_table(tbl, hose->node);
326 return tbl;
327}
328
329static void __devinit pnv_pci_dma_fallback_setup(struct pci_controller *hose,
330 struct pci_dev *pdev)
331{
332 struct device_node *np = pci_bus_to_OF_node(hose->bus);
333 struct pci_dn *pdn;
334
335 if (np == NULL)
336 return;
337 pdn = PCI_DN(np);
338 if (!pdn->iommu_table)
339 pdn->iommu_table = pnv_pci_setup_bml_iommu(hose);
340 if (!pdn->iommu_table)
341 return;
342 set_iommu_table_base(&pdev->dev, pdn->iommu_table);
343}
344
345static void __devinit pnv_pci_dma_dev_setup(struct pci_dev *pdev)
346{
347 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
348 struct pnv_phb *phb = hose->private_data;
349
350 /* If we have no phb structure, try to setup a fallback based on
351 * the device-tree (RTAS PCI for example)
352 */
353 if (phb && phb->dma_dev_setup)
354 phb->dma_dev_setup(phb, pdev);
355 else
356 pnv_pci_dma_fallback_setup(hose, pdev);
357}
358
359static int pnv_pci_probe_mode(struct pci_bus *bus)
360{
361 struct pci_controller *hose = pci_bus_to_host(bus);
362 const __be64 *tstamp;
363 u64 now, target;
364
365
366 /* We hijack this as a way to ensure we have waited long
367 * enough since the reset was lifted on the PCI bus
368 */
369 if (bus != hose->bus)
370 return PCI_PROBE_NORMAL;
371 tstamp = of_get_property(hose->dn, "reset-clear-timestamp", NULL);
372 if (!tstamp || !*tstamp)
373 return PCI_PROBE_NORMAL;
374
375 now = mftb() / tb_ticks_per_usec;
376 target = (be64_to_cpup(tstamp) / tb_ticks_per_usec)
377 + PCI_RESET_DELAY_US;
378
379 pr_devel("pci %04d: Reset target: 0x%llx now: 0x%llx\n",
380 hose->global_number, target, now);
381
382 if (now < target)
383 msleep((target - now + 999) / 1000);
384
385 return PCI_PROBE_NORMAL;
386}
387
388void __init pnv_pci_init(void)
389{
390 struct device_node *np;
391
392 pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
393
394 /* We do not want to just probe */
395 pci_probe_only = 0;
396
397 /* OPAL absent, try POPAL first then RTAS detection of PHBs */
398 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
399#ifdef CONFIG_PPC_POWERNV_RTAS
400 init_pci_config_tokens();
401 find_and_init_phbs();
402#endif /* CONFIG_PPC_POWERNV_RTAS */
403 } else {
404 /* OPAL is here, do our normal stuff */
405
406 /* Look for p5ioc2 IO-Hubs */
407 for_each_compatible_node(np, NULL, "ibm,p5ioc2")
408 pnv_pci_init_p5ioc2_hub(np);
409 }
410
411 /* Setup the linkage between OF nodes and PHBs */
412 pci_devs_phb_init();
413
414 /* Configure IOMMU DMA hooks */
415 ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
416 ppc_md.tce_build = pnv_tce_build;
417 ppc_md.tce_free = pnv_tce_free;
418 ppc_md.pci_probe_mode = pnv_pci_probe_mode;
419 set_pci_dma_ops(&dma_iommu_ops);
420
421 /* Configure MSIs */
422#ifdef CONFIG_PCI_MSI
423 ppc_md.msi_check_device = pnv_msi_check_device;
424 ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
425 ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
426#endif
427}
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
new file mode 100644
index 000000000000..d4dbc4950936
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -0,0 +1,48 @@
1#ifndef __POWERNV_PCI_H
2#define __POWERNV_PCI_H
3
4struct pci_dn;
5
6enum pnv_phb_type {
7 PNV_PHB_P5IOC2,
8 PNV_PHB_IODA1,
9 PNV_PHB_IODA2,
10};
11
12struct pnv_phb {
13 struct pci_controller *hose;
14 enum pnv_phb_type type;
15 u64 opal_id;
16 void __iomem *regs;
17 spinlock_t lock;
18
19#ifdef CONFIG_PCI_MSI
20 unsigned long *msi_map;
21 unsigned int msi_base;
22 unsigned int msi_count;
23 unsigned int msi_next;
24 unsigned int msi32_support;
25#endif
26 int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev,
27 unsigned int hwirq, unsigned int is_64,
28 struct msi_msg *msg);
29 void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
30 void (*fixup_phb)(struct pci_controller *hose);
31 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
32
33 union {
34 struct {
35 struct iommu_table iommu_table;
36 } p5ioc2;
37 };
38};
39
40extern struct pci_ops pnv_pci_ops;
41
42extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
43 void *tce_mem, u64 tce_size,
44 u64 dma_offset);
45extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
46
47
48#endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h
new file mode 100644
index 000000000000..8a9df7f9667e
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/powernv.h
@@ -0,0 +1,16 @@
1#ifndef _POWERNV_H
2#define _POWERNV_H
3
4#ifdef CONFIG_SMP
5extern void pnv_smp_init(void);
6#else
7static inline void pnv_smp_init(void) { }
8#endif
9
10#ifdef CONFIG_PCI
11extern void pnv_pci_init(void);
12#else
13static inline void pnv_pci_init(void) { }
14#endif
15
16#endif /* _POWERNV_H */
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
new file mode 100644
index 000000000000..467bd4ac6824
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -0,0 +1,196 @@
1/*
2 * PowerNV setup code.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#undef DEBUG
13
14#include <linux/cpu.h>
15#include <linux/errno.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/tty.h>
19#include <linux/reboot.h>
20#include <linux/init.h>
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/irq.h>
24#include <linux/seq_file.h>
25#include <linux/of.h>
26#include <linux/interrupt.h>
27#include <linux/bug.h>
28
29#include <asm/machdep.h>
30#include <asm/firmware.h>
31#include <asm/xics.h>
32#include <asm/rtas.h>
33#include <asm/opal.h>
34#include <asm/xics.h>
35
36#include "powernv.h"
37
38static void __init pnv_setup_arch(void)
39{
40 /* Initialize SMP */
41 pnv_smp_init();
42
43 /* Setup PCI */
44 pnv_pci_init();
45
46 /* Setup RTC and NVRAM callbacks */
47 if (firmware_has_feature(FW_FEATURE_OPAL))
48 opal_nvram_init();
49
50 /* Enable NAP mode */
51 powersave_nap = 1;
52
53 /* XXX PMCS */
54}
55
56static void __init pnv_init_early(void)
57{
58#ifdef CONFIG_HVC_OPAL
59 if (firmware_has_feature(FW_FEATURE_OPAL))
60 hvc_opal_init_early();
61 else
62#endif
63 add_preferred_console("hvc", 0, NULL);
64}
65
66static void __init pnv_init_IRQ(void)
67{
68 xics_init();
69
70 WARN_ON(!ppc_md.get_irq);
71}
72
73static void pnv_show_cpuinfo(struct seq_file *m)
74{
75 struct device_node *root;
76 const char *model = "";
77
78 root = of_find_node_by_path("/");
79 if (root)
80 model = of_get_property(root, "model", NULL);
81 seq_printf(m, "machine\t\t: PowerNV %s\n", model);
82 if (firmware_has_feature(FW_FEATURE_OPALv2))
83 seq_printf(m, "firmware\t: OPAL v2\n");
84 else if (firmware_has_feature(FW_FEATURE_OPAL))
85 seq_printf(m, "firmware\t: OPAL v1\n");
86 else
87 seq_printf(m, "firmware\t: BML\n");
88 of_node_put(root);
89}
90
91static void __noreturn pnv_restart(char *cmd)
92{
93 long rc = OPAL_BUSY;
94
95 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
96 rc = opal_cec_reboot();
97 if (rc == OPAL_BUSY_EVENT)
98 opal_poll_events(NULL);
99 else
100 mdelay(10);
101 }
102 for (;;)
103 opal_poll_events(NULL);
104}
105
106static void __noreturn pnv_power_off(void)
107{
108 long rc = OPAL_BUSY;
109
110 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
111 rc = opal_cec_power_down(0);
112 if (rc == OPAL_BUSY_EVENT)
113 opal_poll_events(NULL);
114 else
115 mdelay(10);
116 }
117 for (;;)
118 opal_poll_events(NULL);
119}
120
121static void __noreturn pnv_halt(void)
122{
123 pnv_power_off();
124}
125
126static void pnv_progress(char *s, unsigned short hex)
127{
128}
129
130#ifdef CONFIG_KEXEC
131static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
132{
133 xics_kexec_teardown_cpu(secondary);
134}
135#endif /* CONFIG_KEXEC */
136
137static void __init pnv_setup_machdep_opal(void)
138{
139 ppc_md.get_boot_time = opal_get_boot_time;
140 ppc_md.get_rtc_time = opal_get_rtc_time;
141 ppc_md.set_rtc_time = opal_set_rtc_time;
142 ppc_md.restart = pnv_restart;
143 ppc_md.power_off = pnv_power_off;
144 ppc_md.halt = pnv_halt;
145 ppc_md.machine_check_exception = opal_machine_check;
146}
147
148#ifdef CONFIG_PPC_POWERNV_RTAS
149static void __init pnv_setup_machdep_rtas(void)
150{
151 if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) {
152 ppc_md.get_boot_time = rtas_get_boot_time;
153 ppc_md.get_rtc_time = rtas_get_rtc_time;
154 ppc_md.set_rtc_time = rtas_set_rtc_time;
155 }
156 ppc_md.restart = rtas_restart;
157 ppc_md.power_off = rtas_power_off;
158 ppc_md.halt = rtas_halt;
159}
160#endif /* CONFIG_PPC_POWERNV_RTAS */
161
162static int __init pnv_probe(void)
163{
164 unsigned long root = of_get_flat_dt_root();
165
166 if (!of_flat_dt_is_compatible(root, "ibm,powernv"))
167 return 0;
168
169 hpte_init_native();
170
171 if (firmware_has_feature(FW_FEATURE_OPAL))
172 pnv_setup_machdep_opal();
173#ifdef CONFIG_PPC_POWERNV_RTAS
174 else if (rtas.base)
175 pnv_setup_machdep_rtas();
176#endif /* CONFIG_PPC_POWERNV_RTAS */
177
178 pr_debug("PowerNV detected !\n");
179
180 return 1;
181}
182
183define_machine(powernv) {
184 .name = "PowerNV",
185 .probe = pnv_probe,
186 .init_early = pnv_init_early,
187 .setup_arch = pnv_setup_arch,
188 .init_IRQ = pnv_init_IRQ,
189 .show_cpuinfo = pnv_show_cpuinfo,
190 .progress = pnv_progress,
191 .power_save = power7_idle,
192 .calibrate_decr = generic_calibrate_decr,
193#ifdef CONFIG_KEXEC
194 .kexec_cpu_down = pnv_kexec_cpu_down,
195#endif
196};
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
new file mode 100644
index 000000000000..e87736685243
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -0,0 +1,182 @@
1/*
2 * SMP support for PowerNV machines.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/sched.h>
15#include <linux/smp.h>
16#include <linux/interrupt.h>
17#include <linux/delay.h>
18#include <linux/init.h>
19#include <linux/spinlock.h>
20#include <linux/cpu.h>
21
22#include <asm/irq.h>
23#include <asm/smp.h>
24#include <asm/paca.h>
25#include <asm/machdep.h>
26#include <asm/cputable.h>
27#include <asm/firmware.h>
28#include <asm/system.h>
29#include <asm/rtas.h>
30#include <asm/vdso_datapage.h>
31#include <asm/cputhreads.h>
32#include <asm/xics.h>
33#include <asm/opal.h>
34
35#include "powernv.h"
36
37#ifdef DEBUG
38#include <asm/udbg.h>
39#define DBG(fmt...) udbg_printf(fmt)
40#else
41#define DBG(fmt...)
42#endif
43
44static void __cpuinit pnv_smp_setup_cpu(int cpu)
45{
46 if (cpu != boot_cpuid)
47 xics_setup_cpu();
48}
49
50static int pnv_smp_cpu_bootable(unsigned int nr)
51{
52 /* Special case - we inhibit secondary thread startup
53 * during boot if the user requests it.
54 */
55 if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
56 if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
57 return 0;
58 if (smt_enabled_at_boot
59 && cpu_thread_in_core(nr) >= smt_enabled_at_boot)
60 return 0;
61 }
62
63 return 1;
64}
65
66int __devinit pnv_smp_kick_cpu(int nr)
67{
68 unsigned int pcpu = get_hard_smp_processor_id(nr);
69 unsigned long start_here = __pa(*((unsigned long *)
70 generic_secondary_smp_init));
71 long rc;
72
73 BUG_ON(nr < 0 || nr >= NR_CPUS);
74
75 /* On OPAL v2 the CPU are still spinning inside OPAL itself,
76 * get them back now
77 */
78 if (firmware_has_feature(FW_FEATURE_OPALv2)) {
79 pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
80 rc = opal_start_cpu(pcpu, start_here);
81 if (rc != OPAL_SUCCESS)
82 pr_warn("OPAL Error %ld starting CPU %d\n",
83 rc, nr);
84 }
85 return smp_generic_kick_cpu(nr);
86}
87
88#ifdef CONFIG_HOTPLUG_CPU
89
90static int pnv_smp_cpu_disable(void)
91{
92 int cpu = smp_processor_id();
93
94 /* This is identical to pSeries... might consolidate by
95 * moving migrate_irqs_away to a ppc_md with default to
96 * the generic fixup_irqs. --BenH.
97 */
98 set_cpu_online(cpu, false);
99 vdso_data->processorCount--;
100 if (cpu == boot_cpuid)
101 boot_cpuid = cpumask_any(cpu_online_mask);
102 xics_migrate_irqs_away();
103 return 0;
104}
105
106static void pnv_smp_cpu_kill_self(void)
107{
108 unsigned int cpu;
109
110 /* If powersave_nap is enabled, use NAP mode, else just
111 * spin aimlessly
112 */
113 if (!powersave_nap) {
114 generic_mach_cpu_die();
115 return;
116 }
117
118 /* Standard hot unplug procedure */
119 local_irq_disable();
120 idle_task_exit();
121 current->active_mm = NULL; /* for sanity */
122 cpu = smp_processor_id();
123 DBG("CPU%d offline\n", cpu);
124 generic_set_cpu_dead(cpu);
125 smp_wmb();
126
127 /* We don't want to take decrementer interrupts while we are offline,
128 * so clear LPCR:PECE1. We keep PECE2 enabled.
129 */
130 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
131 while (!generic_check_cpu_restart(cpu)) {
132 power7_idle();
133 if (!generic_check_cpu_restart(cpu)) {
134 DBG("CPU%d Unexpected exit while offline !\n", cpu);
135 /* We may be getting an IPI, so we re-enable
136 * interrupts to process it, it will be ignored
137 * since we aren't online (hopefully)
138 */
139 local_irq_enable();
140 local_irq_disable();
141 }
142 }
143 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
144 DBG("CPU%d coming online...\n", cpu);
145}
146
147#endif /* CONFIG_HOTPLUG_CPU */
148
149static struct smp_ops_t pnv_smp_ops = {
150 .message_pass = smp_muxed_ipi_message_pass,
151 .cause_ipi = NULL, /* Filled at runtime by xics_smp_probe() */
152 .probe = xics_smp_probe,
153 .kick_cpu = pnv_smp_kick_cpu,
154 .setup_cpu = pnv_smp_setup_cpu,
155 .cpu_bootable = pnv_smp_cpu_bootable,
156#ifdef CONFIG_HOTPLUG_CPU
157 .cpu_disable = pnv_smp_cpu_disable,
158 .cpu_die = generic_cpu_die,
159#endif /* CONFIG_HOTPLUG_CPU */
160};
161
162/* This is called very early during platform setup_arch */
163void __init pnv_smp_init(void)
164{
165 smp_ops = &pnv_smp_ops;
166
167 /* XXX We don't yet have a proper entry point from HAL, for
168 * now we rely on kexec-style entry from BML
169 */
170
171#ifdef CONFIG_PPC_RTAS
172 /* Non-lpar has additional take/give timebase */
173 if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
174 smp_ops->give_timebase = rtas_give_timebase;
175 smp_ops->take_timebase = rtas_take_timebase;
176 }
177#endif /* CONFIG_PPC_RTAS */
178
179#ifdef CONFIG_HOTPLUG_CPU
180 ppc_md.cpu_die = pnv_smp_cpu_kill_self;
181#endif
182}
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index dfe316b161a9..476d9d9b2405 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -148,4 +148,16 @@ config PS3_LPM
148 profiling support of the Cell processor with programs like 148 profiling support of the Cell processor with programs like
149 oprofile and perfmon2, then say Y or M, otherwise say N. 149 oprofile and perfmon2, then say Y or M, otherwise say N.
150 150
151config PS3GELIC_UDBG
152 bool "PS3 udbg output via UDP broadcasts on Ethernet"
153 depends on PPC_PS3
154 help
155 Enables udbg early debugging output by sending broadcast UDP
156 via the Ethernet port (UDP port number 18194).
157
158 This driver uses a trivial implementation and is independent
159 from the main network driver.
160
161 If in doubt, say N here.
162
151endmenu 163endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index ac1bdf844eca..02b9e636dab7 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
2obj-y += interrupt.o exports.o os-area.o 2obj-y += interrupt.o exports.o os-area.o
3obj-y += system-bus.o 3obj-y += system-bus.o
4 4
5obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
5obj-$(CONFIG_SMP) += smp.o 6obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_SPU_BASE) += spu.o 7obj-$(CONFIG_SPU_BASE) += spu.o
7obj-y += device-init.o 8obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
new file mode 100644
index 000000000000..20b46a19a48f
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -0,0 +1,273 @@
1/*
2 * udbg debug output routine via GELIC UDP broadcasts
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2006, 2007 Sony Corporation
6 * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
7 * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 */
15
16#include <asm/io.h>
17#include <asm/udbg.h>
18#include <asm/lv1call.h>
19
20#define GELIC_BUS_ID 1
21#define GELIC_DEVICE_ID 0
22#define GELIC_DEBUG_PORT 18194
23#define GELIC_MAX_MESSAGE_SIZE 1000
24
25#define GELIC_LV1_GET_MAC_ADDRESS 1
26#define GELIC_LV1_GET_VLAN_ID 4
27#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
28
29#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
30#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
31
32#define GELIC_DESCR_TX_DMA_IKE 0x00080000
33#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
34#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
35
36#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
37 GELIC_DESCR_TX_DMA_IKE | \
38 GELIC_DESCR_TX_DMA_NO_CHKSUM)
39
40static u64 bus_addr;
41
42struct gelic_descr {
43 /* as defined by the hardware */
44 __be32 buf_addr;
45 __be32 buf_size;
46 __be32 next_descr_addr;
47 __be32 dmac_cmd_status;
48 __be32 result_size;
49 __be32 valid_size; /* all zeroes for tx */
50 __be32 data_status;
51 __be32 data_error; /* all zeroes for tx */
52} __attribute__((aligned(32)));
53
54struct debug_block {
55 struct gelic_descr descr;
56 u8 pkt[1520];
57} __packed;
58
59struct ethhdr {
60 u8 dest[6];
61 u8 src[6];
62 u16 type;
63} __packed;
64
65struct vlantag {
66 u16 vlan;
67 u16 subtype;
68} __packed;
69
70struct iphdr {
71 u8 ver_len;
72 u8 dscp_ecn;
73 u16 total_length;
74 u16 ident;
75 u16 frag_off_flags;
76 u8 ttl;
77 u8 proto;
78 u16 checksum;
79 u32 src;
80 u32 dest;
81} __packed;
82
83struct udphdr {
84 u16 src;
85 u16 dest;
86 u16 len;
87 u16 checksum;
88} __packed;
89
90static __iomem struct ethhdr *h_eth;
91static __iomem struct vlantag *h_vlan;
92static __iomem struct iphdr *h_ip;
93static __iomem struct udphdr *h_udp;
94
95static __iomem char *pmsg;
96static __iomem char *pmsgc;
97
98static __iomem struct debug_block dbg __attribute__((aligned(32)));
99
100static int header_size;
101
102static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
103 u64 *real_bus_addr)
104{
105 s64 result;
106 u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
107 u64 real_end = real_addr + len;
108 u64 map_start = real_addr & ~0xfff;
109 u64 map_end = (real_end + 0xfff) & ~0xfff;
110 u64 bus_addr = 0;
111
112 u64 flags = 0xf800000000000000UL;
113
114 result = lv1_allocate_device_dma_region(bus_id, dev_id,
115 map_end - map_start, 12, 0,
116 &bus_addr);
117 if (result)
118 lv1_panic(0);
119
120 result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
121 bus_addr, map_end - map_start,
122 flags);
123 if (result)
124 lv1_panic(0);
125
126 *real_bus_addr = bus_addr + real_addr - map_start;
127}
128
129static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
130{
131 s64 result;
132 u64 real_bus_addr;
133
134 real_bus_addr = bus_addr & ~0xfff;
135 len += bus_addr - real_bus_addr;
136 len = (len + 0xfff) & ~0xfff;
137
138 result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
139 len);
140 if (result)
141 return result;
142
143 return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
144}
145
146static void gelic_debug_init(void)
147{
148 s64 result;
149 u64 v2;
150 u64 mac;
151 u64 vlan_id;
152
153 result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
154 if (result)
155 lv1_panic(0);
156
157 map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
158 &bus_addr);
159
160 memset(&dbg, 0, sizeof(dbg));
161
162 dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
163
164 wmb();
165
166 result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
167 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
168 &mac, &v2);
169 if (result)
170 lv1_panic(0);
171
172 mac <<= 16;
173
174 h_eth = (struct ethhdr *)dbg.pkt;
175
176 memset(&h_eth->dest, 0xff, 6);
177 memcpy(&h_eth->src, &mac, 6);
178
179 header_size = sizeof(struct ethhdr);
180
181 result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
182 GELIC_LV1_GET_VLAN_ID,
183 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
184 &vlan_id, &v2);
185 if (!result) {
186 h_eth->type = 0x8100;
187
188 header_size += sizeof(struct vlantag);
189 h_vlan = (struct vlantag *)(h_eth + 1);
190 h_vlan->vlan = vlan_id;
191 h_vlan->subtype = 0x0800;
192 h_ip = (struct iphdr *)(h_vlan + 1);
193 } else {
194 h_eth->type = 0x0800;
195 h_ip = (struct iphdr *)(h_eth + 1);
196 }
197
198 header_size += sizeof(struct iphdr);
199 h_ip->ver_len = 0x45;
200 h_ip->ttl = 10;
201 h_ip->proto = 0x11;
202 h_ip->src = 0x00000000;
203 h_ip->dest = 0xffffffff;
204
205 header_size += sizeof(struct udphdr);
206 h_udp = (struct udphdr *)(h_ip + 1);
207 h_udp->src = GELIC_DEBUG_PORT;
208 h_udp->dest = GELIC_DEBUG_PORT;
209
210 pmsgc = pmsg = (char *)(h_udp + 1);
211}
212
213static void gelic_debug_shutdown(void)
214{
215 if (bus_addr)
216 unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
217 bus_addr, sizeof(dbg));
218 lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
219}
220
221static void gelic_sendbuf(int msgsize)
222{
223 u16 *p;
224 u32 sum;
225 int i;
226
227 dbg.descr.buf_size = header_size + msgsize;
228 h_ip->total_length = msgsize + sizeof(struct udphdr) +
229 sizeof(struct iphdr);
230 h_udp->len = msgsize + sizeof(struct udphdr);
231
232 h_ip->checksum = 0;
233 sum = 0;
234 p = (u16 *)h_ip;
235 for (i = 0; i < 5; i++)
236 sum += *p++;
237 h_ip->checksum = ~(sum + (sum >> 16));
238
239 dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
240 GELIC_DESCR_TX_DMA_FRAME_TAIL;
241 dbg.descr.result_size = 0;
242 dbg.descr.data_status = 0;
243
244 wmb();
245
246 lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
247
248 while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
249 GELIC_DESCR_DMA_CARDOWNED)
250 cpu_relax();
251}
252
253static void ps3gelic_udbg_putc(char ch)
254{
255 *pmsgc++ = ch;
256 if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
257 gelic_sendbuf(pmsgc-pmsg);
258 pmsgc = pmsg;
259 }
260}
261
262void __init udbg_init_ps3gelic(void)
263{
264 gelic_debug_init();
265 udbg_putc = ps3gelic_udbg_putc;
266}
267
268void udbg_shutdown_ps3gelic(void)
269{
270 udbg_putc = NULL;
271 gelic_debug_shutdown();
272}
273EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 23083c397528..688141c76e03 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -695,12 +695,18 @@ static int ps3_dma_supported(struct device *_dev, u64 mask)
695 return mask >= DMA_BIT_MASK(32); 695 return mask >= DMA_BIT_MASK(32);
696} 696}
697 697
698static u64 ps3_dma_get_required_mask(struct device *_dev)
699{
700 return DMA_BIT_MASK(32);
701}
702
698static struct dma_map_ops ps3_sb_dma_ops = { 703static struct dma_map_ops ps3_sb_dma_ops = {
699 .alloc_coherent = ps3_alloc_coherent, 704 .alloc_coherent = ps3_alloc_coherent,
700 .free_coherent = ps3_free_coherent, 705 .free_coherent = ps3_free_coherent,
701 .map_sg = ps3_sb_map_sg, 706 .map_sg = ps3_sb_map_sg,
702 .unmap_sg = ps3_sb_unmap_sg, 707 .unmap_sg = ps3_sb_unmap_sg,
703 .dma_supported = ps3_dma_supported, 708 .dma_supported = ps3_dma_supported,
709 .get_required_mask = ps3_dma_get_required_mask,
704 .map_page = ps3_sb_map_page, 710 .map_page = ps3_sb_map_page,
705 .unmap_page = ps3_unmap_page, 711 .unmap_page = ps3_unmap_page,
706}; 712};
@@ -711,6 +717,7 @@ static struct dma_map_ops ps3_ioc0_dma_ops = {
711 .map_sg = ps3_ioc0_map_sg, 717 .map_sg = ps3_ioc0_map_sg,
712 .unmap_sg = ps3_ioc0_unmap_sg, 718 .unmap_sg = ps3_ioc0_unmap_sg,
713 .dma_supported = ps3_dma_supported, 719 .dma_supported = ps3_dma_supported,
720 .get_required_mask = ps3_dma_get_required_mask,
714 .map_page = ps3_ioc0_map_page, 721 .map_page = ps3_ioc0_map_page,
715 .unmap_page = ps3_unmap_page, 722 .unmap_page = ps3_unmap_page,
716}; 723};
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 05cf4769b88c..c81f6bb9c10f 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -15,6 +15,7 @@ config PPC_PSERIES
15 select PPC_UDBG_16550 15 select PPC_UDBG_16550
16 select PPC_NATIVE 16 select PPC_NATIVE
17 select PPC_PCI_CHOICE if EXPERT 17 select PPC_PCI_CHOICE if EXPERT
18 select ZLIB_DEFLATE
18 default y 19 default y
19 20
20config PPC_SPLPAR 21config PPC_SPLPAR
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index e9be25bc571b..0f1b706506ed 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -112,6 +112,7 @@ void dlpar_free_cc_nodes(struct device_node *dn)
112 dlpar_free_one_cc_node(dn); 112 dlpar_free_one_cc_node(dn);
113} 113}
114 114
115#define COMPLETE 0
115#define NEXT_SIBLING 1 116#define NEXT_SIBLING 1
116#define NEXT_CHILD 2 117#define NEXT_CHILD 2
117#define NEXT_PROPERTY 3 118#define NEXT_PROPERTY 3
@@ -158,6 +159,9 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
158 spin_unlock(&rtas_data_buf_lock); 159 spin_unlock(&rtas_data_buf_lock);
159 160
160 switch (rc) { 161 switch (rc) {
162 case COMPLETE:
163 break;
164
161 case NEXT_SIBLING: 165 case NEXT_SIBLING:
162 dn = dlpar_parse_cc_node(ccwa); 166 dn = dlpar_parse_cc_node(ccwa);
163 if (!dn) 167 if (!dn)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index ada6e07532ec..d42f37d8a440 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1338,7 +1338,7 @@ static const struct file_operations proc_eeh_operations = {
1338static int __init eeh_init_proc(void) 1338static int __init eeh_init_proc(void)
1339{ 1339{
1340 if (machine_is(pseries)) 1340 if (machine_is(pseries))
1341 proc_create("ppc64/eeh", 0, NULL, &proc_eeh_operations); 1341 proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
1342 return 0; 1342 return 0;
1343} 1343}
1344__initcall(eeh_init_proc); 1344__initcall(eeh_init_proc);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 01faab9456ca..5905a3b9f7e6 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -939,14 +939,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
939 if (ret) { 939 if (ret) {
940 dev_info(&dev->dev, "failed to map direct window for %s: %d\n", 940 dev_info(&dev->dev, "failed to map direct window for %s: %d\n",
941 dn->full_name, ret); 941 dn->full_name, ret);
942 goto out_clear_window; 942 goto out_free_window;
943 } 943 }
944 944
945 ret = prom_add_property(pdn, win64); 945 ret = prom_add_property(pdn, win64);
946 if (ret) { 946 if (ret) {
947 dev_err(&dev->dev, "unable to add dma window property for %s: %d", 947 dev_err(&dev->dev, "unable to add dma window property for %s: %d",
948 pdn->full_name, ret); 948 pdn->full_name, ret);
949 goto out_clear_window; 949 goto out_free_window;
950 } 950 }
951 951
952 window->device = pdn; 952 window->device = pdn;
@@ -958,6 +958,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
958 dma_addr = of_read_number(&create.addr_hi, 2); 958 dma_addr = of_read_number(&create.addr_hi, 2);
959 goto out_unlock; 959 goto out_unlock;
960 960
961out_free_window:
962 kfree(window);
963
961out_clear_window: 964out_clear_window:
962 remove_ddw(pdn); 965 remove_ddw(pdn);
963 966
@@ -1077,12 +1080,38 @@ check_mask:
1077 return 0; 1080 return 0;
1078} 1081}
1079 1082
1083static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
1084{
1085 if (!dev->dma_mask)
1086 return 0;
1087
1088 if (!disable_ddw && dev_is_pci(dev)) {
1089 struct pci_dev *pdev = to_pci_dev(dev);
1090 struct device_node *dn;
1091
1092 dn = pci_device_to_OF_node(pdev);
1093
1094 /* search upwards for ibm,dma-window */
1095 for (; dn && PCI_DN(dn) && !PCI_DN(dn)->iommu_table;
1096 dn = dn->parent)
1097 if (of_get_property(dn, "ibm,dma-window", NULL))
1098 break;
1099 /* if there is a ibm,ddw-applicable property require 64 bits */
1100 if (dn && PCI_DN(dn) &&
1101 of_get_property(dn, "ibm,ddw-applicable", NULL))
1102 return DMA_BIT_MASK(64);
1103 }
1104
1105 return dma_iommu_ops.get_required_mask(dev);
1106}
1107
1080#else /* CONFIG_PCI */ 1108#else /* CONFIG_PCI */
1081#define pci_dma_bus_setup_pSeries NULL 1109#define pci_dma_bus_setup_pSeries NULL
1082#define pci_dma_dev_setup_pSeries NULL 1110#define pci_dma_dev_setup_pSeries NULL
1083#define pci_dma_bus_setup_pSeriesLP NULL 1111#define pci_dma_bus_setup_pSeriesLP NULL
1084#define pci_dma_dev_setup_pSeriesLP NULL 1112#define pci_dma_dev_setup_pSeriesLP NULL
1085#define dma_set_mask_pSeriesLP NULL 1113#define dma_set_mask_pSeriesLP NULL
1114#define dma_get_required_mask_pSeriesLP NULL
1086#endif /* !CONFIG_PCI */ 1115#endif /* !CONFIG_PCI */
1087 1116
1088static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, 1117static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
@@ -1186,6 +1215,7 @@ void iommu_init_early_pSeries(void)
1186 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; 1215 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
1187 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; 1216 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
1188 ppc_md.dma_set_mask = dma_set_mask_pSeriesLP; 1217 ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
1218 ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP;
1189 } else { 1219 } else {
1190 ppc_md.tce_build = tce_build_pSeries; 1220 ppc_md.tce_build = tce_build_pSeries;
1191 ppc_md.tce_free = tce_free_pSeries; 1221 ppc_md.tce_free = tce_free_pSeries;
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 00cc3a094885..a76b22844d18 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -18,6 +18,8 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/kmsg_dump.h> 20#include <linux/kmsg_dump.h>
21#include <linux/ctype.h>
22#include <linux/zlib.h>
21#include <asm/uaccess.h> 23#include <asm/uaccess.h>
22#include <asm/nvram.h> 24#include <asm/nvram.h>
23#include <asm/rtas.h> 25#include <asm/rtas.h>
@@ -78,8 +80,41 @@ static struct kmsg_dumper nvram_kmsg_dumper = {
78#define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */ 80#define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */
79static unsigned long last_unread_rtas_event; /* timestamp */ 81static unsigned long last_unread_rtas_event; /* timestamp */
80 82
81/* We preallocate oops_buf during init to avoid kmalloc during oops/panic. */ 83/*
82static char *oops_buf; 84 * For capturing and compressing an oops or panic report...
85
86 * big_oops_buf[] holds the uncompressed text we're capturing.
87 *
88 * oops_buf[] holds the compressed text, preceded by a prefix.
89 * The prefix is just a u16 holding the length of the compressed* text.
90 * (*Or uncompressed, if compression fails.) oops_buf[] gets written
91 * to NVRAM.
92 *
93 * oops_len points to the prefix. oops_data points to the compressed text.
94 *
95 * +- oops_buf
96 * | +- oops_data
97 * v v
98 * +------------+-----------------------------------------------+
99 * | length | text |
100 * | (2 bytes) | (oops_data_sz bytes) |
101 * +------------+-----------------------------------------------+
102 * ^
103 * +- oops_len
104 *
105 * We preallocate these buffers during init to avoid kmalloc during oops/panic.
106 */
107static size_t big_oops_buf_sz;
108static char *big_oops_buf, *oops_buf;
109static u16 *oops_len;
110static char *oops_data;
111static size_t oops_data_sz;
112
113/* Compression parameters */
114#define COMPR_LEVEL 6
115#define WINDOW_BITS 12
116#define MEM_LEVEL 4
117static struct z_stream_s stream;
83 118
84static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) 119static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
85{ 120{
@@ -387,11 +422,44 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
387 sizeof(rtas_log_partition)); 422 sizeof(rtas_log_partition));
388 } 423 }
389 oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL); 424 oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL);
425 if (!oops_buf) {
426 pr_err("nvram: No memory for %s partition\n",
427 oops_log_partition.name);
428 return;
429 }
430 oops_len = (u16*) oops_buf;
431 oops_data = oops_buf + sizeof(u16);
432 oops_data_sz = oops_log_partition.size - sizeof(u16);
433
434 /*
435 * Figure compression (preceded by elimination of each line's <n>
436 * severity prefix) will reduce the oops/panic report to at most
437 * 45% of its original size.
438 */
439 big_oops_buf_sz = (oops_data_sz * 100) / 45;
440 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
441 if (big_oops_buf) {
442 stream.workspace = kmalloc(zlib_deflate_workspacesize(
443 WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
444 if (!stream.workspace) {
445 pr_err("nvram: No memory for compression workspace; "
446 "skipping compression of %s partition data\n",
447 oops_log_partition.name);
448 kfree(big_oops_buf);
449 big_oops_buf = NULL;
450 }
451 } else {
452 pr_err("No memory for uncompressed %s data; "
453 "skipping compression\n", oops_log_partition.name);
454 stream.workspace = NULL;
455 }
456
390 rc = kmsg_dump_register(&nvram_kmsg_dumper); 457 rc = kmsg_dump_register(&nvram_kmsg_dumper);
391 if (rc != 0) { 458 if (rc != 0) {
392 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); 459 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);
393 kfree(oops_buf); 460 kfree(oops_buf);
394 return; 461 kfree(big_oops_buf);
462 kfree(stream.workspace);
395 } 463 }
396} 464}
397 465
@@ -473,7 +541,83 @@ static int clobbering_unread_rtas_event(void)
473 NVRAM_RTAS_READ_TIMEOUT); 541 NVRAM_RTAS_READ_TIMEOUT);
474} 542}
475 543
476/* our kmsg_dump callback */ 544/* Squeeze out each line's <n> severity prefix. */
545static size_t elide_severities(char *buf, size_t len)
546{
547 char *in, *out, *buf_end = buf + len;
548 /* Assume a <n> at the very beginning marks the start of a line. */
549 int newline = 1;
550
551 in = out = buf;
552 while (in < buf_end) {
553 if (newline && in+3 <= buf_end &&
554 *in == '<' && isdigit(in[1]) && in[2] == '>') {
555 in += 3;
556 newline = 0;
557 } else {
558 newline = (*in == '\n');
559 *out++ = *in++;
560 }
561 }
562 return out - buf;
563}
564
565/* Derived from logfs_compress() */
566static int nvram_compress(const void *in, void *out, size_t inlen,
567 size_t outlen)
568{
569 int err, ret;
570
571 ret = -EIO;
572 err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
573 MEM_LEVEL, Z_DEFAULT_STRATEGY);
574 if (err != Z_OK)
575 goto error;
576
577 stream.next_in = in;
578 stream.avail_in = inlen;
579 stream.total_in = 0;
580 stream.next_out = out;
581 stream.avail_out = outlen;
582 stream.total_out = 0;
583
584 err = zlib_deflate(&stream, Z_FINISH);
585 if (err != Z_STREAM_END)
586 goto error;
587
588 err = zlib_deflateEnd(&stream);
589 if (err != Z_OK)
590 goto error;
591
592 if (stream.total_out >= stream.total_in)
593 goto error;
594
595 ret = stream.total_out;
596error:
597 return ret;
598}
599
600/* Compress the text from big_oops_buf into oops_buf. */
601static int zip_oops(size_t text_len)
602{
603 int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
604 oops_data_sz);
605 if (zipped_len < 0) {
606 pr_err("nvram: compression failed; returned %d\n", zipped_len);
607 pr_err("nvram: logging uncompressed oops/panic report\n");
608 return -1;
609 }
610 *oops_len = (u16) zipped_len;
611 return 0;
612}
613
614/*
615 * This is our kmsg_dump callback, called after an oops or panic report
616 * has been written to the printk buffer. We want to capture as much
617 * of the printk buffer as possible. First, capture as much as we can
618 * that we think will compress sufficiently to fit in the lnx,oops-log
619 * partition. If that's too much, go back and capture uncompressed text.
620 */
477static void oops_to_nvram(struct kmsg_dumper *dumper, 621static void oops_to_nvram(struct kmsg_dumper *dumper,
478 enum kmsg_dump_reason reason, 622 enum kmsg_dump_reason reason,
479 const char *old_msgs, unsigned long old_len, 623 const char *old_msgs, unsigned long old_len,
@@ -482,6 +626,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
482 static unsigned int oops_count = 0; 626 static unsigned int oops_count = 0;
483 static bool panicking = false; 627 static bool panicking = false;
484 size_t text_len; 628 size_t text_len;
629 unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
630 int rc = -1;
485 631
486 switch (reason) { 632 switch (reason) {
487 case KMSG_DUMP_RESTART: 633 case KMSG_DUMP_RESTART:
@@ -509,8 +655,19 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
509 if (clobbering_unread_rtas_event()) 655 if (clobbering_unread_rtas_event())
510 return; 656 return;
511 657
512 text_len = capture_last_msgs(old_msgs, old_len, new_msgs, new_len, 658 if (big_oops_buf) {
513 oops_buf, oops_log_partition.size); 659 text_len = capture_last_msgs(old_msgs, old_len,
660 new_msgs, new_len, big_oops_buf, big_oops_buf_sz);
661 text_len = elide_severities(big_oops_buf, text_len);
662 rc = zip_oops(text_len);
663 }
664 if (rc != 0) {
665 text_len = capture_last_msgs(old_msgs, old_len,
666 new_msgs, new_len, oops_data, oops_data_sz);
667 err_type = ERR_TYPE_KERNEL_PANIC;
668 *oops_len = (u16) text_len;
669 }
670
514 (void) nvram_write_os_partition(&oops_log_partition, oops_buf, 671 (void) nvram_write_os_partition(&oops_log_partition, oops_buf,
515 (int) text_len, ERR_TYPE_KERNEL_PANIC, ++oops_count); 672 (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
516} 673}
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
index c3c48eb62cc1..f4fb837873fb 100644
--- a/arch/powerpc/platforms/wsp/Kconfig
+++ b/arch/powerpc/platforms/wsp/Kconfig
@@ -1,5 +1,12 @@
1config PPC_WSP 1config PPC_WSP
2 bool 2 bool
3 select PPC_A2
4 select PPC_SCOM
5 select PPC_XICS
6 select PPC_ICP_NATIVE
7 select PCI
8 select PPC_IO_WORKAROUNDS if PCI
9 select PPC_INDIRECT_PIO if PCI
3 default n 10 default n
4 11
5menu "WSP platform selection" 12menu "WSP platform selection"
@@ -7,13 +14,9 @@ menu "WSP platform selection"
7 14
8config PPC_PSR2 15config PPC_PSR2
9 bool "PSR-2 platform" 16 bool "PSR-2 platform"
10 select PPC_A2
11 select GENERIC_TBSYNC 17 select GENERIC_TBSYNC
12 select PPC_SCOM
13 select EPAPR_BOOT 18 select EPAPR_BOOT
14 select PPC_WSP 19 select PPC_WSP
15 select PPC_XICS
16 select PPC_ICP_NATIVE
17 default y 20 default y
18 21
19endmenu 22endmenu
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile
index 095be73d6cd4..a1486b436f02 100644
--- a/arch/powerpc/platforms/wsp/Makefile
+++ b/arch/powerpc/platforms/wsp/Makefile
@@ -4,3 +4,5 @@ obj-y += setup.o ics.o
4obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o 4obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o
5obj-$(CONFIG_PPC_WSP) += scom_wsp.o 5obj-$(CONFIG_PPC_WSP) += scom_wsp.o
6obj-$(CONFIG_SMP) += smp.o scom_smp.o 6obj-$(CONFIG_SMP) += smp.o scom_smp.o
7obj-$(CONFIG_PCI) += wsp_pci.o
8obj-$(CONFIG_PCI_MSI) += msi.o \ No newline at end of file
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c
index e53bd9e7b125..576874392543 100644
--- a/arch/powerpc/platforms/wsp/ics.c
+++ b/arch/powerpc/platforms/wsp/ics.c
@@ -710,3 +710,51 @@ void __init wsp_init_irq(void)
710 /* We need to patch our irq chip's EOI to point to the right ICP */ 710 /* We need to patch our irq chip's EOI to point to the right ICP */
711 wsp_irq_chip.irq_eoi = icp_ops->eoi; 711 wsp_irq_chip.irq_eoi = icp_ops->eoi;
712} 712}
713
714#ifdef CONFIG_PCI_MSI
715static void wsp_ics_msi_unmask_irq(struct irq_data *d)
716{
717 wsp_chip_unmask_irq(d);
718 unmask_msi_irq(d);
719}
720
721static unsigned int wsp_ics_msi_startup(struct irq_data *d)
722{
723 wsp_ics_msi_unmask_irq(d);
724 return 0;
725}
726
727static void wsp_ics_msi_mask_irq(struct irq_data *d)
728{
729 mask_msi_irq(d);
730 wsp_chip_mask_irq(d);
731}
732
733/*
734 * we do it this way because we reassinge default EOI handling in
735 * irq_init() above
736 */
737static void wsp_ics_eoi(struct irq_data *data)
738{
739 wsp_irq_chip.irq_eoi(data);
740}
741
742static struct irq_chip wsp_ics_msi = {
743 .name = "WSP ICS MSI",
744 .irq_startup = wsp_ics_msi_startup,
745 .irq_mask = wsp_ics_msi_mask_irq,
746 .irq_unmask = wsp_ics_msi_unmask_irq,
747 .irq_eoi = wsp_ics_eoi,
748 .irq_set_affinity = wsp_chip_set_affinity
749};
750
751void wsp_ics_set_msi_chip(unsigned int irq)
752{
753 irq_set_chip(irq, &wsp_ics_msi);
754}
755
756void wsp_ics_set_std_chip(unsigned int irq)
757{
758 irq_set_chip(irq, &wsp_irq_chip);
759}
760#endif /* CONFIG_PCI_MSI */
diff --git a/arch/powerpc/platforms/wsp/ics.h b/arch/powerpc/platforms/wsp/ics.h
index e34d53102640..07b644e0cf97 100644
--- a/arch/powerpc/platforms/wsp/ics.h
+++ b/arch/powerpc/platforms/wsp/ics.h
@@ -17,4 +17,9 @@ extern void wsp_init_irq(void);
17extern int wsp_ics_alloc_irq(struct device_node *dn, int num); 17extern int wsp_ics_alloc_irq(struct device_node *dn, int num);
18extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq); 18extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq);
19 19
20#ifdef CONFIG_PCI_MSI
21extern void wsp_ics_set_msi_chip(unsigned int irq);
22extern void wsp_ics_set_std_chip(unsigned int irq);
23#endif /* CONFIG_PCI_MSI */
24
20#endif /* __ICS_H */ 25#endif /* __ICS_H */
diff --git a/arch/powerpc/platforms/wsp/msi.c b/arch/powerpc/platforms/wsp/msi.c
new file mode 100644
index 000000000000..380882f27add
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/msi.c
@@ -0,0 +1,102 @@
1/*
2 * Copyright 2011 Michael Ellerman, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/kernel.h>
11#include <linux/pci.h>
12#include <linux/msi.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15
16#include "msi.h"
17#include "ics.h"
18#include "wsp_pci.h"
19
20/* Magic addresses for 32 & 64-bit MSIs with hardcoded MVE 0 */
21#define MSI_ADDR_32 0xFFFF0000ul
22#define MSI_ADDR_64 0x1000000000000000ul
23
24int wsp_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
25{
26 struct pci_controller *phb;
27 struct msi_desc *entry;
28 struct msi_msg msg;
29 unsigned int virq;
30 int hwirq;
31
32 phb = pci_bus_to_host(dev->bus);
33 if (!phb)
34 return -ENOENT;
35
36 entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
37 if (entry->msi_attrib.is_64) {
38 msg.address_lo = 0;
39 msg.address_hi = MSI_ADDR_64 >> 32;
40 } else {
41 msg.address_lo = MSI_ADDR_32;
42 msg.address_hi = 0;
43 }
44
45 list_for_each_entry(entry, &dev->msi_list, list) {
46 hwirq = wsp_ics_alloc_irq(phb->dn, 1);
47 if (hwirq < 0) {
48 dev_warn(&dev->dev, "wsp_msi: hwirq alloc failed!\n");
49 return hwirq;
50 }
51
52 virq = irq_create_mapping(NULL, hwirq);
53 if (virq == NO_IRQ) {
54 dev_warn(&dev->dev, "wsp_msi: virq alloc failed!\n");
55 return -1;
56 }
57
58 dev_dbg(&dev->dev, "wsp_msi: allocated irq %#x/%#x\n",
59 hwirq, virq);
60
61 wsp_ics_set_msi_chip(virq);
62 irq_set_msi_desc(virq, entry);
63 msg.data = hwirq & XIVE_ADDR_MASK;
64 write_msi_msg(virq, &msg);
65 }
66
67 return 0;
68}
69
70void wsp_teardown_msi_irqs(struct pci_dev *dev)
71{
72 struct pci_controller *phb;
73 struct msi_desc *entry;
74 int hwirq;
75
76 phb = pci_bus_to_host(dev->bus);
77
78 dev_dbg(&dev->dev, "wsp_msi: tearing down msi irqs\n");
79
80 list_for_each_entry(entry, &dev->msi_list, list) {
81 if (entry->irq == NO_IRQ)
82 continue;
83
84 irq_set_msi_desc(entry->irq, NULL);
85 wsp_ics_set_std_chip(entry->irq);
86
87 hwirq = virq_to_hw(entry->irq);
88 /* In this order to avoid racing with irq_create_mapping() */
89 irq_dispose_mapping(entry->irq);
90 wsp_ics_free_irq(phb->dn, hwirq);
91 }
92}
93
94void wsp_setup_phb_msi(struct pci_controller *phb)
95{
96 /* Create a single MVE at offset 0 that matches everything */
97 out_be64(phb->cfg_data + PCIE_REG_IODA_ADDR, PCIE_REG_IODA_AD_TBL_MVT);
98 out_be64(phb->cfg_data + PCIE_REG_IODA_DATA0, 1ull << 63);
99
100 ppc_md.setup_msi_irqs = wsp_setup_msi_irqs;
101 ppc_md.teardown_msi_irqs = wsp_teardown_msi_irqs;
102}
diff --git a/arch/powerpc/platforms/wsp/msi.h b/arch/powerpc/platforms/wsp/msi.h
new file mode 100644
index 000000000000..0ab27b71b24d
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/msi.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright 2011 Michael Ellerman, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef __WSP_MSI_H
11#define __WSP_MSI_H
12
13#ifdef CONFIG_PCI_MSI
14extern void wsp_setup_phb_msi(struct pci_controller *phb);
15#else
16static inline void wsp_setup_phb_msi(struct pci_controller *phb) { }
17#endif
18
19#endif /* __WSP_MSI_H */
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c
index 40f28916ff6c..166f2e4b4bee 100644
--- a/arch/powerpc/platforms/wsp/psr2.c
+++ b/arch/powerpc/platforms/wsp/psr2.c
@@ -63,6 +63,10 @@ static void __init psr2_setup_arch(void)
63#ifdef CONFIG_SMP 63#ifdef CONFIG_SMP
64 a2_setup_smp(); 64 a2_setup_smp();
65#endif 65#endif
66#ifdef CONFIG_PCI
67 wsp_setup_pci();
68#endif
69
66} 70}
67 71
68static int __init psr2_probe(void) 72static int __init psr2_probe(void)
diff --git a/arch/powerpc/platforms/wsp/wsp.h b/arch/powerpc/platforms/wsp/wsp.h
index 7c3e087fd2f2..33479818f62a 100644
--- a/arch/powerpc/platforms/wsp/wsp.h
+++ b/arch/powerpc/platforms/wsp/wsp.h
@@ -3,6 +3,9 @@
3 3
4#include <asm/wsp.h> 4#include <asm/wsp.h>
5 5
6/* Devtree compatible strings for major devices */
7#define PCIE_COMPATIBLE "ibm,wsp-pciex"
8
6extern void wsp_setup_pci(void); 9extern void wsp_setup_pci(void);
7extern void scom_init_wsp(void); 10extern void scom_init_wsp(void);
8 11
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c
new file mode 100644
index 000000000000..e0262cd0e2d3
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/wsp_pci.c
@@ -0,0 +1,1133 @@
1/*
2 * Copyright 2010 Ben Herrenschmidt, IBM Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#define DEBUG
11
12#include <linux/kernel.h>
13#include <linux/pci.h>
14#include <linux/delay.h>
15#include <linux/string.h>
16#include <linux/init.h>
17#include <linux/bootmem.h>
18#include <linux/irq.h>
19#include <linux/interrupt.h>
20#include <linux/debugfs.h>
21
22#include <asm/sections.h>
23#include <asm/io.h>
24#include <asm/prom.h>
25#include <asm/pci-bridge.h>
26#include <asm/machdep.h>
27#include <asm/ppc-pci.h>
28#include <asm/iommu.h>
29#include <asm/io-workarounds.h>
30
31#include "wsp.h"
32#include "wsp_pci.h"
33#include "msi.h"
34
35
36/* Max number of TVTs for one table. Only 32-bit tables can use
37 * multiple TVTs and so the max currently supported is thus 8
38 * since only 2G of DMA space is supported
39 */
40#define MAX_TABLE_TVT_COUNT 8
41
42struct wsp_dma_table {
43 struct list_head link;
44 struct iommu_table table;
45 struct wsp_phb *phb;
46 struct page *tces[MAX_TABLE_TVT_COUNT];
47};
48
49/* We support DMA regions from 0...2G in 32bit space (no support for
50 * 64-bit DMA just yet). Each device gets a separate TCE table (TVT
51 * entry) with validation enabled (though not supported by SimiCS
52 * just yet).
53 *
54 * To simplify things, we divide this 2G space into N regions based
55 * on the constant below which could be turned into a tunable eventually
56 *
57 * We then assign dynamically those regions to devices as they show up.
58 *
59 * We use a bitmap as an allocator for these.
60 *
61 * Tables are allocated/created dynamically as devices are discovered,
62 * multiple TVT entries are used if needed
63 *
64 * When 64-bit DMA support is added we should simply use a separate set
65 * of larger regions (the HW supports 64 TVT entries). We can
66 * additionally create a bypass region in 64-bit space for performances
67 * though that would have a cost in term of security.
68 *
69 * If you set NUM_DMA32_REGIONS to 1, then a single table is shared
70 * for all devices and bus/dev/fn validation is disabled
71 *
72 * Note that a DMA32 region cannot be smaller than 256M so the max
73 * supported here for now is 8. We don't yet support sharing regions
74 * between multiple devices so the max number of devices supported
75 * is MAX_TABLE_TVT_COUNT.
76 */
77#define NUM_DMA32_REGIONS 1
78
79struct wsp_phb {
80 struct pci_controller *hose;
81
82 /* Lock controlling access to the list of dma tables.
83 * It does -not- protect against dma_* operations on
84 * those tables, those should be stopped before an entry
85 * is removed from the list.
86 *
87 * The lock is also used for error handling operations
88 */
89 spinlock_t lock;
90 struct list_head dma_tables;
91 unsigned long dma32_map;
92 unsigned long dma32_base;
93 unsigned int dma32_num_regions;
94 unsigned long dma32_region_size;
95
96 /* Debugfs stuff */
97 struct dentry *ddir;
98
99 struct list_head all;
100};
101static LIST_HEAD(wsp_phbs);
102
103//#define cfg_debug(fmt...) pr_debug(fmt)
104#define cfg_debug(fmt...)
105
106
107static int wsp_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
108 int offset, int len, u32 *val)
109{
110 struct pci_controller *hose;
111 int suboff;
112 u64 addr;
113
114 hose = pci_bus_to_host(bus);
115 if (hose == NULL)
116 return PCIBIOS_DEVICE_NOT_FOUND;
117 if (offset >= 0x1000)
118 return PCIBIOS_BAD_REGISTER_NUMBER;
119 addr = PCIE_REG_CA_ENABLE |
120 ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT |
121 ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT |
122 ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT;
123 suboff = offset & 3;
124
125 /*
126 * Note: the caller has already checked that offset is
127 * suitably aligned and that len is 1, 2 or 4.
128 */
129
130 switch (len) {
131 case 1:
132 addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT;
133 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
134 *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA)
135 >> (suboff << 3)) & 0xff;
136 cfg_debug("read 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n",
137 bus->number, devfn >> 3, devfn & 7,
138 offset, suboff, addr, *val);
139 break;
140 case 2:
141 addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT;
142 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
143 *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA)
144 >> (suboff << 3)) & 0xffff;
145 cfg_debug("read 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n",
146 bus->number, devfn >> 3, devfn & 7,
147 offset, suboff, addr, *val);
148 break;
149 default:
150 addr |= 0xful << PCIE_REG_CA_BE_SHIFT;
151 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
152 *val = in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA);
153 cfg_debug("read 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n",
154 bus->number, devfn >> 3, devfn & 7,
155 offset, suboff, addr, *val);
156 break;
157 }
158 return PCIBIOS_SUCCESSFUL;
159}
160
161static int wsp_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
162 int offset, int len, u32 val)
163{
164 struct pci_controller *hose;
165 int suboff;
166 u64 addr;
167
168 hose = pci_bus_to_host(bus);
169 if (hose == NULL)
170 return PCIBIOS_DEVICE_NOT_FOUND;
171 if (offset >= 0x1000)
172 return PCIBIOS_BAD_REGISTER_NUMBER;
173 addr = PCIE_REG_CA_ENABLE |
174 ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT |
175 ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT |
176 ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT;
177 suboff = offset & 3;
178
179 /*
180 * Note: the caller has already checked that offset is
181 * suitably aligned and that len is 1, 2 or 4.
182 */
183 switch (len) {
184 case 1:
185 addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT;
186 val <<= suboff << 3;
187 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
188 out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
189 cfg_debug("write 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n",
190 bus->number, devfn >> 3, devfn & 7,
191 offset, suboff, addr, val);
192 break;
193 case 2:
194 addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT;
195 val <<= suboff << 3;
196 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
197 out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
198 cfg_debug("write 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n",
199 bus->number, devfn >> 3, devfn & 7,
200 offset, suboff, addr, val);
201 break;
202 default:
203 addr |= 0xful << PCIE_REG_CA_BE_SHIFT;
204 out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
205 out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
206 cfg_debug("write 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n",
207 bus->number, devfn >> 3, devfn & 7,
208 offset, suboff, addr, val);
209 break;
210 }
211 return PCIBIOS_SUCCESSFUL;
212}
213
214static struct pci_ops wsp_pcie_pci_ops =
215{
216 .read = wsp_pcie_read_config,
217 .write = wsp_pcie_write_config,
218};
219
220#define TCE_SHIFT 12
221#define TCE_PAGE_SIZE (1 << TCE_SHIFT)
222#define TCE_PCI_WRITE 0x2 /* write from PCI allowed */
223#define TCE_PCI_READ 0x1 /* read from PCI allowed */
224#define TCE_RPN_MASK 0x3fffffffffful /* 42-bit RPN (4K pages) */
225#define TCE_RPN_SHIFT 12
226
227//#define dma_debug(fmt...) pr_debug(fmt)
228#define dma_debug(fmt...)
229
230static int tce_build_wsp(struct iommu_table *tbl, long index, long npages,
231 unsigned long uaddr, enum dma_data_direction direction,
232 struct dma_attrs *attrs)
233{
234 struct wsp_dma_table *ptbl = container_of(tbl,
235 struct wsp_dma_table,
236 table);
237 u64 proto_tce;
238 u64 *tcep;
239 u64 rpn;
240
241 proto_tce = TCE_PCI_READ;
242#ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
243 proto_tce |= TCE_PCI_WRITE;
244#else
245 if (direction != DMA_TO_DEVICE)
246 proto_tce |= TCE_PCI_WRITE;
247#endif
248
249 /* XXX Make this faster by factoring out the page address for
250 * within a TCE table
251 */
252 while (npages--) {
253 /* We don't use it->base as the table can be scattered */
254 tcep = (u64 *)page_address(ptbl->tces[index >> 16]);
255 tcep += (index & 0xffff);
256
257 /* can't move this out since we might cross LMB boundary */
258 rpn = __pa(uaddr) >> TCE_SHIFT;
259 *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
260
261 dma_debug("[DMA] TCE %p set to 0x%016llx (dma addr: 0x%lx)\n",
262 tcep, *tcep, (tbl->it_offset + index) << IOMMU_PAGE_SHIFT);
263
264 uaddr += TCE_PAGE_SIZE;
265 index++;
266 }
267 return 0;
268}
269
270static void tce_free_wsp(struct iommu_table *tbl, long index, long npages)
271{
272 struct wsp_dma_table *ptbl = container_of(tbl,
273 struct wsp_dma_table,
274 table);
275#ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
276 struct pci_controller *hose = ptbl->phb->hose;
277#endif
278 u64 *tcep;
279
280 /* XXX Make this faster by factoring out the page address for
281 * within a TCE table. Also use line-kill option to kill multiple
282 * TCEs at once
283 */
284 while (npages--) {
285 /* We don't use it->base as the table can be scattered */
286 tcep = (u64 *)page_address(ptbl->tces[index >> 16]);
287 tcep += (index & 0xffff);
288 dma_debug("[DMA] TCE %p cleared\n", tcep);
289 *tcep = 0;
290#ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
291 /* Don't write there since it would pollute other MMIO accesses */
292 out_be64(hose->cfg_data + PCIE_REG_TCE_KILL,
293 PCIE_REG_TCEKILL_SINGLE | PCIE_REG_TCEKILL_PS_4K |
294 (__pa(tcep) & PCIE_REG_TCEKILL_ADDR_MASK));
295#endif
296 index++;
297 }
298}
299
300static struct wsp_dma_table *wsp_pci_create_dma32_table(struct wsp_phb *phb,
301 unsigned int region,
302 struct pci_dev *validate)
303{
304 struct pci_controller *hose = phb->hose;
305 unsigned long size = phb->dma32_region_size;
306 unsigned long addr = phb->dma32_region_size * region + phb->dma32_base;
307 struct wsp_dma_table *tbl;
308 int tvts_per_table, i, tvt, nid;
309 unsigned long flags;
310
311 nid = of_node_to_nid(phb->hose->dn);
312
313 /* Calculate how many TVTs are needed */
314 tvts_per_table = size / 0x10000000;
315 if (tvts_per_table == 0)
316 tvts_per_table = 1;
317
318 /* Calculate the base TVT index. We know all tables have the same
319 * size so we just do a simple multiply here
320 */
321 tvt = region * tvts_per_table;
322
323 pr_debug(" Region : %d\n", region);
324 pr_debug(" DMA range : 0x%08lx..0x%08lx\n", addr, addr + size - 1);
325 pr_debug(" Number of TVTs : %d\n", tvts_per_table);
326 pr_debug(" Base TVT : %d\n", tvt);
327 pr_debug(" Node : %d\n", nid);
328
329 tbl = kzalloc_node(sizeof(struct wsp_dma_table), GFP_KERNEL, nid);
330 if (!tbl)
331 return ERR_PTR(-ENOMEM);
332 tbl->phb = phb;
333
334 /* Create as many TVTs as needed, each represents 256M at most */
335 for (i = 0; i < tvts_per_table; i++) {
336 u64 tvt_data1, tvt_data0;
337
338 /* Allocate table. We use a 4K TCE size for now always so
339 * one table is always 8 * (258M / 4K) == 512K
340 */
341 tbl->tces[i] = alloc_pages_node(nid, GFP_KERNEL, get_order(0x80000));
342 if (tbl->tces[i] == NULL)
343 goto fail;
344 memset(page_address(tbl->tces[i]), 0, 0x80000);
345
346 pr_debug(" TCE table %d at : %p\n", i, page_address(tbl->tces[i]));
347
348 /* Table size. We currently set it to be the whole 256M region */
349 tvt_data0 = 2ull << IODA_TVT0_TCE_TABLE_SIZE_SHIFT;
350 /* IO page size set to 4K */
351 tvt_data1 = 1ull << IODA_TVT1_IO_PAGE_SIZE_SHIFT;
352 /* Shift in the address */
353 tvt_data0 |= __pa(page_address(tbl->tces[i])) << IODA_TVT0_TTA_SHIFT;
354
355 /* Validation stuff. We only validate fully bus/dev/fn for now
356 * one day maybe we can group devices but that isn't the case
357 * at the moment
358 */
359 if (validate) {
360 tvt_data0 |= IODA_TVT0_BUSNUM_VALID_MASK;
361 tvt_data0 |= validate->bus->number;
362 tvt_data1 |= IODA_TVT1_DEVNUM_VALID;
363 tvt_data1 |= ((u64)PCI_SLOT(validate->devfn))
364 << IODA_TVT1_DEVNUM_VALUE_SHIFT;
365 tvt_data1 |= IODA_TVT1_FUNCNUM_VALID;
366 tvt_data1 |= ((u64)PCI_FUNC(validate->devfn))
367 << IODA_TVT1_FUNCNUM_VALUE_SHIFT;
368 }
369
370 /* XX PE number is always 0 for now */
371
372 /* Program the values using the PHB lock */
373 spin_lock_irqsave(&phb->lock, flags);
374 out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR,
375 (tvt + i) | PCIE_REG_IODA_AD_TBL_TVT);
376 out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, tvt_data1);
377 out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, tvt_data0);
378 spin_unlock_irqrestore(&phb->lock, flags);
379 }
380
381 /* Init bits and pieces */
382 tbl->table.it_blocksize = 16;
383 tbl->table.it_offset = addr >> IOMMU_PAGE_SHIFT;
384 tbl->table.it_size = size >> IOMMU_PAGE_SHIFT;
385
386 /*
387 * It's already blank but we clear it anyway.
388 * Consider an aditiona interface that makes cleaing optional
389 */
390 iommu_init_table(&tbl->table, nid);
391
392 list_add(&tbl->link, &phb->dma_tables);
393 return tbl;
394
395 fail:
396 pr_debug(" Failed to allocate a 256M TCE table !\n");
397 for (i = 0; i < tvts_per_table; i++)
398 if (tbl->tces[i])
399 __free_pages(tbl->tces[i], get_order(0x80000));
400 kfree(tbl);
401 return ERR_PTR(-ENOMEM);
402}
403
404static void __devinit wsp_pci_dma_dev_setup(struct pci_dev *pdev)
405{
406 struct dev_archdata *archdata = &pdev->dev.archdata;
407 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
408 struct wsp_phb *phb = hose->private_data;
409 struct wsp_dma_table *table = NULL;
410 unsigned long flags;
411 int i;
412
413 /* Don't assign an iommu table to a bridge */
414 if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
415 return;
416
417 pr_debug("%s: Setting up DMA...\n", pci_name(pdev));
418
419 spin_lock_irqsave(&phb->lock, flags);
420
421 /* If only one region, check if it already exist */
422 if (phb->dma32_num_regions == 1) {
423 spin_unlock_irqrestore(&phb->lock, flags);
424 if (list_empty(&phb->dma_tables))
425 table = wsp_pci_create_dma32_table(phb, 0, NULL);
426 else
427 table = list_first_entry(&phb->dma_tables,
428 struct wsp_dma_table,
429 link);
430 } else {
431 /* else find a free region */
432 for (i = 0; i < phb->dma32_num_regions && !table; i++) {
433 if (__test_and_set_bit(i, &phb->dma32_map))
434 continue;
435 spin_unlock_irqrestore(&phb->lock, flags);
436 table = wsp_pci_create_dma32_table(phb, i, pdev);
437 }
438 }
439
440 /* Check if we got an error */
441 if (IS_ERR(table)) {
442 pr_err("%s: Failed to create DMA table, err %ld !\n",
443 pci_name(pdev), PTR_ERR(table));
444 return;
445 }
446
447 /* Or a valid table */
448 if (table) {
449 pr_info("%s: Setup iommu: 32-bit DMA region 0x%08lx..0x%08lx\n",
450 pci_name(pdev),
451 table->table.it_offset << IOMMU_PAGE_SHIFT,
452 (table->table.it_offset << IOMMU_PAGE_SHIFT)
453 + phb->dma32_region_size - 1);
454 archdata->dma_data.iommu_table_base = &table->table;
455 return;
456 }
457
458 /* Or no room */
459 spin_unlock_irqrestore(&phb->lock, flags);
460 pr_err("%s: Out of DMA space !\n", pci_name(pdev));
461}
462
463static void __init wsp_pcie_configure_hw(struct pci_controller *hose)
464{
465 u64 val;
466 int i;
467
468#define DUMP_REG(x) \
469 pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x))
470
471#ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS
472 /* WSP DD1 has a bogus class code by default in the PCI-E
473 * root complex's built-in P2P bridge */
474 val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1);
475 pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val);
476 out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1,
477 (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8));
478 pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1));
479#endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */
480
481#ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
482 /* XXX Disable TCE caching, it doesn't work on DD1 */
483 out_be64(hose->cfg_data + 0xe50,
484 in_be64(hose->cfg_data + 0xe50) | (3ull << 62));
485 printk("PCI-E DEBUG CONTROL 5 = 0x%llx\n", in_be64(hose->cfg_data + 0xe50));
486#endif
487
488 /* Configure M32A and IO. IO is hard wired to be 1M for now */
489 out_be64(hose->cfg_data + PCIE_REG_IO_BASE_ADDR, hose->io_base_phys);
490 out_be64(hose->cfg_data + PCIE_REG_IO_BASE_MASK,
491 (~(hose->io_resource.end - hose->io_resource.start)) &
492 0x3fffffff000ul);
493 out_be64(hose->cfg_data + PCIE_REG_IO_START_ADDR, 0 | 1);
494
495 out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_ADDR,
496 hose->mem_resources[0].start);
497 printk("Want to write to M32A_BASE_MASK : 0x%llx\n",
498 (~(hose->mem_resources[0].end -
499 hose->mem_resources[0].start)) & 0x3ffffff0000ul);
500 out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_MASK,
501 (~(hose->mem_resources[0].end -
502 hose->mem_resources[0].start)) & 0x3ffffff0000ul);
503 out_be64(hose->cfg_data + PCIE_REG_M32A_START_ADDR,
504 (hose->mem_resources[0].start - hose->pci_mem_offset) | 1);
505
506 /* Clear all TVT entries
507 *
508 * XX Might get TVT count from device-tree
509 */
510 for (i = 0; i < IODA_TVT_COUNT; i++) {
511 out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR,
512 PCIE_REG_IODA_AD_TBL_TVT | i);
513 out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, 0);
514 out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, 0);
515 }
516
517 /* Kill the TCE cache */
518 out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG,
519 in_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG) |
520 PCIE_REG_PHBC_64B_TCE_EN);
521
522 /* Enable 32 & 64-bit MSIs, IO space and M32A */
523 val = PCIE_REG_PHBC_32BIT_MSI_EN |
524 PCIE_REG_PHBC_IO_EN |
525 PCIE_REG_PHBC_64BIT_MSI_EN |
526 PCIE_REG_PHBC_M32A_EN;
527 if (iommu_is_off)
528 val |= PCIE_REG_PHBC_DMA_XLATE_BYPASS;
529 pr_debug("Will write config: 0x%llx\n", val);
530 out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, val);
531
532 /* Enable error reporting */
533 out_be64(hose->cfg_data + 0xe00,
534 in_be64(hose->cfg_data + 0xe00) | 0x0008000000000000ull);
535
536 /* Mask an error that's generated when doing config space probe
537 *
538 * XXX Maybe we should only mask it around config space cycles... that or
539 * ignore it when we know we had a config space cycle recently ?
540 */
541 out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS_MASK, 0x8000000000000000ull);
542 out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS_MASK, 0x8000000000000000ull);
543
544 /* Enable UTL errors, for now, all of them got to UTL irq 1
545 *
546 * We similarily mask one UTL error caused apparently during normal
547 * probing. We also mask the link up error
548 */
549 out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_ERR_SEV, 0);
550 out_be64(hose->cfg_data + PCIE_UTL_RC_ERR_SEVERITY, 0);
551 out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_ERROR_SEV, 0);
552 out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_IRQ_EN, 0xffffffff00000000ull);
553 out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_IRQ_EN, 0xff5fffff00000000ull);
554 out_be64(hose->cfg_data + PCIE_UTL_EP_ERR_IRQ_EN, 0xffffffff00000000ull);
555
556 DUMP_REG(PCIE_REG_IO_BASE_ADDR);
557 DUMP_REG(PCIE_REG_IO_BASE_MASK);
558 DUMP_REG(PCIE_REG_IO_START_ADDR);
559 DUMP_REG(PCIE_REG_M32A_BASE_ADDR);
560 DUMP_REG(PCIE_REG_M32A_BASE_MASK);
561 DUMP_REG(PCIE_REG_M32A_START_ADDR);
562 DUMP_REG(PCIE_REG_M32B_BASE_ADDR);
563 DUMP_REG(PCIE_REG_M32B_BASE_MASK);
564 DUMP_REG(PCIE_REG_M32B_START_ADDR);
565 DUMP_REG(PCIE_REG_M64_BASE_ADDR);
566 DUMP_REG(PCIE_REG_M64_BASE_MASK);
567 DUMP_REG(PCIE_REG_M64_START_ADDR);
568 DUMP_REG(PCIE_REG_PHB_CONFIG);
569}
570
571static void wsp_pci_wait_io_idle(struct wsp_phb *phb, unsigned long port)
572{
573 u64 val;
574 int i;
575
576 for (i = 0; i < 10000; i++) {
577 val = in_be64(phb->hose->cfg_data + 0xe08);
578 if ((val & 0x1900000000000000ull) == 0x0100000000000000ull)
579 return;
580 udelay(1);
581 }
582 pr_warning("PCI IO timeout on domain %d port 0x%lx\n",
583 phb->hose->global_number, port);
584}
585
586#define DEF_PCI_AC_RET_pio(name, ret, at, al, aa) \
587static ret wsp_pci_##name at \
588{ \
589 struct iowa_bus *bus; \
590 struct wsp_phb *phb; \
591 unsigned long flags; \
592 ret rval; \
593 bus = iowa_pio_find_bus(aa); \
594 WARN_ON(!bus); \
595 phb = bus->private; \
596 spin_lock_irqsave(&phb->lock, flags); \
597 wsp_pci_wait_io_idle(phb, aa); \
598 rval = __do_##name al; \
599 spin_unlock_irqrestore(&phb->lock, flags); \
600 return rval; \
601}
602
603#define DEF_PCI_AC_NORET_pio(name, at, al, aa) \
604static void wsp_pci_##name at \
605{ \
606 struct iowa_bus *bus; \
607 struct wsp_phb *phb; \
608 unsigned long flags; \
609 bus = iowa_pio_find_bus(aa); \
610 WARN_ON(!bus); \
611 phb = bus->private; \
612 spin_lock_irqsave(&phb->lock, flags); \
613 wsp_pci_wait_io_idle(phb, aa); \
614 __do_##name al; \
615 spin_unlock_irqrestore(&phb->lock, flags); \
616}
617
618#define DEF_PCI_AC_RET_mem(name, ret, at, al, aa)
619#define DEF_PCI_AC_NORET_mem(name, at, al, aa)
620
621#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
622 DEF_PCI_AC_RET_##space(name, ret, at, al, aa)
623
624#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
625 DEF_PCI_AC_NORET_##space(name, at, al, aa) \
626
627
628#include <asm/io-defs.h>
629
630#undef DEF_PCI_AC_RET
631#undef DEF_PCI_AC_NORET
632
633static struct ppc_pci_io wsp_pci_iops = {
634 .inb = wsp_pci_inb,
635 .inw = wsp_pci_inw,
636 .inl = wsp_pci_inl,
637 .outb = wsp_pci_outb,
638 .outw = wsp_pci_outw,
639 .outl = wsp_pci_outl,
640 .insb = wsp_pci_insb,
641 .insw = wsp_pci_insw,
642 .insl = wsp_pci_insl,
643 .outsb = wsp_pci_outsb,
644 .outsw = wsp_pci_outsw,
645 .outsl = wsp_pci_outsl,
646};
647
648static int __init wsp_setup_one_phb(struct device_node *np)
649{
650 struct pci_controller *hose;
651 struct wsp_phb *phb;
652
653 pr_info("PCI: Setting up PCIe host bridge 0x%s\n", np->full_name);
654
655 phb = zalloc_maybe_bootmem(sizeof(struct wsp_phb), GFP_KERNEL);
656 if (!phb)
657 return -ENOMEM;
658 hose = pcibios_alloc_controller(np);
659 if (!hose) {
660 /* Can't really free the phb */
661 return -ENOMEM;
662 }
663 hose->private_data = phb;
664 phb->hose = hose;
665
666 INIT_LIST_HEAD(&phb->dma_tables);
667 spin_lock_init(&phb->lock);
668
669 /* XXX Use bus-range property ? */
670 hose->first_busno = 0;
671 hose->last_busno = 0xff;
672
673 /* We use cfg_data as the address for the whole bridge MMIO space
674 */
675 hose->cfg_data = of_iomap(hose->dn, 0);
676
677 pr_debug("PCIe registers mapped at 0x%p\n", hose->cfg_data);
678
679 /* Get the ranges of the device-tree */
680 pci_process_bridge_OF_ranges(hose, np, 0);
681
682 /* XXX Force re-assigning of everything for now */
683 pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC |
684 PCI_ENABLE_PROC_DOMAINS);
685 pci_probe_only = 0;
686
687 /* Calculate how the TCE space is divided */
688 phb->dma32_base = 0;
689 phb->dma32_num_regions = NUM_DMA32_REGIONS;
690 if (phb->dma32_num_regions > MAX_TABLE_TVT_COUNT) {
691 pr_warning("IOMMU: Clamped to %d DMA32 regions\n",
692 MAX_TABLE_TVT_COUNT);
693 phb->dma32_num_regions = MAX_TABLE_TVT_COUNT;
694 }
695 phb->dma32_region_size = 0x80000000 / phb->dma32_num_regions;
696
697 BUG_ON(!is_power_of_2(phb->dma32_region_size));
698
699 /* Setup config ops */
700 hose->ops = &wsp_pcie_pci_ops;
701
702 /* Configure the HW */
703 wsp_pcie_configure_hw(hose);
704
705 /* Instanciate IO workarounds */
706 iowa_register_bus(hose, &wsp_pci_iops, NULL, phb);
707#ifdef CONFIG_PCI_MSI
708 wsp_setup_phb_msi(hose);
709#endif
710
711 /* Add to global list */
712 list_add(&phb->all, &wsp_phbs);
713
714 return 0;
715}
716
717void __init wsp_setup_pci(void)
718{
719 struct device_node *np;
720 int rc;
721
722 /* Find host bridges */
723 for_each_compatible_node(np, "pciex", PCIE_COMPATIBLE) {
724 rc = wsp_setup_one_phb(np);
725 if (rc)
726 pr_err("Failed to setup PCIe bridge %s, rc=%d\n",
727 np->full_name, rc);
728 }
729
730 /* Establish device-tree linkage */
731 pci_devs_phb_init();
732
733 /* Set DMA ops to use TCEs */
734 if (iommu_is_off) {
735 pr_info("PCI-E: Disabled TCEs, using direct DMA\n");
736 set_pci_dma_ops(&dma_direct_ops);
737 } else {
738 ppc_md.pci_dma_dev_setup = wsp_pci_dma_dev_setup;
739 ppc_md.tce_build = tce_build_wsp;
740 ppc_md.tce_free = tce_free_wsp;
741 set_pci_dma_ops(&dma_iommu_ops);
742 }
743}
744
745#define err_debug(fmt...) pr_debug(fmt)
746//#define err_debug(fmt...)
747
748static int __init wsp_pci_get_err_irq_no_dt(struct device_node *np)
749{
750 const u32 *prop;
751 int hw_irq;
752
753 /* Ok, no interrupts property, let's try to find our child P2P */
754 np = of_get_next_child(np, NULL);
755 if (np == NULL)
756 return 0;
757
758 /* Grab it's interrupt map */
759 prop = of_get_property(np, "interrupt-map", NULL);
760 if (prop == NULL)
761 return 0;
762
763 /* Grab one of the interrupts in there, keep the low 4 bits */
764 hw_irq = prop[5] & 0xf;
765
766 /* 0..4 for PHB 0 and 5..9 for PHB 1 */
767 if (hw_irq < 5)
768 hw_irq = 4;
769 else
770 hw_irq = 9;
771 hw_irq |= prop[5] & ~0xf;
772
773 err_debug("PCI: Using 0x%x as error IRQ for %s\n",
774 hw_irq, np->parent->full_name);
775 return irq_create_mapping(NULL, hw_irq);
776}
777
778static const struct {
779 u32 offset;
780 const char *name;
781} wsp_pci_regs[] = {
782#define DREG(x) { PCIE_REG_##x, #x }
783#define DUTL(x) { PCIE_UTL_##x, "UTL_" #x }
784 /* Architected registers except CONFIG_ and IODA
785 * to avoid side effects
786 */
787 DREG(DMA_CHAN_STATUS),
788 DREG(CPU_LOADSTORE_STATUS),
789 DREG(LOCK0),
790 DREG(LOCK1),
791 DREG(PHB_CONFIG),
792 DREG(IO_BASE_ADDR),
793 DREG(IO_BASE_MASK),
794 DREG(IO_START_ADDR),
795 DREG(M32A_BASE_ADDR),
796 DREG(M32A_BASE_MASK),
797 DREG(M32A_START_ADDR),
798 DREG(M32B_BASE_ADDR),
799 DREG(M32B_BASE_MASK),
800 DREG(M32B_START_ADDR),
801 DREG(M64_BASE_ADDR),
802 DREG(M64_BASE_MASK),
803 DREG(M64_START_ADDR),
804 DREG(TCE_KILL),
805 DREG(LOCK2),
806 DREG(PHB_GEN_CAP),
807 DREG(PHB_TCE_CAP),
808 DREG(PHB_IRQ_CAP),
809 DREG(PHB_EEH_CAP),
810 DREG(PAPR_ERR_INJ_CONTROL),
811 DREG(PAPR_ERR_INJ_ADDR),
812 DREG(PAPR_ERR_INJ_MASK),
813
814 /* UTL core regs */
815 DUTL(SYS_BUS_CONTROL),
816 DUTL(STATUS),
817 DUTL(SYS_BUS_AGENT_STATUS),
818 DUTL(SYS_BUS_AGENT_ERR_SEV),
819 DUTL(SYS_BUS_AGENT_IRQ_EN),
820 DUTL(SYS_BUS_BURST_SZ_CONF),
821 DUTL(REVISION_ID),
822 DUTL(OUT_POST_HDR_BUF_ALLOC),
823 DUTL(OUT_POST_DAT_BUF_ALLOC),
824 DUTL(IN_POST_HDR_BUF_ALLOC),
825 DUTL(IN_POST_DAT_BUF_ALLOC),
826 DUTL(OUT_NP_BUF_ALLOC),
827 DUTL(IN_NP_BUF_ALLOC),
828 DUTL(PCIE_TAGS_ALLOC),
829 DUTL(GBIF_READ_TAGS_ALLOC),
830
831 DUTL(PCIE_PORT_CONTROL),
832 DUTL(PCIE_PORT_STATUS),
833 DUTL(PCIE_PORT_ERROR_SEV),
834 DUTL(PCIE_PORT_IRQ_EN),
835 DUTL(RC_STATUS),
836 DUTL(RC_ERR_SEVERITY),
837 DUTL(RC_IRQ_EN),
838 DUTL(EP_STATUS),
839 DUTL(EP_ERR_SEVERITY),
840 DUTL(EP_ERR_IRQ_EN),
841 DUTL(PCI_PM_CTRL1),
842 DUTL(PCI_PM_CTRL2),
843
844 /* PCIe stack regs */
845 DREG(SYSTEM_CONFIG1),
846 DREG(SYSTEM_CONFIG2),
847 DREG(EP_SYSTEM_CONFIG),
848 DREG(EP_FLR),
849 DREG(EP_BAR_CONFIG),
850 DREG(LINK_CONFIG),
851 DREG(PM_CONFIG),
852 DREG(DLP_CONTROL),
853 DREG(DLP_STATUS),
854 DREG(ERR_REPORT_CONTROL),
855 DREG(SLOT_CONTROL1),
856 DREG(SLOT_CONTROL2),
857 DREG(UTL_CONFIG),
858 DREG(BUFFERS_CONFIG),
859 DREG(ERROR_INJECT),
860 DREG(SRIOV_CONFIG),
861 DREG(PF0_SRIOV_STATUS),
862 DREG(PF1_SRIOV_STATUS),
863 DREG(PORT_NUMBER),
864 DREG(POR_SYSTEM_CONFIG),
865
866 /* Internal logic regs */
867 DREG(PHB_VERSION),
868 DREG(RESET),
869 DREG(PHB_CONTROL),
870 DREG(PHB_TIMEOUT_CONTROL1),
871 DREG(PHB_QUIESCE_DMA),
872 DREG(PHB_DMA_READ_TAG_ACTV),
873 DREG(PHB_TCE_READ_TAG_ACTV),
874
875 /* FIR registers */
876 DREG(LEM_FIR_ACCUM),
877 DREG(LEM_FIR_AND_MASK),
878 DREG(LEM_FIR_OR_MASK),
879 DREG(LEM_ACTION0),
880 DREG(LEM_ACTION1),
881 DREG(LEM_ERROR_MASK),
882 DREG(LEM_ERROR_AND_MASK),
883 DREG(LEM_ERROR_OR_MASK),
884
885 /* Error traps registers */
886 DREG(PHB_ERR_STATUS),
887 DREG(PHB_ERR_STATUS),
888 DREG(PHB_ERR1_STATUS),
889 DREG(PHB_ERR_INJECT),
890 DREG(PHB_ERR_LEM_ENABLE),
891 DREG(PHB_ERR_IRQ_ENABLE),
892 DREG(PHB_ERR_FREEZE_ENABLE),
893 DREG(PHB_ERR_SIDE_ENABLE),
894 DREG(PHB_ERR_LOG_0),
895 DREG(PHB_ERR_LOG_1),
896 DREG(PHB_ERR_STATUS_MASK),
897 DREG(PHB_ERR1_STATUS_MASK),
898 DREG(MMIO_ERR_STATUS),
899 DREG(MMIO_ERR1_STATUS),
900 DREG(MMIO_ERR_INJECT),
901 DREG(MMIO_ERR_LEM_ENABLE),
902 DREG(MMIO_ERR_IRQ_ENABLE),
903 DREG(MMIO_ERR_FREEZE_ENABLE),
904 DREG(MMIO_ERR_SIDE_ENABLE),
905 DREG(MMIO_ERR_LOG_0),
906 DREG(MMIO_ERR_LOG_1),
907 DREG(MMIO_ERR_STATUS_MASK),
908 DREG(MMIO_ERR1_STATUS_MASK),
909 DREG(DMA_ERR_STATUS),
910 DREG(DMA_ERR1_STATUS),
911 DREG(DMA_ERR_INJECT),
912 DREG(DMA_ERR_LEM_ENABLE),
913 DREG(DMA_ERR_IRQ_ENABLE),
914 DREG(DMA_ERR_FREEZE_ENABLE),
915 DREG(DMA_ERR_SIDE_ENABLE),
916 DREG(DMA_ERR_LOG_0),
917 DREG(DMA_ERR_LOG_1),
918 DREG(DMA_ERR_STATUS_MASK),
919 DREG(DMA_ERR1_STATUS_MASK),
920
921 /* Debug and Trace registers */
922 DREG(PHB_DEBUG_CONTROL0),
923 DREG(PHB_DEBUG_STATUS0),
924 DREG(PHB_DEBUG_CONTROL1),
925 DREG(PHB_DEBUG_STATUS1),
926 DREG(PHB_DEBUG_CONTROL2),
927 DREG(PHB_DEBUG_STATUS2),
928 DREG(PHB_DEBUG_CONTROL3),
929 DREG(PHB_DEBUG_STATUS3),
930 DREG(PHB_DEBUG_CONTROL4),
931 DREG(PHB_DEBUG_STATUS4),
932 DREG(PHB_DEBUG_CONTROL5),
933 DREG(PHB_DEBUG_STATUS5),
934
935 /* Don't seem to exist ...
936 DREG(PHB_DEBUG_CONTROL6),
937 DREG(PHB_DEBUG_STATUS6),
938 */
939};
940
941static int wsp_pci_regs_show(struct seq_file *m, void *private)
942{
943 struct wsp_phb *phb = m->private;
944 struct pci_controller *hose = phb->hose;
945 int i;
946
947 for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) {
948 /* Skip write-only regs */
949 if (wsp_pci_regs[i].offset == 0xc08 ||
950 wsp_pci_regs[i].offset == 0xc10 ||
951 wsp_pci_regs[i].offset == 0xc38 ||
952 wsp_pci_regs[i].offset == 0xc40)
953 continue;
954 seq_printf(m, "0x%03x: 0x%016llx %s\n",
955 wsp_pci_regs[i].offset,
956 in_be64(hose->cfg_data + wsp_pci_regs[i].offset),
957 wsp_pci_regs[i].name);
958 }
959 return 0;
960}
961
962static int wsp_pci_regs_open(struct inode *inode, struct file *file)
963{
964 return single_open(file, wsp_pci_regs_show, inode->i_private);
965}
966
967static const struct file_operations wsp_pci_regs_fops = {
968 .open = wsp_pci_regs_open,
969 .read = seq_read,
970 .llseek = seq_lseek,
971 .release = single_release,
972};
973
974static int wsp_pci_reg_set(void *data, u64 val)
975{
976 out_be64((void __iomem *)data, val);
977 return 0;
978}
979
980static int wsp_pci_reg_get(void *data, u64 *val)
981{
982 *val = in_be64((void __iomem *)data);
983 return 0;
984}
985
986DEFINE_SIMPLE_ATTRIBUTE(wsp_pci_reg_fops, wsp_pci_reg_get, wsp_pci_reg_set, "0x%llx\n");
987
988static irqreturn_t wsp_pci_err_irq(int irq, void *dev_id)
989{
990 struct wsp_phb *phb = dev_id;
991 struct pci_controller *hose = phb->hose;
992 irqreturn_t handled = IRQ_NONE;
993 struct wsp_pcie_err_log_data ed;
994
995 pr_err("PCI: Error interrupt on %s (PHB %d)\n",
996 hose->dn->full_name, hose->global_number);
997 again:
998 memset(&ed, 0, sizeof(ed));
999
1000 /* Read and clear UTL errors */
1001 ed.utl_sys_err = in_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS);
1002 if (ed.utl_sys_err)
1003 out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS, ed.utl_sys_err);
1004 ed.utl_port_err = in_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS);
1005 if (ed.utl_port_err)
1006 out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS, ed.utl_port_err);
1007 ed.utl_rc_err = in_be64(hose->cfg_data + PCIE_UTL_RC_STATUS);
1008 if (ed.utl_rc_err)
1009 out_be64(hose->cfg_data + PCIE_UTL_RC_STATUS, ed.utl_rc_err);
1010
1011 /* Read and clear main trap errors */
1012 ed.phb_err = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS);
1013 if (ed.phb_err) {
1014 ed.phb_err1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS);
1015 ed.phb_log0 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_0);
1016 ed.phb_log1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_1);
1017 out_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS, 0);
1018 out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS, 0);
1019 }
1020 ed.mmio_err = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS);
1021 if (ed.mmio_err) {
1022 ed.mmio_err1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS);
1023 ed.mmio_log0 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_0);
1024 ed.mmio_log1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_1);
1025 out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS, 0);
1026 out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS, 0);
1027 }
1028 ed.dma_err = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS);
1029 if (ed.dma_err) {
1030 ed.dma_err1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS);
1031 ed.dma_log0 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_0);
1032 ed.dma_log1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_1);
1033 out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS, 0);
1034 out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS, 0);
1035 }
1036
1037 /* Now print things out */
1038 if (ed.phb_err) {
1039 pr_err(" PHB Error Status : 0x%016llx\n", ed.phb_err);
1040 pr_err(" PHB First Error Status: 0x%016llx\n", ed.phb_err1);
1041 pr_err(" PHB Error Log 0 : 0x%016llx\n", ed.phb_log0);
1042 pr_err(" PHB Error Log 1 : 0x%016llx\n", ed.phb_log1);
1043 }
1044 if (ed.mmio_err) {
1045 pr_err(" MMIO Error Status : 0x%016llx\n", ed.mmio_err);
1046 pr_err(" MMIO First Error Status: 0x%016llx\n", ed.mmio_err1);
1047 pr_err(" MMIO Error Log 0 : 0x%016llx\n", ed.mmio_log0);
1048 pr_err(" MMIO Error Log 1 : 0x%016llx\n", ed.mmio_log1);
1049 }
1050 if (ed.dma_err) {
1051 pr_err(" DMA Error Status : 0x%016llx\n", ed.dma_err);
1052 pr_err(" DMA First Error Status: 0x%016llx\n", ed.dma_err1);
1053 pr_err(" DMA Error Log 0 : 0x%016llx\n", ed.dma_log0);
1054 pr_err(" DMA Error Log 1 : 0x%016llx\n", ed.dma_log1);
1055 }
1056 if (ed.utl_sys_err)
1057 pr_err(" UTL Sys Error Status : 0x%016llx\n", ed.utl_sys_err);
1058 if (ed.utl_port_err)
1059 pr_err(" UTL Port Error Status : 0x%016llx\n", ed.utl_port_err);
1060 if (ed.utl_rc_err)
1061 pr_err(" UTL RC Error Status : 0x%016llx\n", ed.utl_rc_err);
1062
1063 /* Interrupts are caused by the error traps. If we had any error there
1064 * we loop again in case the UTL buffered some new stuff between
1065 * going there and going to the traps
1066 */
1067 if (ed.dma_err || ed.mmio_err || ed.phb_err) {
1068 handled = IRQ_HANDLED;
1069 goto again;
1070 }
1071 return handled;
1072}
1073
1074static void __init wsp_setup_pci_err_reporting(struct wsp_phb *phb)
1075{
1076 struct pci_controller *hose = phb->hose;
1077 int err_irq, i, rc;
1078 char fname[16];
1079
1080 /* Create a debugfs file for that PHB */
1081 sprintf(fname, "phb%d", phb->hose->global_number);
1082 phb->ddir = debugfs_create_dir(fname, powerpc_debugfs_root);
1083
1084 /* Some useful debug output */
1085 if (phb->ddir) {
1086 struct dentry *d = debugfs_create_dir("regs", phb->ddir);
1087 char tmp[64];
1088
1089 for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) {
1090 sprintf(tmp, "%03x_%s", wsp_pci_regs[i].offset,
1091 wsp_pci_regs[i].name);
1092 debugfs_create_file(tmp, 0600, d,
1093 hose->cfg_data + wsp_pci_regs[i].offset,
1094 &wsp_pci_reg_fops);
1095 }
1096 debugfs_create_file("all_regs", 0600, phb->ddir, phb, &wsp_pci_regs_fops);
1097 }
1098
1099 /* Find the IRQ number for that PHB */
1100 err_irq = irq_of_parse_and_map(hose->dn, 0);
1101 if (err_irq == 0)
1102 /* XXX Error IRQ lacking from device-tree */
1103 err_irq = wsp_pci_get_err_irq_no_dt(hose->dn);
1104 if (err_irq == 0) {
1105 pr_err("PCI: Failed to fetch error interrupt for %s\n",
1106 hose->dn->full_name);
1107 return;
1108 }
1109 /* Request it */
1110 rc = request_irq(err_irq, wsp_pci_err_irq, 0, "wsp_pci error", phb);
1111 if (rc) {
1112 pr_err("PCI: Failed to request interrupt for %s\n",
1113 hose->dn->full_name);
1114 }
1115 /* Enable interrupts for all errors for now */
1116 out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
1117 out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
1118 out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
1119}
1120
1121/*
1122 * This is called later to hookup with the error interrupt
1123 */
1124static int __init wsp_setup_pci_late(void)
1125{
1126 struct wsp_phb *phb;
1127
1128 list_for_each_entry(phb, &wsp_phbs, all)
1129 wsp_setup_pci_err_reporting(phb);
1130
1131 return 0;
1132}
1133arch_initcall(wsp_setup_pci_late);
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.h b/arch/powerpc/platforms/wsp/wsp_pci.h
new file mode 100644
index 000000000000..52e9bd95250d
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/wsp_pci.h
@@ -0,0 +1,268 @@
1/*
2 * Copyright 2010 Ben Herrenschmidt, IBM Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef __WSP_PCI_H
11#define __WSP_PCI_H
12
13/* Architected registers */
14#define PCIE_REG_DMA_CHAN_STATUS 0x110
15#define PCIE_REG_CPU_LOADSTORE_STATUS 0x120
16
17#define PCIE_REG_CONFIG_DATA 0x130
18#define PCIE_REG_LOCK0 0x138
19#define PCIE_REG_CONFIG_ADDRESS 0x140
20#define PCIE_REG_CA_ENABLE 0x8000000000000000ull
21#define PCIE_REG_CA_BUS_MASK 0x0ff0000000000000ull
22#define PCIE_REG_CA_BUS_SHIFT (20+32)
23#define PCIE_REG_CA_DEV_MASK 0x000f800000000000ull
24#define PCIE_REG_CA_DEV_SHIFT (15+32)
25#define PCIE_REG_CA_FUNC_MASK 0x0000700000000000ull
26#define PCIE_REG_CA_FUNC_SHIFT (12+32)
27#define PCIE_REG_CA_REG_MASK 0x00000fff00000000ull
28#define PCIE_REG_CA_REG_SHIFT ( 0+32)
29#define PCIE_REG_CA_BE_MASK 0x00000000f0000000ull
30#define PCIE_REG_CA_BE_SHIFT ( 28)
31#define PCIE_REG_LOCK1 0x148
32
33#define PCIE_REG_PHB_CONFIG 0x160
34#define PCIE_REG_PHBC_64B_TCE_EN 0x2000000000000000ull
35#define PCIE_REG_PHBC_MMIO_DMA_FREEZE_EN 0x1000000000000000ull
36#define PCIE_REG_PHBC_32BIT_MSI_EN 0x0080000000000000ull
37#define PCIE_REG_PHBC_M64_EN 0x0040000000000000ull
38#define PCIE_REG_PHBC_IO_EN 0x0008000000000000ull
39#define PCIE_REG_PHBC_64BIT_MSI_EN 0x0002000000000000ull
40#define PCIE_REG_PHBC_M32A_EN 0x0000800000000000ull
41#define PCIE_REG_PHBC_M32B_EN 0x0000400000000000ull
42#define PCIE_REG_PHBC_MSI_PE_VALIDATE 0x0000200000000000ull
43#define PCIE_REG_PHBC_DMA_XLATE_BYPASS 0x0000100000000000ull
44
45#define PCIE_REG_IO_BASE_ADDR 0x170
46#define PCIE_REG_IO_BASE_MASK 0x178
47#define PCIE_REG_IO_START_ADDR 0x180
48
49#define PCIE_REG_M32A_BASE_ADDR 0x190
50#define PCIE_REG_M32A_BASE_MASK 0x198
51#define PCIE_REG_M32A_START_ADDR 0x1a0
52
53#define PCIE_REG_M32B_BASE_ADDR 0x1b0
54#define PCIE_REG_M32B_BASE_MASK 0x1b8
55#define PCIE_REG_M32B_START_ADDR 0x1c0
56
57#define PCIE_REG_M64_BASE_ADDR 0x1e0
58#define PCIE_REG_M64_BASE_MASK 0x1e8
59#define PCIE_REG_M64_START_ADDR 0x1f0
60
61#define PCIE_REG_TCE_KILL 0x210
62#define PCIE_REG_TCEKILL_SINGLE 0x8000000000000000ull
63#define PCIE_REG_TCEKILL_ADDR_MASK 0x000003fffffffff8ull
64#define PCIE_REG_TCEKILL_PS_4K 0
65#define PCIE_REG_TCEKILL_PS_64K 1
66#define PCIE_REG_TCEKILL_PS_16M 2
67#define PCIE_REG_TCEKILL_PS_16G 3
68
69#define PCIE_REG_IODA_ADDR 0x220
70#define PCIE_REG_IODA_AD_AUTOINC 0x8000000000000000ull
71#define PCIE_REG_IODA_AD_TBL_MVT 0x0005000000000000ull
72#define PCIE_REG_IODA_AD_TBL_PELT 0x0006000000000000ull
73#define PCIE_REG_IODA_AD_TBL_PESTA 0x0007000000000000ull
74#define PCIE_REG_IODA_AD_TBL_PESTB 0x0008000000000000ull
75#define PCIE_REG_IODA_AD_TBL_TVT 0x0009000000000000ull
76#define PCIE_REG_IODA_AD_TBL_TCE 0x000a000000000000ull
77#define PCIE_REG_IODA_DATA0 0x228
78#define PCIE_REG_IODA_DATA1 0x230
79
80#define PCIE_REG_LOCK2 0x240
81
82#define PCIE_REG_PHB_GEN_CAP 0x250
83#define PCIE_REG_PHB_TCE_CAP 0x258
84#define PCIE_REG_PHB_IRQ_CAP 0x260
85#define PCIE_REG_PHB_EEH_CAP 0x268
86
87#define PCIE_REG_PAPR_ERR_INJ_CONTROL 0x2b0
88#define PCIE_REG_PAPR_ERR_INJ_ADDR 0x2b8
89#define PCIE_REG_PAPR_ERR_INJ_MASK 0x2c0
90
91
92#define PCIE_REG_SYS_CFG1 0x600
93#define PCIE_REG_SYS_CFG1_CLASS_CODE 0x0000000000ffffffull
94
95#define IODA_TVT0_TTA_MASK 0x000fffffffff0000ull
96#define IODA_TVT0_TTA_SHIFT 4
97#define IODA_TVT0_BUSNUM_VALID_MASK 0x000000000000e000ull
98#define IODA_TVT0_TCE_TABLE_SIZE_MASK 0x0000000000001f00ull
99#define IODA_TVT0_TCE_TABLE_SIZE_SHIFT 8
100#define IODA_TVT0_BUSNUM_VALUE_MASK 0x00000000000000ffull
101#define IODA_TVT0_BUSNUM_VALID_SHIFT 0
102#define IODA_TVT1_DEVNUM_VALID 0x2000000000000000ull
103#define IODA_TVT1_DEVNUM_VALUE_MASK 0x1f00000000000000ull
104#define IODA_TVT1_DEVNUM_VALUE_SHIFT 56
105#define IODA_TVT1_FUNCNUM_VALID 0x0008000000000000ull
106#define IODA_TVT1_FUNCNUM_VALUE_MASK 0x0007000000000000ull
107#define IODA_TVT1_FUNCNUM_VALUE_SHIFT 48
108#define IODA_TVT1_IO_PAGE_SIZE_MASK 0x00001f0000000000ull
109#define IODA_TVT1_IO_PAGE_SIZE_SHIFT 40
110#define IODA_TVT1_PE_NUMBER_MASK 0x000000000000003full
111#define IODA_TVT1_PE_NUMBER_SHIFT 0
112
113#define IODA_TVT_COUNT 64
114
115/* UTL Core registers */
116#define PCIE_UTL_SYS_BUS_CONTROL 0x400
117#define PCIE_UTL_STATUS 0x408
118#define PCIE_UTL_SYS_BUS_AGENT_STATUS 0x410
119#define PCIE_UTL_SYS_BUS_AGENT_ERR_SEV 0x418
120#define PCIE_UTL_SYS_BUS_AGENT_IRQ_EN 0x420
121#define PCIE_UTL_SYS_BUS_BURST_SZ_CONF 0x440
122#define PCIE_UTL_REVISION_ID 0x448
123
124#define PCIE_UTL_OUT_POST_HDR_BUF_ALLOC 0x4c0
125#define PCIE_UTL_OUT_POST_DAT_BUF_ALLOC 0x4d0
126#define PCIE_UTL_IN_POST_HDR_BUF_ALLOC 0x4e0
127#define PCIE_UTL_IN_POST_DAT_BUF_ALLOC 0x4f0
128#define PCIE_UTL_OUT_NP_BUF_ALLOC 0x500
129#define PCIE_UTL_IN_NP_BUF_ALLOC 0x510
130#define PCIE_UTL_PCIE_TAGS_ALLOC 0x520
131#define PCIE_UTL_GBIF_READ_TAGS_ALLOC 0x530
132
133#define PCIE_UTL_PCIE_PORT_CONTROL 0x540
134#define PCIE_UTL_PCIE_PORT_STATUS 0x548
135#define PCIE_UTL_PCIE_PORT_ERROR_SEV 0x550
136#define PCIE_UTL_PCIE_PORT_IRQ_EN 0x558
137#define PCIE_UTL_RC_STATUS 0x560
138#define PCIE_UTL_RC_ERR_SEVERITY 0x568
139#define PCIE_UTL_RC_IRQ_EN 0x570
140#define PCIE_UTL_EP_STATUS 0x578
141#define PCIE_UTL_EP_ERR_SEVERITY 0x580
142#define PCIE_UTL_EP_ERR_IRQ_EN 0x588
143
144#define PCIE_UTL_PCI_PM_CTRL1 0x590
145#define PCIE_UTL_PCI_PM_CTRL2 0x598
146
147/* PCIe stack registers */
148#define PCIE_REG_SYSTEM_CONFIG1 0x600
149#define PCIE_REG_SYSTEM_CONFIG2 0x608
150#define PCIE_REG_EP_SYSTEM_CONFIG 0x618
151#define PCIE_REG_EP_FLR 0x620
152#define PCIE_REG_EP_BAR_CONFIG 0x628
153#define PCIE_REG_LINK_CONFIG 0x630
154#define PCIE_REG_PM_CONFIG 0x640
155#define PCIE_REG_DLP_CONTROL 0x650
156#define PCIE_REG_DLP_STATUS 0x658
157#define PCIE_REG_ERR_REPORT_CONTROL 0x660
158#define PCIE_REG_SLOT_CONTROL1 0x670
159#define PCIE_REG_SLOT_CONTROL2 0x678
160#define PCIE_REG_UTL_CONFIG 0x680
161#define PCIE_REG_BUFFERS_CONFIG 0x690
162#define PCIE_REG_ERROR_INJECT 0x698
163#define PCIE_REG_SRIOV_CONFIG 0x6a0
164#define PCIE_REG_PF0_SRIOV_STATUS 0x6a8
165#define PCIE_REG_PF1_SRIOV_STATUS 0x6b0
166#define PCIE_REG_PORT_NUMBER 0x700
167#define PCIE_REG_POR_SYSTEM_CONFIG 0x708
168
169/* PHB internal logic registers */
170#define PCIE_REG_PHB_VERSION 0x800
171#define PCIE_REG_RESET 0x808
172#define PCIE_REG_PHB_CONTROL 0x810
173#define PCIE_REG_PHB_TIMEOUT_CONTROL1 0x878
174#define PCIE_REG_PHB_QUIESCE_DMA 0x888
175#define PCIE_REG_PHB_DMA_READ_TAG_ACTV 0x900
176#define PCIE_REG_PHB_TCE_READ_TAG_ACTV 0x908
177
178/* FIR registers */
179#define PCIE_REG_LEM_FIR_ACCUM 0xc00
180#define PCIE_REG_LEM_FIR_AND_MASK 0xc08
181#define PCIE_REG_LEM_FIR_OR_MASK 0xc10
182#define PCIE_REG_LEM_ACTION0 0xc18
183#define PCIE_REG_LEM_ACTION1 0xc20
184#define PCIE_REG_LEM_ERROR_MASK 0xc30
185#define PCIE_REG_LEM_ERROR_AND_MASK 0xc38
186#define PCIE_REG_LEM_ERROR_OR_MASK 0xc40
187
188/* PHB Error registers */
189#define PCIE_REG_PHB_ERR_STATUS 0xc80
190#define PCIE_REG_PHB_ERR1_STATUS 0xc88
191#define PCIE_REG_PHB_ERR_INJECT 0xc90
192#define PCIE_REG_PHB_ERR_LEM_ENABLE 0xc98
193#define PCIE_REG_PHB_ERR_IRQ_ENABLE 0xca0
194#define PCIE_REG_PHB_ERR_FREEZE_ENABLE 0xca8
195#define PCIE_REG_PHB_ERR_SIDE_ENABLE 0xcb8
196#define PCIE_REG_PHB_ERR_LOG_0 0xcc0
197#define PCIE_REG_PHB_ERR_LOG_1 0xcc8
198#define PCIE_REG_PHB_ERR_STATUS_MASK 0xcd0
199#define PCIE_REG_PHB_ERR1_STATUS_MASK 0xcd8
200
201#define PCIE_REG_MMIO_ERR_STATUS 0xd00
202#define PCIE_REG_MMIO_ERR1_STATUS 0xd08
203#define PCIE_REG_MMIO_ERR_INJECT 0xd10
204#define PCIE_REG_MMIO_ERR_LEM_ENABLE 0xd18
205#define PCIE_REG_MMIO_ERR_IRQ_ENABLE 0xd20
206#define PCIE_REG_MMIO_ERR_FREEZE_ENABLE 0xd28
207#define PCIE_REG_MMIO_ERR_SIDE_ENABLE 0xd38
208#define PCIE_REG_MMIO_ERR_LOG_0 0xd40
209#define PCIE_REG_MMIO_ERR_LOG_1 0xd48
210#define PCIE_REG_MMIO_ERR_STATUS_MASK 0xd50
211#define PCIE_REG_MMIO_ERR1_STATUS_MASK 0xd58
212
213#define PCIE_REG_DMA_ERR_STATUS 0xd80
214#define PCIE_REG_DMA_ERR1_STATUS 0xd88
215#define PCIE_REG_DMA_ERR_INJECT 0xd90
216#define PCIE_REG_DMA_ERR_LEM_ENABLE 0xd98
217#define PCIE_REG_DMA_ERR_IRQ_ENABLE 0xda0
218#define PCIE_REG_DMA_ERR_FREEZE_ENABLE 0xda8
219#define PCIE_REG_DMA_ERR_SIDE_ENABLE 0xdb8
220#define PCIE_REG_DMA_ERR_LOG_0 0xdc0
221#define PCIE_REG_DMA_ERR_LOG_1 0xdc8
222#define PCIE_REG_DMA_ERR_STATUS_MASK 0xdd0
223#define PCIE_REG_DMA_ERR1_STATUS_MASK 0xdd8
224
225/* Shortcuts for access to the above using the PHB definitions
226 * with an offset
227 */
228#define PCIE_REG_ERR_PHB_OFFSET 0x0
229#define PCIE_REG_ERR_MMIO_OFFSET 0x80
230#define PCIE_REG_ERR_DMA_OFFSET 0x100
231
232/* Debug and Trace registers */
233#define PCIE_REG_PHB_DEBUG_CONTROL0 0xe00
234#define PCIE_REG_PHB_DEBUG_STATUS0 0xe08
235#define PCIE_REG_PHB_DEBUG_CONTROL1 0xe10
236#define PCIE_REG_PHB_DEBUG_STATUS1 0xe18
237#define PCIE_REG_PHB_DEBUG_CONTROL2 0xe20
238#define PCIE_REG_PHB_DEBUG_STATUS2 0xe28
239#define PCIE_REG_PHB_DEBUG_CONTROL3 0xe30
240#define PCIE_REG_PHB_DEBUG_STATUS3 0xe38
241#define PCIE_REG_PHB_DEBUG_CONTROL4 0xe40
242#define PCIE_REG_PHB_DEBUG_STATUS4 0xe48
243#define PCIE_REG_PHB_DEBUG_CONTROL5 0xe50
244#define PCIE_REG_PHB_DEBUG_STATUS5 0xe58
245#define PCIE_REG_PHB_DEBUG_CONTROL6 0xe60
246#define PCIE_REG_PHB_DEBUG_STATUS6 0xe68
247
248/* Definition for PCIe errors */
249struct wsp_pcie_err_log_data {
250 __u64 phb_err;
251 __u64 phb_err1;
252 __u64 phb_log0;
253 __u64 phb_log1;
254 __u64 mmio_err;
255 __u64 mmio_err1;
256 __u64 mmio_log0;
257 __u64 mmio_log1;
258 __u64 dma_err;
259 __u64 dma_err1;
260 __u64 dma_log0;
261 __u64 dma_log1;
262 __u64 utl_sys_err;
263 __u64 utl_port_err;
264 __u64 utl_rc_err;
265 __u64 unused;
266};
267
268#endif /* __WSP_PCI_H */
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cf736ca0cf05..84e13253aec5 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
18obj-$(CONFIG_FSL_PMC) += fsl_pmc.o 18obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
19obj-$(CONFIG_FSL_LBC) += fsl_lbc.o 19obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
20obj-$(CONFIG_FSL_GTM) += fsl_gtm.o 20obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
21obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o
22obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o 21obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
23obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o 22obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
24obj-$(CONFIG_FSL_RIO) += fsl_rio.o 23obj-$(CONFIG_FSL_RIO) += fsl_rio.o
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 265f0f09395a..ba4271919062 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -104,7 +104,7 @@ axon_ram_irq_handler(int irq, void *dev)
104 * axon_ram_make_request - make_request() method for block device 104 * axon_ram_make_request - make_request() method for block device
105 * @queue, @bio: see blk_queue_make_request() 105 * @queue, @bio: see blk_queue_make_request()
106 */ 106 */
107static int 107static void
108axon_ram_make_request(struct request_queue *queue, struct bio *bio) 108axon_ram_make_request(struct request_queue *queue, struct bio *bio)
109{ 109{
110 struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data; 110 struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
@@ -113,7 +113,6 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
113 struct bio_vec *vec; 113 struct bio_vec *vec;
114 unsigned int transfered; 114 unsigned int transfered;
115 unsigned short idx; 115 unsigned short idx;
116 int rc = 0;
117 116
118 phys_mem = bank->io_addr + (bio->bi_sector << AXON_RAM_SECTOR_SHIFT); 117 phys_mem = bank->io_addr + (bio->bi_sector << AXON_RAM_SECTOR_SHIFT);
119 phys_end = bank->io_addr + bank->size; 118 phys_end = bank->io_addr + bank->size;
@@ -121,8 +120,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
121 bio_for_each_segment(vec, bio, idx) { 120 bio_for_each_segment(vec, bio, idx) {
122 if (unlikely(phys_mem + vec->bv_len > phys_end)) { 121 if (unlikely(phys_mem + vec->bv_len > phys_end)) {
123 bio_io_error(bio); 122 bio_io_error(bio);
124 rc = -ERANGE; 123 return;
125 break;
126 } 124 }
127 125
128 user_mem = page_address(vec->bv_page) + vec->bv_offset; 126 user_mem = page_address(vec->bv_page) + vec->bv_offset;
@@ -135,8 +133,6 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
135 transfered += vec->bv_len; 133 transfered += vec->bv_len;
136 } 134 }
137 bio_endio(bio, 0); 135 bio_endio(bio, 0);
138
139 return rc;
140} 136}
141 137
142/** 138/**
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index d55d0ad0deab..8db10bb90042 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Scott Wood <scottwood@freescale.com> 4 * Author: Scott Wood <scottwood@freescale.com>
5 * 5 *
6 * Copyright 2007 Freescale Semiconductor, Inc. 6 * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
7 * 7 *
8 * Some parts derived from commproc.c/cpm2_common.c, which is: 8 * Some parts derived from commproc.c/cpm2_common.c, which is:
9 * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) 9 * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
@@ -146,6 +146,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
146 spin_lock_irqsave(&cpm_muram_lock, flags); 146 spin_lock_irqsave(&cpm_muram_lock, flags);
147 cpm_muram_info.alignment = align; 147 cpm_muram_info.alignment = align;
148 start = rh_alloc(&cpm_muram_info, size, "commproc"); 148 start = rh_alloc(&cpm_muram_info, size, "commproc");
149 memset(cpm_muram_addr(start), 0, size);
149 spin_unlock_irqrestore(&cpm_muram_lock, flags); 150 spin_unlock_irqrestore(&cpm_muram_lock, flags);
150 151
151 return start; 152 return start;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 419a77239bd7..e5c344d336ea 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head);
30 30
31struct fsl_msi_feature { 31struct fsl_msi_feature {
32 u32 fsl_pic_ip; 32 u32 fsl_pic_ip;
33 u32 msiir_offset; 33 u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */
34}; 34};
35 35
36struct fsl_msi_cascade_data { 36struct fsl_msi_cascade_data {
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
126{ 126{
127 struct fsl_msi *msi_data = fsl_msi_data; 127 struct fsl_msi *msi_data = fsl_msi_data;
128 struct pci_controller *hose = pci_bus_to_host(pdev->bus); 128 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
129 u64 base = fsl_pci_immrbar_base(hose); 129 u64 address; /* Physical address of the MSIIR */
130 int len;
131 const u64 *reg;
132
133 /* If the msi-address-64 property exists, then use it */
134 reg = of_get_property(hose->dn, "msi-address-64", &len);
135 if (reg && (len == sizeof(u64)))
136 address = be64_to_cpup(reg);
137 else
138 address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset;
130 139
131 msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base); 140 msg->address_lo = lower_32_bits(address);
132 msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base); 141 msg->address_hi = upper_32_bits(address);
133 142
134 msg->data = hwirq; 143 msg->data = hwirq;
135 144
@@ -296,7 +305,7 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
296 } 305 }
297 306
298 msi->msi_virqs[irq_index] = virt_msir; 307 msi->msi_virqs[irq_index] = virt_msir;
299 cascade_data->index = offset + irq_index; 308 cascade_data->index = offset;
300 cascade_data->msi_data = msi; 309 cascade_data->msi_data = msi;
301 irq_set_handler_data(virt_msir, cascade_data); 310 irq_set_handler_data(virt_msir, cascade_data);
302 irq_set_chained_handler(virt_msir, fsl_msi_cascade); 311 irq_set_chained_handler(virt_msir, fsl_msi_cascade);
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
359 368
360 msi->irqhost->host_data = msi; 369 msi->irqhost->host_data = msi;
361 370
362 msi->msi_addr_hi = 0x0; 371 msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff);
363 msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
364 372
365 rc = fsl_msi_init_allocator(msi); 373 rc = fsl_msi_init_allocator(msi);
366 if (rc) { 374 if (rc) {
@@ -376,8 +384,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
376 goto error_out; 384 goto error_out;
377 } 385 }
378 386
379 if (!p) 387 if (!p) {
380 p = all_avail; 388 p = all_avail;
389 len = sizeof(all_avail);
390 }
381 391
382 for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { 392 for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) {
383 if (p[i * 2] % IRQS_PER_MSI_REG || 393 if (p[i * 2] % IRQS_PER_MSI_REG ||
@@ -393,7 +403,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
393 count = p[i * 2 + 1] / IRQS_PER_MSI_REG; 403 count = p[i * 2 + 1] / IRQS_PER_MSI_REG;
394 404
395 for (j = 0; j < count; j++, irq_index++) { 405 for (j = 0; j < count; j++, irq_index++) {
396 err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index); 406 err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index);
397 if (err) 407 if (err)
398 goto error_out; 408 goto error_out;
399 } 409 }
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 624580c252d7..1313abbc5200 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -28,8 +28,7 @@ struct fsl_msi {
28 28
29 unsigned long cascade_irq; 29 unsigned long cascade_irq;
30 30
31 u32 msi_addr_lo; 31 u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
32 u32 msi_addr_hi;
33 void __iomem *msi_regs; 32 void __iomem *msi_regs;
34 u32 feature; 33 u32 feature;
35 int msi_virqs[NR_MSI_REG]; 34 int msi_virqs[NR_MSI_REG];
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d5d3ff3d757e..0842c6f8a3e6 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1285,13 +1285,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1285 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1285 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1286 | MPIC_GREG_GCONF_MCK); 1286 | MPIC_GREG_GCONF_MCK);
1287 1287
1288 /* Read feature register, calculate num CPUs and, for non-ISU 1288 /*
1289 * MPICs, num sources as well. On ISU MPICs, sources are counted 1289 * Read feature register. For non-ISU MPICs, num sources as well. On
1290 * as ISUs are added 1290 * ISU MPICs, sources are counted as ISUs are added
1291 */ 1291 */
1292 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); 1292 greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
1293 mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK)
1294 >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
1295 if (isu_size == 0) { 1293 if (isu_size == 0) {
1296 if (flags & MPIC_BROKEN_FRR_NIRQS) 1294 if (flags & MPIC_BROKEN_FRR_NIRQS)
1297 mpic->num_sources = mpic->irq_count; 1295 mpic->num_sources = mpic->irq_count;
@@ -1301,10 +1299,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1301 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; 1299 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
1302 } 1300 }
1303 1301
1302 /*
1303 * The MPIC driver will crash if there are more cores than we
1304 * can initialize, so we may as well catch that problem here.
1305 */
1306 BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
1307
1304 /* Map the per-CPU registers */ 1308 /* Map the per-CPU registers */
1305 for (i = 0; i < mpic->num_cpus; i++) { 1309 for_each_possible_cpu(i) {
1306 mpic_map(mpic, node, paddr, &mpic->cpuregs[i], 1310 unsigned int cpu = get_hard_smp_processor_id(i);
1307 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 1311
1312 mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
1313 MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
1308 0x1000); 1314 0x1000);
1309 } 1315 }
1310 1316
@@ -1343,7 +1349,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1343 } 1349 }
1344 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," 1350 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
1345 " max %d CPUs\n", 1351 " max %d CPUs\n",
1346 name, vers, (unsigned long long)paddr, mpic->num_cpus); 1352 name, vers, (unsigned long long)paddr, num_possible_cpus());
1347 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", 1353 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
1348 mpic->isu_size, mpic->isu_shift, mpic->isu_mask); 1354 mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
1349 1355
@@ -1742,6 +1748,7 @@ void mpic_reset_core(int cpu)
1742 struct mpic *mpic = mpic_primary; 1748 struct mpic *mpic = mpic_primary;
1743 u32 pir; 1749 u32 pir;
1744 int cpuid = get_hard_smp_processor_id(cpu); 1750 int cpuid = get_hard_smp_processor_id(cpu);
1751 int i;
1745 1752
1746 /* Set target bit for core reset */ 1753 /* Set target bit for core reset */
1747 pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); 1754 pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
@@ -1753,6 +1760,15 @@ void mpic_reset_core(int cpu)
1753 pir &= ~(1 << cpuid); 1760 pir &= ~(1 << cpuid);
1754 mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); 1761 mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
1755 mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); 1762 mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
1763
1764 /* Perform 15 EOI on each reset core to clear pending interrupts.
1765 * This is required for FSL CoreNet based devices */
1766 if (mpic->flags & MPIC_FSL) {
1767 for (i = 0; i < 15; i++) {
1768 _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
1769 MPIC_CPU_EOI, 0);
1770 }
1771 }
1756} 1772}
1757#endif /* CONFIG_SMP */ 1773#endif /* CONFIG_SMP */
1758 1774
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index dbfe96bc878a..862f11b3821e 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -834,7 +834,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np)
834 return 3; 834 return 3;
835} 835}
836 836
837static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 837static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
838{ 838{
839 u32 val = 1 << 24; 839 u32 val = 1 << 24;
840 840
@@ -872,12 +872,12 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
872 return ppc4xx_pciex_port_reset_sdr(port); 872 return ppc4xx_pciex_port_reset_sdr(port);
873} 873}
874 874
875static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 875static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
876{ 876{
877 return ppc440spe_pciex_init_port_hw(port); 877 return ppc440spe_pciex_init_port_hw(port);
878} 878}
879 879
880static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 880static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
881{ 881{
882 int rc = ppc440spe_pciex_init_port_hw(port); 882 int rc = ppc440spe_pciex_init_port_hw(port);
883 883
@@ -936,7 +936,7 @@ static int __init ppc460ex_pciex_core_init(struct device_node *np)
936 return 2; 936 return 2;
937} 937}
938 938
939static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 939static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
940{ 940{
941 u32 val; 941 u32 val;
942 u32 utlset1; 942 u32 utlset1;
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
1092 mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); 1092 mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
1093 mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); 1093 mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
1094 1094
1095 /* Set HSS PRBS enabled */
1096 mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130);
1097 mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130);
1098
1095 udelay(100); 1099 udelay(100);
1096 1100
1097 /* De-assert PLLRESET */ 1101 /* De-assert PLLRESET */
@@ -1122,7 +1126,7 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
1122 return 2; 1126 return 2;
1123} 1127}
1124 1128
1125static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 1129static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1126{ 1130{
1127 1131
1128 if (port->endpoint) 1132 if (port->endpoint)
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1132 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, 1136 dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
1133 0, 0x01000000); 1137 0, 0x01000000);
1134 1138
1135 /*Gen-1*/
1136 mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
1137
1138 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 1139 dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
1139 (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), 1140 (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
1140 PESDRx_RCSSET_RSTPYN); 1141 PESDRx_RCSSET_RSTPYN);
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
1148{ 1149{
1149 /* Max 128 Bytes */ 1150 /* Max 128 Bytes */
1150 out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); 1151 out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000);
1152 /* Assert VRB and TXE - per datasheet turn off addr validation */
1153 out_be32(port->utl_base + PEUTL_PCTL, 0x80800000);
1151 return 0; 1154 return 0;
1152} 1155}
1153 1156
1157static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port)
1158{
1159 void __iomem *mbase;
1160 int attempt = 50;
1161
1162 port->link = 0;
1163
1164 mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
1165 if (mbase == NULL) {
1166 printk(KERN_ERR "%s: Can't map internal config space !",
1167 port->node->full_name);
1168 goto done;
1169 }
1170
1171 while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA)
1172 & PECFG_460SX_DLLSTA_LINKUP))) {
1173 attempt--;
1174 mdelay(10);
1175 }
1176 if (attempt)
1177 port->link = 1;
1178done:
1179 iounmap(mbase);
1180
1181}
1182
1154static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { 1183static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
1155 .core_init = ppc460sx_pciex_core_init, 1184 .core_init = ppc460sx_pciex_core_init,
1156 .port_init_hw = ppc460sx_pciex_init_port_hw, 1185 .port_init_hw = ppc460sx_pciex_init_port_hw,
1157 .setup_utl = ppc460sx_pciex_init_utl, 1186 .setup_utl = ppc460sx_pciex_init_utl,
1158 .check_link = ppc4xx_pciex_check_link_sdr, 1187 .check_link = ppc460sx_pciex_check_link,
1159}; 1188};
1160 1189
1161#endif /* CONFIG_44x */ 1190#endif /* CONFIG_44x */
@@ -1189,7 +1218,7 @@ static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
1189 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); 1218 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
1190} 1219}
1191 1220
1192static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) 1221static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
1193{ 1222{
1194 u32 val; 1223 u32 val;
1195 1224
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1338 if (rc != 0) 1367 if (rc != 0)
1339 return rc; 1368 return rc;
1340 1369
1341 if (ppc4xx_pciex_hwops->check_link)
1342 ppc4xx_pciex_hwops->check_link(port);
1343
1344 /* 1370 /*
1345 * Initialize mapping: disable all regions and configure 1371 * Initialize mapping: disable all regions and configure
1346 * CFG and REG regions based on resources in the device tree 1372 * CFG and REG regions based on resources in the device tree
1347 */ 1373 */
1348 ppc4xx_pciex_port_init_mapping(port); 1374 ppc4xx_pciex_port_init_mapping(port);
1349 1375
1376 if (ppc4xx_pciex_hwops->check_link)
1377 ppc4xx_pciex_hwops->check_link(port);
1378
1350 /* 1379 /*
1351 * Map UTL 1380 * Map UTL
1352 */ 1381 */
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1360 ppc4xx_pciex_hwops->setup_utl(port); 1389 ppc4xx_pciex_hwops->setup_utl(port);
1361 1390
1362 /* 1391 /*
1363 * Check for VC0 active and assert RDY. 1392 * Check for VC0 active or PLL Locked and assert RDY.
1364 */ 1393 */
1365 if (port->sdr_base) { 1394 if (port->sdr_base) {
1366 if (port->link && 1395 if (of_device_is_compatible(port->node,
1367 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1396 "ibm,plb-pciex-460sx")){
1368 1 << 16, 1 << 16, 5000)) { 1397 if (port->link && ppc4xx_pciex_wait_on_sdr(port,
1369 printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); 1398 PESDRn_RCSSTS,
1399 1 << 12, 1 << 12, 5000)) {
1400 printk(KERN_INFO "PCIE%d: PLL not locked\n",
1401 port->index);
1402 port->link = 0;
1403 }
1404 } else if (port->link &&
1405 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
1406 1 << 16, 1 << 16, 5000)) {
1407 printk(KERN_INFO "PCIE%d: VC0 not active\n",
1408 port->index);
1370 port->link = 0; 1409 port->link = 0;
1371 } 1410 }
1372 1411
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1573 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); 1612 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
1574 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); 1613 dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
1575 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); 1614 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
1576 /* Note that 3 here means enabled | single region */ 1615 /*Enabled and single region */
1577 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); 1616 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1617 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
1618 sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
1619 | DCRO_PEGPL_OMRxMSKL_VAL);
1620 else
1621 dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
1622 sa | DCRO_PEGPL_OMR1MSKL_UOT
1623 | DCRO_PEGPL_OMRxMSKL_VAL);
1578 break; 1624 break;
1579 case 1: 1625 case 1:
1580 out_le32(mbase + PECFG_POM1LAH, pciah); 1626 out_le32(mbase + PECFG_POM1LAH, pciah);
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1582 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); 1628 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
1583 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); 1629 dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
1584 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); 1630 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
1585 /* Note that 3 here means enabled | single region */ 1631 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL,
1586 dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); 1632 sa | DCRO_PEGPL_OMRxMSKL_VAL);
1587 break; 1633 break;
1588 case 2: 1634 case 2:
1589 out_le32(mbase + PECFG_POM2LAH, pciah); 1635 out_le32(mbase + PECFG_POM2LAH, pciah);
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port,
1592 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); 1638 dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
1593 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); 1639 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
1594 /* Note that 3 here means enabled | IO space !!! */ 1640 /* Note that 3 here means enabled | IO space !!! */
1595 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3); 1641 dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL,
1642 sa | DCRO_PEGPL_OMR3MSKL_IO
1643 | DCRO_PEGPL_OMRxMSKL_VAL);
1596 break; 1644 break;
1597 } 1645 }
1598 1646
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
1693 if (res->flags & IORESOURCE_PREFETCH) 1741 if (res->flags & IORESOURCE_PREFETCH)
1694 sa |= 0x8; 1742 sa |= 0x8;
1695 1743
1744 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1745 sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
1746
1696 out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); 1747 out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
1697 out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); 1748 out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
1698 1749
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
1854 } 1905 }
1855 out_le16(mbase + 0x202, val); 1906 out_le16(mbase + 0x202, val);
1856 1907
1908 /* Enable Bus master, memory, and io space */
1909 if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
1910 out_le16(mbase + 0x204, 0x7);
1911
1857 if (!port->endpoint) { 1912 if (!port->endpoint) {
1858 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ 1913 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
1859 out_le32(mbase + 0x208, 0x06040001); 1914 out_le32(mbase + 0x208, 0x06040001);
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index c39a134e8684..32ce763a375a 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -464,6 +464,18 @@
464#define PECFG_POM2LAL 0x390 464#define PECFG_POM2LAL 0x390
465#define PECFG_POM2LAH 0x394 465#define PECFG_POM2LAH 0x394
466 466
467/* 460sx only */
468#define PECFG_460SX_DLLSTA 0x3f8
469
470/* 460sx Bit Mappings */
471#define PECFG_460SX_DLLSTA_LINKUP 0x00000010
472#define DCRO_PEGPL_460SX_OMR1MSKL_UOT 0x00000004
473
474/* PEGPL Bit Mappings */
475#define DCRO_PEGPL_OMRxMSKL_VAL 0x00000001
476#define DCRO_PEGPL_OMR1MSKL_UOT 0x00000002
477#define DCRO_PEGPL_OMR3MSKL_IO 0x00000002
478
467/* SDR Bit Mappings */ 479/* SDR Bit Mappings */
468#define PESDRx_RCSSET_HLDPLB 0x10000000 480#define PESDRx_RCSSET_HLDPLB 0x10000000
469#define PESDRx_RCSSET_RSTGU 0x01000000 481#define PESDRx_RCSSET_RSTGU 0x01000000
diff --git a/arch/powerpc/sysdev/xics/Makefile b/arch/powerpc/sysdev/xics/Makefile
index b75a6059337f..c606aa8ba60a 100644
--- a/arch/powerpc/sysdev/xics/Makefile
+++ b/arch/powerpc/sysdev/xics/Makefile
@@ -4,3 +4,4 @@ obj-y += xics-common.o
4obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o 4obj-$(CONFIG_PPC_ICP_NATIVE) += icp-native.o
5obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o 5obj-$(CONFIG_PPC_ICP_HV) += icp-hv.o
6obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o 6obj-$(CONFIG_PPC_ICS_RTAS) += ics-rtas.o
7obj-$(CONFIG_PPC_POWERNV) += ics-opal.o
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 50e32afe392e..4c79b6fbee1c 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -276,7 +276,7 @@ static const struct icp_ops icp_native_ops = {
276#endif 276#endif
277}; 277};
278 278
279int icp_native_init(void) 279int __init icp_native_init(void)
280{ 280{
281 struct device_node *np; 281 struct device_node *np;
282 u32 indx = 0; 282 u32 indx = 0;
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c
new file mode 100644
index 000000000000..f7e8609df0d5
--- /dev/null
+++ b/arch/powerpc/sysdev/xics/ics-opal.c
@@ -0,0 +1,244 @@
1/*
2 * ICS backend for OPAL managed interrupts.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#undef DEBUG
13
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/irq.h>
17#include <linux/smp.h>
18#include <linux/interrupt.h>
19#include <linux/init.h>
20#include <linux/cpu.h>
21#include <linux/of.h>
22#include <linux/spinlock.h>
23#include <linux/msi.h>
24
25#include <asm/prom.h>
26#include <asm/smp.h>
27#include <asm/machdep.h>
28#include <asm/irq.h>
29#include <asm/errno.h>
30#include <asm/xics.h>
31#include <asm/opal.h>
32#include <asm/firmware.h>
33
34static int ics_opal_mangle_server(int server)
35{
36 /* No link for now */
37 return server << 2;
38}
39
40static int ics_opal_unmangle_server(int server)
41{
42 /* No link for now */
43 return server >> 2;
44}
45
46static void ics_opal_unmask_irq(struct irq_data *d)
47{
48 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
49 int64_t rc;
50 int server;
51
52 pr_devel("ics-hal: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq);
53
54 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
55 return;
56
57 server = xics_get_irq_server(d->irq, d->affinity, 0);
58 server = ics_opal_mangle_server(server);
59
60 rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY);
61 if (rc != OPAL_SUCCESS)
62 pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
63 " error %lld\n",
64 __func__, d->irq, hw_irq, server, rc);
65}
66
67static unsigned int ics_opal_startup(struct irq_data *d)
68{
69#ifdef CONFIG_PCI_MSI
70 /*
71 * The generic MSI code returns with the interrupt disabled on the
72 * card, using the MSI mask bits. Firmware doesn't appear to unmask
73 * at that level, so we do it here by hand.
74 */
75 if (d->msi_desc)
76 unmask_msi_irq(d);
77#endif
78
79 /* unmask it */
80 ics_opal_unmask_irq(d);
81 return 0;
82}
83
84static void ics_opal_mask_real_irq(unsigned int hw_irq)
85{
86 int server = ics_opal_mangle_server(xics_default_server);
87 int64_t rc;
88
89 if (hw_irq == XICS_IPI)
90 return;
91
92 /* Have to set XIVE to 0xff to be able to remove a slot */
93 rc = opal_set_xive(hw_irq, server, 0xff);
94 if (rc != OPAL_SUCCESS)
95 pr_err("%s: opal_set_xive(0xff) irq=%u returned %lld\n",
96 __func__, hw_irq, rc);
97}
98
99static void ics_opal_mask_irq(struct irq_data *d)
100{
101 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
102
103 pr_devel("ics-hal: mask virq %d [hw 0x%x]\n", d->irq, hw_irq);
104
105 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
106 return;
107 ics_opal_mask_real_irq(hw_irq);
108}
109
110static int ics_opal_set_affinity(struct irq_data *d,
111 const struct cpumask *cpumask,
112 bool force)
113{
114 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
115 int16_t server;
116 int8_t priority;
117 int64_t rc;
118 int wanted_server;
119
120 if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
121 return -1;
122
123 rc = opal_get_xive(hw_irq, &server, &priority);
124 if (rc != OPAL_SUCCESS) {
125 pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
126 " error %lld\n",
127 __func__, d->irq, hw_irq, server, rc);
128 return -1;
129 }
130
131 wanted_server = xics_get_irq_server(d->irq, cpumask, 1);
132 if (wanted_server < 0) {
133 char cpulist[128];
134 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
135 pr_warning("%s: No online cpus in the mask %s for irq %d\n",
136 __func__, cpulist, d->irq);
137 return -1;
138 }
139 server = ics_opal_mangle_server(wanted_server);
140
141 pr_devel("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n",
142 d->irq, hw_irq, wanted_server, server);
143
144 rc = opal_set_xive(hw_irq, server, priority);
145 if (rc != OPAL_SUCCESS) {
146 pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
147 " error %lld\n",
148 __func__, d->irq, hw_irq, server, rc);
149 return -1;
150 }
151 return 0;
152}
153
154static struct irq_chip ics_opal_irq_chip = {
155 .name = "OPAL ICS",
156 .irq_startup = ics_opal_startup,
157 .irq_mask = ics_opal_mask_irq,
158 .irq_unmask = ics_opal_unmask_irq,
159 .irq_eoi = NULL, /* Patched at init time */
160 .irq_set_affinity = ics_opal_set_affinity
161};
162
163static int ics_opal_map(struct ics *ics, unsigned int virq);
164static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec);
165static long ics_opal_get_server(struct ics *ics, unsigned long vec);
166
167static int ics_opal_host_match(struct ics *ics, struct device_node *node)
168{
169 return 1;
170}
171
172/* Only one global & state struct ics */
173static struct ics ics_hal = {
174 .map = ics_opal_map,
175 .mask_unknown = ics_opal_mask_unknown,
176 .get_server = ics_opal_get_server,
177 .host_match = ics_opal_host_match,
178};
179
180static int ics_opal_map(struct ics *ics, unsigned int virq)
181{
182 unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
183 int64_t rc;
184 int16_t server;
185 int8_t priority;
186
187 if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
188 return -EINVAL;
189
190 /* Check if HAL knows about this interrupt */
191 rc = opal_get_xive(hw_irq, &server, &priority);
192 if (rc != OPAL_SUCCESS)
193 return -ENXIO;
194
195 irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq);
196 irq_set_chip_data(virq, &ics_hal);
197
198 return 0;
199}
200
201static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec)
202{
203 int64_t rc;
204 int16_t server;
205 int8_t priority;
206
207 /* Check if HAL knows about this interrupt */
208 rc = opal_get_xive(vec, &server, &priority);
209 if (rc != OPAL_SUCCESS)
210 return;
211
212 ics_opal_mask_real_irq(vec);
213}
214
215static long ics_opal_get_server(struct ics *ics, unsigned long vec)
216{
217 int64_t rc;
218 int16_t server;
219 int8_t priority;
220
221 /* Check if HAL knows about this interrupt */
222 rc = opal_get_xive(vec, &server, &priority);
223 if (rc != OPAL_SUCCESS)
224 return -1;
225 return ics_opal_unmangle_server(server);
226}
227
228int __init ics_opal_init(void)
229{
230 if (!firmware_has_feature(FW_FEATURE_OPAL))
231 return -ENODEV;
232
233 /* We need to patch our irq chip's EOI to point to the
234 * right ICP
235 */
236 ics_opal_irq_chip.irq_eoi = icp_ops->eoi;
237
238 /* Register ourselves */
239 xics_register_ics(&ics_hal);
240
241 pr_info("ICS OPAL backend registered\n");
242
243 return 0;
244}
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index 445c5a01b766..3d93a8ded0f8 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -409,14 +409,10 @@ void __init xics_init(void)
409 int rc = -1; 409 int rc = -1;
410 410
411 /* Fist locate ICP */ 411 /* Fist locate ICP */
412#ifdef CONFIG_PPC_ICP_HV
413 if (firmware_has_feature(FW_FEATURE_LPAR)) 412 if (firmware_has_feature(FW_FEATURE_LPAR))
414 rc = icp_hv_init(); 413 rc = icp_hv_init();
415#endif
416#ifdef CONFIG_PPC_ICP_NATIVE
417 if (rc < 0) 414 if (rc < 0)
418 rc = icp_native_init(); 415 rc = icp_native_init();
419#endif
420 if (rc < 0) { 416 if (rc < 0) {
421 pr_warning("XICS: Cannot find a Presentation Controller !\n"); 417 pr_warning("XICS: Cannot find a Presentation Controller !\n");
422 return; 418 return;
@@ -429,9 +425,9 @@ void __init xics_init(void)
429 xics_ipi_chip.irq_eoi = icp_ops->eoi; 425 xics_ipi_chip.irq_eoi = icp_ops->eoi;
430 426
431 /* Now locate ICS */ 427 /* Now locate ICS */
432#ifdef CONFIG_PPC_ICS_RTAS
433 rc = ics_rtas_init(); 428 rc = ics_rtas_init();
434#endif 429 if (rc < 0)
430 rc = ics_opal_init();
435 if (rc < 0) 431 if (rc < 0)
436 pr_warning("XICS: Cannot find a Source Controller !\n"); 432 pr_warning("XICS: Cannot find a Source Controller !\n");
437 433
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 42541bbcc7fa..13f82f847669 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -340,8 +340,8 @@ int cpus_are_in_xmon(void)
340 340
341static inline int unrecoverable_excp(struct pt_regs *regs) 341static inline int unrecoverable_excp(struct pt_regs *regs)
342{ 342{
343#ifdef CONFIG_4xx 343#if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
344 /* We have no MSR_RI bit on 4xx, so we simply return false */ 344 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
345 return 0; 345 return 0;
346#else 346#else
347 return ((regs->msr & MSR_RI) == 0); 347 return ((regs->msr & MSR_RI) == 0);
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index d36265758911..7030f4c8cf11 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -345,9 +345,10 @@ static struct soc_camera_platform_info camera_info = {
345 .width = 640, 345 .width = 640,
346 .height = 480, 346 .height = 480,
347 }, 347 },
348 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | 348 .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
349 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 | 349 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
350 SOCAM_DATA_ACTIVE_HIGH, 350 V4L2_MBUS_DATA_ACTIVE_HIGH,
351 .mbus_type = V4L2_MBUS_PARALLEL,
351 .set_capture = camera_set_capture, 352 .set_capture = camera_set_capture,
352}; 353};
353 354
@@ -501,8 +502,7 @@ static struct i2c_board_info ap325rxa_i2c_camera[] = {
501}; 502};
502 503
503static struct ov772x_camera_info ov7725_info = { 504static struct ov772x_camera_info ov7725_info = {
504 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \ 505 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
505 OV772X_FLAG_8BIT,
506 .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), 506 .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
507}; 507};
508 508
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 2d4c9c8c6664..e4c81195929c 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -448,9 +448,7 @@ static struct i2c_board_info migor_i2c_camera[] = {
448 }, 448 },
449}; 449};
450 450
451static struct ov772x_camera_info ov7725_info = { 451static struct ov772x_camera_info ov7725_info;
452 .flags = OV772X_FLAG_8BIT,
453};
454 452
455static struct soc_camera_link ov7725_link = { 453static struct soc_camera_link ov7725_link = {
456 .power = ov7725_power, 454 .power = ov7725_power,
diff --git a/arch/tile/include/arch/Kbuild b/arch/tile/include/arch/Kbuild
new file mode 100644
index 000000000000..9c0ea24cc948
--- /dev/null
+++ b/arch/tile/include/arch/Kbuild
@@ -0,0 +1,17 @@
1header-y += abi.h
2header-y += chip.h
3header-y += chip_tile64.h
4header-y += chip_tilegx.h
5header-y += chip_tilepro.h
6header-y += icache.h
7header-y += interrupts.h
8header-y += interrupts_32.h
9header-y += interrupts_64.h
10header-y += opcode.h
11header-y += opcode_tilegx.h
12header-y += opcode_tilepro.h
13header-y += sim.h
14header-y += sim_def.h
15header-y += spr_def.h
16header-y += spr_def_32.h
17header-y += spr_def_64.h
diff --git a/arch/tile/include/arch/abi.h b/arch/tile/include/arch/abi.h
index 8affc76f771a..c55a3d432644 100644
--- a/arch/tile/include/arch/abi.h
+++ b/arch/tile/include/arch/abi.h
@@ -15,13 +15,78 @@
15/** 15/**
16 * @file 16 * @file
17 * 17 *
18 * ABI-related register definitions helpful when writing assembly code. 18 * ABI-related register definitions.
19 */ 19 */
20 20
21#ifndef __ARCH_ABI_H__ 21#ifndef __ARCH_ABI_H__
22#define __ARCH_ABI_H__
23 22
24#include <arch/chip.h> 23#if !defined __need_int_reg_t && !defined __DOXYGEN__
24# define __ARCH_ABI_H__
25# include <arch/chip.h>
26#endif
27
28/* Provide the basic machine types. */
29#ifndef __INT_REG_BITS
30
31/** Number of bits in a register. */
32#if defined __tilegx__
33# define __INT_REG_BITS 64
34#elif defined __tilepro__
35# define __INT_REG_BITS 32
36#elif !defined __need_int_reg_t
37# include <arch/chip.h>
38# define __INT_REG_BITS CHIP_WORD_SIZE()
39#else
40# error Unrecognized architecture with __need_int_reg_t
41#endif
42
43#if __INT_REG_BITS == 64
44
45#ifndef __ASSEMBLER__
46/** Unsigned type that can hold a register. */
47typedef unsigned long long __uint_reg_t;
48
49/** Signed type that can hold a register. */
50typedef long long __int_reg_t;
51#endif
52
53/** String prefix to use for printf(). */
54#define __INT_REG_FMT "ll"
55
56#else
57
58#ifndef __ASSEMBLER__
59/** Unsigned type that can hold a register. */
60typedef unsigned long __uint_reg_t;
61
62/** Signed type that can hold a register. */
63typedef long __int_reg_t;
64#endif
65
66/** String prefix to use for printf(). */
67#define __INT_REG_FMT "l"
68
69#endif
70#endif /* __INT_REG_BITS */
71
72
73#ifndef __need_int_reg_t
74
75
76#ifndef __ASSEMBLER__
77/** Unsigned type that can hold a register. */
78typedef __uint_reg_t uint_reg_t;
79
80/** Signed type that can hold a register. */
81typedef __int_reg_t int_reg_t;
82#endif
83
84/** String prefix to use for printf(). */
85#define INT_REG_FMT __INT_REG_FMT
86
87/** Number of bits in a register. */
88#define INT_REG_BITS __INT_REG_BITS
89
25 90
26/* Registers 0 - 55 are "normal", but some perform special roles. */ 91/* Registers 0 - 55 are "normal", but some perform special roles. */
27 92
@@ -59,7 +124,7 @@
59 * The ABI requires callers to allocate a caller state save area of 124 * The ABI requires callers to allocate a caller state save area of
60 * this many bytes at the bottom of each stack frame. 125 * this many bytes at the bottom of each stack frame.
61 */ 126 */
62#define C_ABI_SAVE_AREA_SIZE (2 * (CHIP_WORD_SIZE() / 8)) 127#define C_ABI_SAVE_AREA_SIZE (2 * (INT_REG_BITS / 8))
63 128
64/** 129/**
65 * The operand to an 'info' opcode directing the backtracer to not 130 * The operand to an 'info' opcode directing the backtracer to not
@@ -67,30 +132,10 @@
67 */ 132 */
68#define INFO_OP_CANNOT_BACKTRACE 2 133#define INFO_OP_CANNOT_BACKTRACE 2
69 134
70#ifndef __ASSEMBLER__
71#if CHIP_WORD_SIZE() > 32
72 135
73/** Unsigned type that can hold a register. */ 136#endif /* !__need_int_reg_t */
74typedef unsigned long long uint_reg_t;
75 137
76/** Signed type that can hold a register. */ 138/* Make sure we later can get all the definitions and declarations. */
77typedef long long int_reg_t; 139#undef __need_int_reg_t
78
79/** String prefix to use for printf(). */
80#define INT_REG_FMT "ll"
81
82#elif !defined(__LP64__) /* avoid confusion with LP64 cross-build tools */
83
84/** Unsigned type that can hold a register. */
85typedef unsigned long uint_reg_t;
86
87/** Signed type that can hold a register. */
88typedef long int_reg_t;
89
90/** String prefix to use for printf(). */
91#define INT_REG_FMT "l"
92
93#endif
94#endif /* __ASSEMBLER__ */
95 140
96#endif /* !__ARCH_ABI_H__ */ 141#endif /* !__ARCH_ABI_H__ */
diff --git a/arch/tile/include/asm/opcode_constants.h b/arch/tile/include/arch/opcode.h
index 37a9f2958cb1..92d15229ecec 100644
--- a/arch/tile/include/asm/opcode_constants.h
+++ b/arch/tile/include/arch/opcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -12,15 +12,10 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#ifndef _ASM_TILE_OPCODE_CONSTANTS_H 15#if defined(__tilepro__)
16#define _ASM_TILE_OPCODE_CONSTANTS_H 16#include <arch/opcode_tilepro.h>
17 17#elif defined(__tilegx__)
18#include <arch/chip.h> 18#include <arch/opcode_tilegx.h>
19
20#if CHIP_WORD_SIZE() == 64
21#include <asm/opcode_constants_64.h>
22#else 19#else
23#include <asm/opcode_constants_32.h> 20#error Unexpected Tilera chip type
24#endif 21#endif
25
26#endif /* _ASM_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/opcode_constants_64.h b/arch/tile/include/arch/opcode_tilegx.h
index 710192869476..c14d02c81600 100644
--- a/arch/tile/include/asm/opcode_constants_64.h
+++ b/arch/tile/include/arch/opcode_tilegx.h
@@ -1,4 +1,5 @@
1/* 1/* TILE-Gx opcode information.
2 *
2 * Copyright 2011 Tilera Corporation. All Rights Reserved. 3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
3 * 4 *
4 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -10,13 +11,805 @@
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for 12 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details. 13 * more details.
14 *
15 *
16 *
17 *
18 *
13 */ 19 */
14 20
15/* This file is machine-generated; DO NOT EDIT! */ 21#ifndef __ARCH_OPCODE_H__
22#define __ARCH_OPCODE_H__
23
24#ifndef __ASSEMBLER__
25
26typedef unsigned long long tilegx_bundle_bits;
27
28/* These are the bits that determine if a bundle is in the X encoding. */
29#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
30
31enum
32{
33 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
34 TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
35
36 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
37 TILEGX_NUM_PIPELINE_ENCODINGS = 5,
38
39 /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
40 TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
41
42 /* Instructions take this many bytes. */
43 TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
44
45 /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
46 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
47
48 /* Bundles should be aligned modulo this number of bytes. */
49 TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
50 (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
51
52 /* Number of registers (some are magic, such as network I/O). */
53 TILEGX_NUM_REGISTERS = 64,
54};
55
56/* Make a few "tile_" variables to simplify common code between
57 architectures. */
58
59typedef tilegx_bundle_bits tile_bundle_bits;
60#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
61#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
62#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
63 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
64
65/* 64-bit pattern for a { bpt ; nop } bundle. */
66#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
67
68static __inline unsigned int
69get_BFEnd_X0(tilegx_bundle_bits num)
70{
71 const unsigned int n = (unsigned int)num;
72 return (((n >> 12)) & 0x3f);
73}
74
75static __inline unsigned int
76get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
77{
78 const unsigned int n = (unsigned int)num;
79 return (((n >> 24)) & 0xf);
80}
81
82static __inline unsigned int
83get_BFStart_X0(tilegx_bundle_bits num)
84{
85 const unsigned int n = (unsigned int)num;
86 return (((n >> 18)) & 0x3f);
87}
88
89static __inline unsigned int
90get_BrOff_X1(tilegx_bundle_bits n)
91{
92 return (((unsigned int)(n >> 31)) & 0x0000003f) |
93 (((unsigned int)(n >> 37)) & 0x0001ffc0);
94}
95
96static __inline unsigned int
97get_BrType_X1(tilegx_bundle_bits n)
98{
99 return (((unsigned int)(n >> 54)) & 0x1f);
100}
101
102static __inline unsigned int
103get_Dest_Imm8_X1(tilegx_bundle_bits n)
104{
105 return (((unsigned int)(n >> 31)) & 0x0000003f) |
106 (((unsigned int)(n >> 43)) & 0x000000c0);
107}
108
109static __inline unsigned int
110get_Dest_X0(tilegx_bundle_bits num)
111{
112 const unsigned int n = (unsigned int)num;
113 return (((n >> 0)) & 0x3f);
114}
115
116static __inline unsigned int
117get_Dest_X1(tilegx_bundle_bits n)
118{
119 return (((unsigned int)(n >> 31)) & 0x3f);
120}
121
122static __inline unsigned int
123get_Dest_Y0(tilegx_bundle_bits num)
124{
125 const unsigned int n = (unsigned int)num;
126 return (((n >> 0)) & 0x3f);
127}
128
129static __inline unsigned int
130get_Dest_Y1(tilegx_bundle_bits n)
131{
132 return (((unsigned int)(n >> 31)) & 0x3f);
133}
134
135static __inline unsigned int
136get_Imm16_X0(tilegx_bundle_bits num)
137{
138 const unsigned int n = (unsigned int)num;
139 return (((n >> 12)) & 0xffff);
140}
141
142static __inline unsigned int
143get_Imm16_X1(tilegx_bundle_bits n)
144{
145 return (((unsigned int)(n >> 43)) & 0xffff);
146}
147
148static __inline unsigned int
149get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
150{
151 const unsigned int n = (unsigned int)num;
152 return (((n >> 20)) & 0xff);
153}
154
155static __inline unsigned int
156get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
157{
158 return (((unsigned int)(n >> 51)) & 0xff);
159}
160
161static __inline unsigned int
162get_Imm8_X0(tilegx_bundle_bits num)
163{
164 const unsigned int n = (unsigned int)num;
165 return (((n >> 12)) & 0xff);
166}
167
168static __inline unsigned int
169get_Imm8_X1(tilegx_bundle_bits n)
170{
171 return (((unsigned int)(n >> 43)) & 0xff);
172}
173
174static __inline unsigned int
175get_Imm8_Y0(tilegx_bundle_bits num)
176{
177 const unsigned int n = (unsigned int)num;
178 return (((n >> 12)) & 0xff);
179}
180
181static __inline unsigned int
182get_Imm8_Y1(tilegx_bundle_bits n)
183{
184 return (((unsigned int)(n >> 43)) & 0xff);
185}
186
187static __inline unsigned int
188get_JumpOff_X1(tilegx_bundle_bits n)
189{
190 return (((unsigned int)(n >> 31)) & 0x7ffffff);
191}
192
193static __inline unsigned int
194get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
195{
196 return (((unsigned int)(n >> 58)) & 0x1);
197}
198
199static __inline unsigned int
200get_MF_Imm14_X1(tilegx_bundle_bits n)
201{
202 return (((unsigned int)(n >> 37)) & 0x3fff);
203}
204
205static __inline unsigned int
206get_MT_Imm14_X1(tilegx_bundle_bits n)
207{
208 return (((unsigned int)(n >> 31)) & 0x0000003f) |
209 (((unsigned int)(n >> 37)) & 0x00003fc0);
210}
211
212static __inline unsigned int
213get_Mode(tilegx_bundle_bits n)
214{
215 return (((unsigned int)(n >> 62)) & 0x3);
216}
217
218static __inline unsigned int
219get_Opcode_X0(tilegx_bundle_bits num)
220{
221 const unsigned int n = (unsigned int)num;
222 return (((n >> 28)) & 0x7);
223}
224
225static __inline unsigned int
226get_Opcode_X1(tilegx_bundle_bits n)
227{
228 return (((unsigned int)(n >> 59)) & 0x7);
229}
230
231static __inline unsigned int
232get_Opcode_Y0(tilegx_bundle_bits num)
233{
234 const unsigned int n = (unsigned int)num;
235 return (((n >> 27)) & 0xf);
236}
237
238static __inline unsigned int
239get_Opcode_Y1(tilegx_bundle_bits n)
240{
241 return (((unsigned int)(n >> 58)) & 0xf);
242}
243
244static __inline unsigned int
245get_Opcode_Y2(tilegx_bundle_bits n)
246{
247 return (((n >> 26)) & 0x00000001) |
248 (((unsigned int)(n >> 56)) & 0x00000002);
249}
250
251static __inline unsigned int
252get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
253{
254 const unsigned int n = (unsigned int)num;
255 return (((n >> 18)) & 0x3ff);
256}
257
258static __inline unsigned int
259get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
260{
261 return (((unsigned int)(n >> 49)) & 0x3ff);
262}
263
264static __inline unsigned int
265get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
266{
267 const unsigned int n = (unsigned int)num;
268 return (((n >> 18)) & 0x3);
269}
270
271static __inline unsigned int
272get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
273{
274 return (((unsigned int)(n >> 49)) & 0x3);
275}
276
277static __inline unsigned int
278get_ShAmt_X0(tilegx_bundle_bits num)
279{
280 const unsigned int n = (unsigned int)num;
281 return (((n >> 12)) & 0x3f);
282}
283
284static __inline unsigned int
285get_ShAmt_X1(tilegx_bundle_bits n)
286{
287 return (((unsigned int)(n >> 43)) & 0x3f);
288}
289
290static __inline unsigned int
291get_ShAmt_Y0(tilegx_bundle_bits num)
292{
293 const unsigned int n = (unsigned int)num;
294 return (((n >> 12)) & 0x3f);
295}
296
297static __inline unsigned int
298get_ShAmt_Y1(tilegx_bundle_bits n)
299{
300 return (((unsigned int)(n >> 43)) & 0x3f);
301}
302
303static __inline unsigned int
304get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
305{
306 const unsigned int n = (unsigned int)num;
307 return (((n >> 18)) & 0x3ff);
308}
309
310static __inline unsigned int
311get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
312{
313 return (((unsigned int)(n >> 49)) & 0x3ff);
314}
315
316static __inline unsigned int
317get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
318{
319 const unsigned int n = (unsigned int)num;
320 return (((n >> 18)) & 0x3);
321}
322
323static __inline unsigned int
324get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
325{
326 return (((unsigned int)(n >> 49)) & 0x3);
327}
328
329static __inline unsigned int
330get_SrcA_X0(tilegx_bundle_bits num)
331{
332 const unsigned int n = (unsigned int)num;
333 return (((n >> 6)) & 0x3f);
334}
335
336static __inline unsigned int
337get_SrcA_X1(tilegx_bundle_bits n)
338{
339 return (((unsigned int)(n >> 37)) & 0x3f);
340}
341
342static __inline unsigned int
343get_SrcA_Y0(tilegx_bundle_bits num)
344{
345 const unsigned int n = (unsigned int)num;
346 return (((n >> 6)) & 0x3f);
347}
348
349static __inline unsigned int
350get_SrcA_Y1(tilegx_bundle_bits n)
351{
352 return (((unsigned int)(n >> 37)) & 0x3f);
353}
354
355static __inline unsigned int
356get_SrcA_Y2(tilegx_bundle_bits num)
357{
358 const unsigned int n = (unsigned int)num;
359 return (((n >> 20)) & 0x3f);
360}
361
362static __inline unsigned int
363get_SrcBDest_Y2(tilegx_bundle_bits n)
364{
365 return (((unsigned int)(n >> 51)) & 0x3f);
366}
367
368static __inline unsigned int
369get_SrcB_X0(tilegx_bundle_bits num)
370{
371 const unsigned int n = (unsigned int)num;
372 return (((n >> 12)) & 0x3f);
373}
374
375static __inline unsigned int
376get_SrcB_X1(tilegx_bundle_bits n)
377{
378 return (((unsigned int)(n >> 43)) & 0x3f);
379}
380
381static __inline unsigned int
382get_SrcB_Y0(tilegx_bundle_bits num)
383{
384 const unsigned int n = (unsigned int)num;
385 return (((n >> 12)) & 0x3f);
386}
387
388static __inline unsigned int
389get_SrcB_Y1(tilegx_bundle_bits n)
390{
391 return (((unsigned int)(n >> 43)) & 0x3f);
392}
393
394static __inline unsigned int
395get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
396{
397 const unsigned int n = (unsigned int)num;
398 return (((n >> 12)) & 0x3f);
399}
400
401static __inline unsigned int
402get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
403{
404 return (((unsigned int)(n >> 43)) & 0x3f);
405}
406
407static __inline unsigned int
408get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
409{
410 const unsigned int n = (unsigned int)num;
411 return (((n >> 12)) & 0x3f);
412}
413
414static __inline unsigned int
415get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
416{
417 return (((unsigned int)(n >> 43)) & 0x3f);
418}
419
420
421static __inline int
422sign_extend(int n, int num_bits)
423{
424 int shift = (int)(sizeof(int) * 8 - num_bits);
425 return (n << shift) >> shift;
426}
427
428
429
430static __inline tilegx_bundle_bits
431create_BFEnd_X0(int num)
432{
433 const unsigned int n = (unsigned int)num;
434 return ((n & 0x3f) << 12);
435}
436
437static __inline tilegx_bundle_bits
438create_BFOpcodeExtension_X0(int num)
439{
440 const unsigned int n = (unsigned int)num;
441 return ((n & 0xf) << 24);
442}
443
444static __inline tilegx_bundle_bits
445create_BFStart_X0(int num)
446{
447 const unsigned int n = (unsigned int)num;
448 return ((n & 0x3f) << 18);
449}
450
451static __inline tilegx_bundle_bits
452create_BrOff_X1(int num)
453{
454 const unsigned int n = (unsigned int)num;
455 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
456 (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
457}
458
459static __inline tilegx_bundle_bits
460create_BrType_X1(int num)
461{
462 const unsigned int n = (unsigned int)num;
463 return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
464}
465
466static __inline tilegx_bundle_bits
467create_Dest_Imm8_X1(int num)
468{
469 const unsigned int n = (unsigned int)num;
470 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
471 (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
472}
473
474static __inline tilegx_bundle_bits
475create_Dest_X0(int num)
476{
477 const unsigned int n = (unsigned int)num;
478 return ((n & 0x3f) << 0);
479}
480
481static __inline tilegx_bundle_bits
482create_Dest_X1(int num)
483{
484 const unsigned int n = (unsigned int)num;
485 return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
486}
487
488static __inline tilegx_bundle_bits
489create_Dest_Y0(int num)
490{
491 const unsigned int n = (unsigned int)num;
492 return ((n & 0x3f) << 0);
493}
494
495static __inline tilegx_bundle_bits
496create_Dest_Y1(int num)
497{
498 const unsigned int n = (unsigned int)num;
499 return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
500}
501
502static __inline tilegx_bundle_bits
503create_Imm16_X0(int num)
504{
505 const unsigned int n = (unsigned int)num;
506 return ((n & 0xffff) << 12);
507}
508
509static __inline tilegx_bundle_bits
510create_Imm16_X1(int num)
511{
512 const unsigned int n = (unsigned int)num;
513 return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
514}
515
516static __inline tilegx_bundle_bits
517create_Imm8OpcodeExtension_X0(int num)
518{
519 const unsigned int n = (unsigned int)num;
520 return ((n & 0xff) << 20);
521}
522
523static __inline tilegx_bundle_bits
524create_Imm8OpcodeExtension_X1(int num)
525{
526 const unsigned int n = (unsigned int)num;
527 return (((tilegx_bundle_bits)(n & 0xff)) << 51);
528}
529
530static __inline tilegx_bundle_bits
531create_Imm8_X0(int num)
532{
533 const unsigned int n = (unsigned int)num;
534 return ((n & 0xff) << 12);
535}
536
537static __inline tilegx_bundle_bits
538create_Imm8_X1(int num)
539{
540 const unsigned int n = (unsigned int)num;
541 return (((tilegx_bundle_bits)(n & 0xff)) << 43);
542}
543
544static __inline tilegx_bundle_bits
545create_Imm8_Y0(int num)
546{
547 const unsigned int n = (unsigned int)num;
548 return ((n & 0xff) << 12);
549}
550
551static __inline tilegx_bundle_bits
552create_Imm8_Y1(int num)
553{
554 const unsigned int n = (unsigned int)num;
555 return (((tilegx_bundle_bits)(n & 0xff)) << 43);
556}
557
558static __inline tilegx_bundle_bits
559create_JumpOff_X1(int num)
560{
561 const unsigned int n = (unsigned int)num;
562 return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
563}
564
565static __inline tilegx_bundle_bits
566create_JumpOpcodeExtension_X1(int num)
567{
568 const unsigned int n = (unsigned int)num;
569 return (((tilegx_bundle_bits)(n & 0x1)) << 58);
570}
571
572static __inline tilegx_bundle_bits
573create_MF_Imm14_X1(int num)
574{
575 const unsigned int n = (unsigned int)num;
576 return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
577}
578
579static __inline tilegx_bundle_bits
580create_MT_Imm14_X1(int num)
581{
582 const unsigned int n = (unsigned int)num;
583 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
584 (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
585}
586
587static __inline tilegx_bundle_bits
588create_Mode(int num)
589{
590 const unsigned int n = (unsigned int)num;
591 return (((tilegx_bundle_bits)(n & 0x3)) << 62);
592}
593
594static __inline tilegx_bundle_bits
595create_Opcode_X0(int num)
596{
597 const unsigned int n = (unsigned int)num;
598 return ((n & 0x7) << 28);
599}
600
601static __inline tilegx_bundle_bits
602create_Opcode_X1(int num)
603{
604 const unsigned int n = (unsigned int)num;
605 return (((tilegx_bundle_bits)(n & 0x7)) << 59);
606}
607
608static __inline tilegx_bundle_bits
609create_Opcode_Y0(int num)
610{
611 const unsigned int n = (unsigned int)num;
612 return ((n & 0xf) << 27);
613}
614
615static __inline tilegx_bundle_bits
616create_Opcode_Y1(int num)
617{
618 const unsigned int n = (unsigned int)num;
619 return (((tilegx_bundle_bits)(n & 0xf)) << 58);
620}
621
622static __inline tilegx_bundle_bits
623create_Opcode_Y2(int num)
624{
625 const unsigned int n = (unsigned int)num;
626 return ((n & 0x00000001) << 26) |
627 (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
628}
629
630static __inline tilegx_bundle_bits
631create_RRROpcodeExtension_X0(int num)
632{
633 const unsigned int n = (unsigned int)num;
634 return ((n & 0x3ff) << 18);
635}
636
637static __inline tilegx_bundle_bits
638create_RRROpcodeExtension_X1(int num)
639{
640 const unsigned int n = (unsigned int)num;
641 return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
642}
643
644static __inline tilegx_bundle_bits
645create_RRROpcodeExtension_Y0(int num)
646{
647 const unsigned int n = (unsigned int)num;
648 return ((n & 0x3) << 18);
649}
650
651static __inline tilegx_bundle_bits
652create_RRROpcodeExtension_Y1(int num)
653{
654 const unsigned int n = (unsigned int)num;
655 return (((tilegx_bundle_bits)(n & 0x3)) << 49);
656}
657
658static __inline tilegx_bundle_bits
659create_ShAmt_X0(int num)
660{
661 const unsigned int n = (unsigned int)num;
662 return ((n & 0x3f) << 12);
663}
664
665static __inline tilegx_bundle_bits
666create_ShAmt_X1(int num)
667{
668 const unsigned int n = (unsigned int)num;
669 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
670}
671
672static __inline tilegx_bundle_bits
673create_ShAmt_Y0(int num)
674{
675 const unsigned int n = (unsigned int)num;
676 return ((n & 0x3f) << 12);
677}
678
679static __inline tilegx_bundle_bits
680create_ShAmt_Y1(int num)
681{
682 const unsigned int n = (unsigned int)num;
683 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
684}
685
686static __inline tilegx_bundle_bits
687create_ShiftOpcodeExtension_X0(int num)
688{
689 const unsigned int n = (unsigned int)num;
690 return ((n & 0x3ff) << 18);
691}
692
693static __inline tilegx_bundle_bits
694create_ShiftOpcodeExtension_X1(int num)
695{
696 const unsigned int n = (unsigned int)num;
697 return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
698}
699
700static __inline tilegx_bundle_bits
701create_ShiftOpcodeExtension_Y0(int num)
702{
703 const unsigned int n = (unsigned int)num;
704 return ((n & 0x3) << 18);
705}
706
707static __inline tilegx_bundle_bits
708create_ShiftOpcodeExtension_Y1(int num)
709{
710 const unsigned int n = (unsigned int)num;
711 return (((tilegx_bundle_bits)(n & 0x3)) << 49);
712}
713
714static __inline tilegx_bundle_bits
715create_SrcA_X0(int num)
716{
717 const unsigned int n = (unsigned int)num;
718 return ((n & 0x3f) << 6);
719}
720
721static __inline tilegx_bundle_bits
722create_SrcA_X1(int num)
723{
724 const unsigned int n = (unsigned int)num;
725 return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
726}
727
728static __inline tilegx_bundle_bits
729create_SrcA_Y0(int num)
730{
731 const unsigned int n = (unsigned int)num;
732 return ((n & 0x3f) << 6);
733}
734
735static __inline tilegx_bundle_bits
736create_SrcA_Y1(int num)
737{
738 const unsigned int n = (unsigned int)num;
739 return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
740}
741
742static __inline tilegx_bundle_bits
743create_SrcA_Y2(int num)
744{
745 const unsigned int n = (unsigned int)num;
746 return ((n & 0x3f) << 20);
747}
748
749static __inline tilegx_bundle_bits
750create_SrcBDest_Y2(int num)
751{
752 const unsigned int n = (unsigned int)num;
753 return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
754}
755
756static __inline tilegx_bundle_bits
757create_SrcB_X0(int num)
758{
759 const unsigned int n = (unsigned int)num;
760 return ((n & 0x3f) << 12);
761}
762
763static __inline tilegx_bundle_bits
764create_SrcB_X1(int num)
765{
766 const unsigned int n = (unsigned int)num;
767 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
768}
769
770static __inline tilegx_bundle_bits
771create_SrcB_Y0(int num)
772{
773 const unsigned int n = (unsigned int)num;
774 return ((n & 0x3f) << 12);
775}
776
777static __inline tilegx_bundle_bits
778create_SrcB_Y1(int num)
779{
780 const unsigned int n = (unsigned int)num;
781 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
782}
783
784static __inline tilegx_bundle_bits
785create_UnaryOpcodeExtension_X0(int num)
786{
787 const unsigned int n = (unsigned int)num;
788 return ((n & 0x3f) << 12);
789}
790
791static __inline tilegx_bundle_bits
792create_UnaryOpcodeExtension_X1(int num)
793{
794 const unsigned int n = (unsigned int)num;
795 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
796}
797
798static __inline tilegx_bundle_bits
799create_UnaryOpcodeExtension_Y0(int num)
800{
801 const unsigned int n = (unsigned int)num;
802 return ((n & 0x3f) << 12);
803}
804
805static __inline tilegx_bundle_bits
806create_UnaryOpcodeExtension_Y1(int num)
807{
808 const unsigned int n = (unsigned int)num;
809 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
810}
16 811
17 812
18#ifndef _TILE_OPCODE_CONSTANTS_H
19#define _TILE_OPCODE_CONSTANTS_H
20enum 813enum
21{ 814{
22 ADDI_IMM8_OPCODE_X0 = 1, 815 ADDI_IMM8_OPCODE_X0 = 1,
@@ -606,4 +1399,7 @@ enum
606 XOR_RRR_5_OPCODE_Y1 = 3 1399 XOR_RRR_5_OPCODE_Y1 = 3
607}; 1400};
608 1401
609#endif /* !_TILE_OPCODE_CONSTANTS_H */ 1402
1403#endif /* __ASSEMBLER__ */
1404
1405#endif /* __ARCH_OPCODE_H__ */
diff --git a/arch/tile/include/arch/opcode_tilepro.h b/arch/tile/include/arch/opcode_tilepro.h
new file mode 100644
index 000000000000..71b763b8ce83
--- /dev/null
+++ b/arch/tile/include/arch/opcode_tilepro.h
@@ -0,0 +1,1471 @@
1/* TILEPro opcode information.
2 *
3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 *
16 *
17 *
18 *
19 */
20
21#ifndef __ARCH_OPCODE_H__
22#define __ARCH_OPCODE_H__
23
24#ifndef __ASSEMBLER__
25
26typedef unsigned long long tilepro_bundle_bits;
27
28/* This is the bit that determines if a bundle is in the Y encoding. */
29#define TILEPRO_BUNDLE_Y_ENCODING_MASK ((tilepro_bundle_bits)1 << 63)
30
31enum
32{
33 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
34 TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
35
36 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
37 TILEPRO_NUM_PIPELINE_ENCODINGS = 5,
38
39 /* Log base 2 of TILEPRO_BUNDLE_SIZE_IN_BYTES. */
40 TILEPRO_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
41
42 /* Instructions take this many bytes. */
43 TILEPRO_BUNDLE_SIZE_IN_BYTES = 1 << TILEPRO_LOG2_BUNDLE_SIZE_IN_BYTES,
44
45 /* Log base 2 of TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES. */
46 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
47
48 /* Bundles should be aligned modulo this number of bytes. */
49 TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES =
50 (1 << TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
51
52 /* Log base 2 of TILEPRO_SN_INSTRUCTION_SIZE_IN_BYTES. */
53 TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
54
55 /* Static network instructions take this many bytes. */
56 TILEPRO_SN_INSTRUCTION_SIZE_IN_BYTES =
57 (1 << TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
58
59 /* Number of registers (some are magic, such as network I/O). */
60 TILEPRO_NUM_REGISTERS = 64,
61
62 /* Number of static network registers. */
63 TILEPRO_NUM_SN_REGISTERS = 4
64};
65
66/* Make a few "tile_" variables to simplify common code between
67 architectures. */
68
69typedef tilepro_bundle_bits tile_bundle_bits;
70#define TILE_BUNDLE_SIZE_IN_BYTES TILEPRO_BUNDLE_SIZE_IN_BYTES
71#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES
72#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
73 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
74
75/* 64-bit pattern for a { bpt ; nop } bundle. */
76#define TILEPRO_BPT_BUNDLE 0x400b3cae70166000ULL
77
78static __inline unsigned int
79get_BrOff_SN(tilepro_bundle_bits num)
80{
81 const unsigned int n = (unsigned int)num;
82 return (((n >> 0)) & 0x3ff);
83}
84
85static __inline unsigned int
86get_BrOff_X1(tilepro_bundle_bits n)
87{
88 return (((unsigned int)(n >> 43)) & 0x00007fff) |
89 (((unsigned int)(n >> 20)) & 0x00018000);
90}
91
92static __inline unsigned int
93get_BrType_X1(tilepro_bundle_bits n)
94{
95 return (((unsigned int)(n >> 31)) & 0xf);
96}
97
98static __inline unsigned int
99get_Dest_Imm8_X1(tilepro_bundle_bits n)
100{
101 return (((unsigned int)(n >> 31)) & 0x0000003f) |
102 (((unsigned int)(n >> 43)) & 0x000000c0);
103}
104
105static __inline unsigned int
106get_Dest_SN(tilepro_bundle_bits num)
107{
108 const unsigned int n = (unsigned int)num;
109 return (((n >> 2)) & 0x3);
110}
111
112static __inline unsigned int
113get_Dest_X0(tilepro_bundle_bits num)
114{
115 const unsigned int n = (unsigned int)num;
116 return (((n >> 0)) & 0x3f);
117}
118
119static __inline unsigned int
120get_Dest_X1(tilepro_bundle_bits n)
121{
122 return (((unsigned int)(n >> 31)) & 0x3f);
123}
124
125static __inline unsigned int
126get_Dest_Y0(tilepro_bundle_bits num)
127{
128 const unsigned int n = (unsigned int)num;
129 return (((n >> 0)) & 0x3f);
130}
131
132static __inline unsigned int
133get_Dest_Y1(tilepro_bundle_bits n)
134{
135 return (((unsigned int)(n >> 31)) & 0x3f);
136}
137
138static __inline unsigned int
139get_Imm16_X0(tilepro_bundle_bits num)
140{
141 const unsigned int n = (unsigned int)num;
142 return (((n >> 12)) & 0xffff);
143}
144
145static __inline unsigned int
146get_Imm16_X1(tilepro_bundle_bits n)
147{
148 return (((unsigned int)(n >> 43)) & 0xffff);
149}
150
151static __inline unsigned int
152get_Imm8_SN(tilepro_bundle_bits num)
153{
154 const unsigned int n = (unsigned int)num;
155 return (((n >> 0)) & 0xff);
156}
157
158static __inline unsigned int
159get_Imm8_X0(tilepro_bundle_bits num)
160{
161 const unsigned int n = (unsigned int)num;
162 return (((n >> 12)) & 0xff);
163}
164
165static __inline unsigned int
166get_Imm8_X1(tilepro_bundle_bits n)
167{
168 return (((unsigned int)(n >> 43)) & 0xff);
169}
170
171static __inline unsigned int
172get_Imm8_Y0(tilepro_bundle_bits num)
173{
174 const unsigned int n = (unsigned int)num;
175 return (((n >> 12)) & 0xff);
176}
177
178static __inline unsigned int
179get_Imm8_Y1(tilepro_bundle_bits n)
180{
181 return (((unsigned int)(n >> 43)) & 0xff);
182}
183
184static __inline unsigned int
185get_ImmOpcodeExtension_X0(tilepro_bundle_bits num)
186{
187 const unsigned int n = (unsigned int)num;
188 return (((n >> 20)) & 0x7f);
189}
190
191static __inline unsigned int
192get_ImmOpcodeExtension_X1(tilepro_bundle_bits n)
193{
194 return (((unsigned int)(n >> 51)) & 0x7f);
195}
196
197static __inline unsigned int
198get_ImmRROpcodeExtension_SN(tilepro_bundle_bits num)
199{
200 const unsigned int n = (unsigned int)num;
201 return (((n >> 8)) & 0x3);
202}
203
204static __inline unsigned int
205get_JOffLong_X1(tilepro_bundle_bits n)
206{
207 return (((unsigned int)(n >> 43)) & 0x00007fff) |
208 (((unsigned int)(n >> 20)) & 0x00018000) |
209 (((unsigned int)(n >> 14)) & 0x001e0000) |
210 (((unsigned int)(n >> 16)) & 0x07e00000) |
211 (((unsigned int)(n >> 31)) & 0x18000000);
212}
213
214static __inline unsigned int
215get_JOff_X1(tilepro_bundle_bits n)
216{
217 return (((unsigned int)(n >> 43)) & 0x00007fff) |
218 (((unsigned int)(n >> 20)) & 0x00018000) |
219 (((unsigned int)(n >> 14)) & 0x001e0000) |
220 (((unsigned int)(n >> 16)) & 0x07e00000) |
221 (((unsigned int)(n >> 31)) & 0x08000000);
222}
223
224static __inline unsigned int
225get_MF_Imm15_X1(tilepro_bundle_bits n)
226{
227 return (((unsigned int)(n >> 37)) & 0x00003fff) |
228 (((unsigned int)(n >> 44)) & 0x00004000);
229}
230
231static __inline unsigned int
232get_MMEnd_X0(tilepro_bundle_bits num)
233{
234 const unsigned int n = (unsigned int)num;
235 return (((n >> 18)) & 0x1f);
236}
237
238static __inline unsigned int
239get_MMEnd_X1(tilepro_bundle_bits n)
240{
241 return (((unsigned int)(n >> 49)) & 0x1f);
242}
243
244static __inline unsigned int
245get_MMStart_X0(tilepro_bundle_bits num)
246{
247 const unsigned int n = (unsigned int)num;
248 return (((n >> 23)) & 0x1f);
249}
250
251static __inline unsigned int
252get_MMStart_X1(tilepro_bundle_bits n)
253{
254 return (((unsigned int)(n >> 54)) & 0x1f);
255}
256
257static __inline unsigned int
258get_MT_Imm15_X1(tilepro_bundle_bits n)
259{
260 return (((unsigned int)(n >> 31)) & 0x0000003f) |
261 (((unsigned int)(n >> 37)) & 0x00003fc0) |
262 (((unsigned int)(n >> 44)) & 0x00004000);
263}
264
265static __inline unsigned int
266get_Mode(tilepro_bundle_bits n)
267{
268 return (((unsigned int)(n >> 63)) & 0x1);
269}
270
271static __inline unsigned int
272get_NoRegOpcodeExtension_SN(tilepro_bundle_bits num)
273{
274 const unsigned int n = (unsigned int)num;
275 return (((n >> 0)) & 0xf);
276}
277
278static __inline unsigned int
279get_Opcode_SN(tilepro_bundle_bits num)
280{
281 const unsigned int n = (unsigned int)num;
282 return (((n >> 10)) & 0x3f);
283}
284
285static __inline unsigned int
286get_Opcode_X0(tilepro_bundle_bits num)
287{
288 const unsigned int n = (unsigned int)num;
289 return (((n >> 28)) & 0x7);
290}
291
292static __inline unsigned int
293get_Opcode_X1(tilepro_bundle_bits n)
294{
295 return (((unsigned int)(n >> 59)) & 0xf);
296}
297
298static __inline unsigned int
299get_Opcode_Y0(tilepro_bundle_bits num)
300{
301 const unsigned int n = (unsigned int)num;
302 return (((n >> 27)) & 0xf);
303}
304
305static __inline unsigned int
306get_Opcode_Y1(tilepro_bundle_bits n)
307{
308 return (((unsigned int)(n >> 59)) & 0xf);
309}
310
311static __inline unsigned int
312get_Opcode_Y2(tilepro_bundle_bits n)
313{
314 return (((unsigned int)(n >> 56)) & 0x7);
315}
316
317static __inline unsigned int
318get_RROpcodeExtension_SN(tilepro_bundle_bits num)
319{
320 const unsigned int n = (unsigned int)num;
321 return (((n >> 4)) & 0xf);
322}
323
324static __inline unsigned int
325get_RRROpcodeExtension_X0(tilepro_bundle_bits num)
326{
327 const unsigned int n = (unsigned int)num;
328 return (((n >> 18)) & 0x1ff);
329}
330
331static __inline unsigned int
332get_RRROpcodeExtension_X1(tilepro_bundle_bits n)
333{
334 return (((unsigned int)(n >> 49)) & 0x1ff);
335}
336
337static __inline unsigned int
338get_RRROpcodeExtension_Y0(tilepro_bundle_bits num)
339{
340 const unsigned int n = (unsigned int)num;
341 return (((n >> 18)) & 0x3);
342}
343
344static __inline unsigned int
345get_RRROpcodeExtension_Y1(tilepro_bundle_bits n)
346{
347 return (((unsigned int)(n >> 49)) & 0x3);
348}
349
350static __inline unsigned int
351get_RouteOpcodeExtension_SN(tilepro_bundle_bits num)
352{
353 const unsigned int n = (unsigned int)num;
354 return (((n >> 0)) & 0x3ff);
355}
356
357static __inline unsigned int
358get_S_X0(tilepro_bundle_bits num)
359{
360 const unsigned int n = (unsigned int)num;
361 return (((n >> 27)) & 0x1);
362}
363
364static __inline unsigned int
365get_S_X1(tilepro_bundle_bits n)
366{
367 return (((unsigned int)(n >> 58)) & 0x1);
368}
369
370static __inline unsigned int
371get_ShAmt_X0(tilepro_bundle_bits num)
372{
373 const unsigned int n = (unsigned int)num;
374 return (((n >> 12)) & 0x1f);
375}
376
377static __inline unsigned int
378get_ShAmt_X1(tilepro_bundle_bits n)
379{
380 return (((unsigned int)(n >> 43)) & 0x1f);
381}
382
383static __inline unsigned int
384get_ShAmt_Y0(tilepro_bundle_bits num)
385{
386 const unsigned int n = (unsigned int)num;
387 return (((n >> 12)) & 0x1f);
388}
389
390static __inline unsigned int
391get_ShAmt_Y1(tilepro_bundle_bits n)
392{
393 return (((unsigned int)(n >> 43)) & 0x1f);
394}
395
396static __inline unsigned int
397get_SrcA_X0(tilepro_bundle_bits num)
398{
399 const unsigned int n = (unsigned int)num;
400 return (((n >> 6)) & 0x3f);
401}
402
403static __inline unsigned int
404get_SrcA_X1(tilepro_bundle_bits n)
405{
406 return (((unsigned int)(n >> 37)) & 0x3f);
407}
408
409static __inline unsigned int
410get_SrcA_Y0(tilepro_bundle_bits num)
411{
412 const unsigned int n = (unsigned int)num;
413 return (((n >> 6)) & 0x3f);
414}
415
416static __inline unsigned int
417get_SrcA_Y1(tilepro_bundle_bits n)
418{
419 return (((unsigned int)(n >> 37)) & 0x3f);
420}
421
422static __inline unsigned int
423get_SrcA_Y2(tilepro_bundle_bits n)
424{
425 return (((n >> 26)) & 0x00000001) |
426 (((unsigned int)(n >> 50)) & 0x0000003e);
427}
428
429static __inline unsigned int
430get_SrcBDest_Y2(tilepro_bundle_bits num)
431{
432 const unsigned int n = (unsigned int)num;
433 return (((n >> 20)) & 0x3f);
434}
435
436static __inline unsigned int
437get_SrcB_X0(tilepro_bundle_bits num)
438{
439 const unsigned int n = (unsigned int)num;
440 return (((n >> 12)) & 0x3f);
441}
442
443static __inline unsigned int
444get_SrcB_X1(tilepro_bundle_bits n)
445{
446 return (((unsigned int)(n >> 43)) & 0x3f);
447}
448
449static __inline unsigned int
450get_SrcB_Y0(tilepro_bundle_bits num)
451{
452 const unsigned int n = (unsigned int)num;
453 return (((n >> 12)) & 0x3f);
454}
455
456static __inline unsigned int
457get_SrcB_Y1(tilepro_bundle_bits n)
458{
459 return (((unsigned int)(n >> 43)) & 0x3f);
460}
461
462static __inline unsigned int
463get_Src_SN(tilepro_bundle_bits num)
464{
465 const unsigned int n = (unsigned int)num;
466 return (((n >> 0)) & 0x3);
467}
468
469static __inline unsigned int
470get_UnOpcodeExtension_X0(tilepro_bundle_bits num)
471{
472 const unsigned int n = (unsigned int)num;
473 return (((n >> 12)) & 0x1f);
474}
475
476static __inline unsigned int
477get_UnOpcodeExtension_X1(tilepro_bundle_bits n)
478{
479 return (((unsigned int)(n >> 43)) & 0x1f);
480}
481
482static __inline unsigned int
483get_UnOpcodeExtension_Y0(tilepro_bundle_bits num)
484{
485 const unsigned int n = (unsigned int)num;
486 return (((n >> 12)) & 0x1f);
487}
488
489static __inline unsigned int
490get_UnOpcodeExtension_Y1(tilepro_bundle_bits n)
491{
492 return (((unsigned int)(n >> 43)) & 0x1f);
493}
494
495static __inline unsigned int
496get_UnShOpcodeExtension_X0(tilepro_bundle_bits num)
497{
498 const unsigned int n = (unsigned int)num;
499 return (((n >> 17)) & 0x3ff);
500}
501
502static __inline unsigned int
503get_UnShOpcodeExtension_X1(tilepro_bundle_bits n)
504{
505 return (((unsigned int)(n >> 48)) & 0x3ff);
506}
507
508static __inline unsigned int
509get_UnShOpcodeExtension_Y0(tilepro_bundle_bits num)
510{
511 const unsigned int n = (unsigned int)num;
512 return (((n >> 17)) & 0x7);
513}
514
515static __inline unsigned int
516get_UnShOpcodeExtension_Y1(tilepro_bundle_bits n)
517{
518 return (((unsigned int)(n >> 48)) & 0x7);
519}
520
521
522static __inline int
523sign_extend(int n, int num_bits)
524{
525 int shift = (int)(sizeof(int) * 8 - num_bits);
526 return (n << shift) >> shift;
527}
528
529
530
531static __inline tilepro_bundle_bits
532create_BrOff_SN(int num)
533{
534 const unsigned int n = (unsigned int)num;
535 return ((n & 0x3ff) << 0);
536}
537
538static __inline tilepro_bundle_bits
539create_BrOff_X1(int num)
540{
541 const unsigned int n = (unsigned int)num;
542 return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
543 (((tilepro_bundle_bits)(n & 0x00018000)) << 20);
544}
545
546static __inline tilepro_bundle_bits
547create_BrType_X1(int num)
548{
549 const unsigned int n = (unsigned int)num;
550 return (((tilepro_bundle_bits)(n & 0xf)) << 31);
551}
552
553static __inline tilepro_bundle_bits
554create_Dest_Imm8_X1(int num)
555{
556 const unsigned int n = (unsigned int)num;
557 return (((tilepro_bundle_bits)(n & 0x0000003f)) << 31) |
558 (((tilepro_bundle_bits)(n & 0x000000c0)) << 43);
559}
560
561static __inline tilepro_bundle_bits
562create_Dest_SN(int num)
563{
564 const unsigned int n = (unsigned int)num;
565 return ((n & 0x3) << 2);
566}
567
568static __inline tilepro_bundle_bits
569create_Dest_X0(int num)
570{
571 const unsigned int n = (unsigned int)num;
572 return ((n & 0x3f) << 0);
573}
574
575static __inline tilepro_bundle_bits
576create_Dest_X1(int num)
577{
578 const unsigned int n = (unsigned int)num;
579 return (((tilepro_bundle_bits)(n & 0x3f)) << 31);
580}
581
582static __inline tilepro_bundle_bits
583create_Dest_Y0(int num)
584{
585 const unsigned int n = (unsigned int)num;
586 return ((n & 0x3f) << 0);
587}
588
589static __inline tilepro_bundle_bits
590create_Dest_Y1(int num)
591{
592 const unsigned int n = (unsigned int)num;
593 return (((tilepro_bundle_bits)(n & 0x3f)) << 31);
594}
595
596static __inline tilepro_bundle_bits
597create_Imm16_X0(int num)
598{
599 const unsigned int n = (unsigned int)num;
600 return ((n & 0xffff) << 12);
601}
602
603static __inline tilepro_bundle_bits
604create_Imm16_X1(int num)
605{
606 const unsigned int n = (unsigned int)num;
607 return (((tilepro_bundle_bits)(n & 0xffff)) << 43);
608}
609
610static __inline tilepro_bundle_bits
611create_Imm8_SN(int num)
612{
613 const unsigned int n = (unsigned int)num;
614 return ((n & 0xff) << 0);
615}
616
617static __inline tilepro_bundle_bits
618create_Imm8_X0(int num)
619{
620 const unsigned int n = (unsigned int)num;
621 return ((n & 0xff) << 12);
622}
623
624static __inline tilepro_bundle_bits
625create_Imm8_X1(int num)
626{
627 const unsigned int n = (unsigned int)num;
628 return (((tilepro_bundle_bits)(n & 0xff)) << 43);
629}
630
631static __inline tilepro_bundle_bits
632create_Imm8_Y0(int num)
633{
634 const unsigned int n = (unsigned int)num;
635 return ((n & 0xff) << 12);
636}
637
638static __inline tilepro_bundle_bits
639create_Imm8_Y1(int num)
640{
641 const unsigned int n = (unsigned int)num;
642 return (((tilepro_bundle_bits)(n & 0xff)) << 43);
643}
644
645static __inline tilepro_bundle_bits
646create_ImmOpcodeExtension_X0(int num)
647{
648 const unsigned int n = (unsigned int)num;
649 return ((n & 0x7f) << 20);
650}
651
652static __inline tilepro_bundle_bits
653create_ImmOpcodeExtension_X1(int num)
654{
655 const unsigned int n = (unsigned int)num;
656 return (((tilepro_bundle_bits)(n & 0x7f)) << 51);
657}
658
659static __inline tilepro_bundle_bits
660create_ImmRROpcodeExtension_SN(int num)
661{
662 const unsigned int n = (unsigned int)num;
663 return ((n & 0x3) << 8);
664}
665
666static __inline tilepro_bundle_bits
667create_JOffLong_X1(int num)
668{
669 const unsigned int n = (unsigned int)num;
670 return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
671 (((tilepro_bundle_bits)(n & 0x00018000)) << 20) |
672 (((tilepro_bundle_bits)(n & 0x001e0000)) << 14) |
673 (((tilepro_bundle_bits)(n & 0x07e00000)) << 16) |
674 (((tilepro_bundle_bits)(n & 0x18000000)) << 31);
675}
676
677static __inline tilepro_bundle_bits
678create_JOff_X1(int num)
679{
680 const unsigned int n = (unsigned int)num;
681 return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
682 (((tilepro_bundle_bits)(n & 0x00018000)) << 20) |
683 (((tilepro_bundle_bits)(n & 0x001e0000)) << 14) |
684 (((tilepro_bundle_bits)(n & 0x07e00000)) << 16) |
685 (((tilepro_bundle_bits)(n & 0x08000000)) << 31);
686}
687
688static __inline tilepro_bundle_bits
689create_MF_Imm15_X1(int num)
690{
691 const unsigned int n = (unsigned int)num;
692 return (((tilepro_bundle_bits)(n & 0x00003fff)) << 37) |
693 (((tilepro_bundle_bits)(n & 0x00004000)) << 44);
694}
695
696static __inline tilepro_bundle_bits
697create_MMEnd_X0(int num)
698{
699 const unsigned int n = (unsigned int)num;
700 return ((n & 0x1f) << 18);
701}
702
703static __inline tilepro_bundle_bits
704create_MMEnd_X1(int num)
705{
706 const unsigned int n = (unsigned int)num;
707 return (((tilepro_bundle_bits)(n & 0x1f)) << 49);
708}
709
710static __inline tilepro_bundle_bits
711create_MMStart_X0(int num)
712{
713 const unsigned int n = (unsigned int)num;
714 return ((n & 0x1f) << 23);
715}
716
717static __inline tilepro_bundle_bits
718create_MMStart_X1(int num)
719{
720 const unsigned int n = (unsigned int)num;
721 return (((tilepro_bundle_bits)(n & 0x1f)) << 54);
722}
723
724static __inline tilepro_bundle_bits
725create_MT_Imm15_X1(int num)
726{
727 const unsigned int n = (unsigned int)num;
728 return (((tilepro_bundle_bits)(n & 0x0000003f)) << 31) |
729 (((tilepro_bundle_bits)(n & 0x00003fc0)) << 37) |
730 (((tilepro_bundle_bits)(n & 0x00004000)) << 44);
731}
732
733static __inline tilepro_bundle_bits
734create_Mode(int num)
735{
736 const unsigned int n = (unsigned int)num;
737 return (((tilepro_bundle_bits)(n & 0x1)) << 63);
738}
739
740static __inline tilepro_bundle_bits
741create_NoRegOpcodeExtension_SN(int num)
742{
743 const unsigned int n = (unsigned int)num;
744 return ((n & 0xf) << 0);
745}
746
747static __inline tilepro_bundle_bits
748create_Opcode_SN(int num)
749{
750 const unsigned int n = (unsigned int)num;
751 return ((n & 0x3f) << 10);
752}
753
754static __inline tilepro_bundle_bits
755create_Opcode_X0(int num)
756{
757 const unsigned int n = (unsigned int)num;
758 return ((n & 0x7) << 28);
759}
760
761static __inline tilepro_bundle_bits
762create_Opcode_X1(int num)
763{
764 const unsigned int n = (unsigned int)num;
765 return (((tilepro_bundle_bits)(n & 0xf)) << 59);
766}
767
768static __inline tilepro_bundle_bits
769create_Opcode_Y0(int num)
770{
771 const unsigned int n = (unsigned int)num;
772 return ((n & 0xf) << 27);
773}
774
775static __inline tilepro_bundle_bits
776create_Opcode_Y1(int num)
777{
778 const unsigned int n = (unsigned int)num;
779 return (((tilepro_bundle_bits)(n & 0xf)) << 59);
780}
781
782static __inline tilepro_bundle_bits
783create_Opcode_Y2(int num)
784{
785 const unsigned int n = (unsigned int)num;
786 return (((tilepro_bundle_bits)(n & 0x7)) << 56);
787}
788
789static __inline tilepro_bundle_bits
790create_RROpcodeExtension_SN(int num)
791{
792 const unsigned int n = (unsigned int)num;
793 return ((n & 0xf) << 4);
794}
795
796static __inline tilepro_bundle_bits
797create_RRROpcodeExtension_X0(int num)
798{
799 const unsigned int n = (unsigned int)num;
800 return ((n & 0x1ff) << 18);
801}
802
803static __inline tilepro_bundle_bits
804create_RRROpcodeExtension_X1(int num)
805{
806 const unsigned int n = (unsigned int)num;
807 return (((tilepro_bundle_bits)(n & 0x1ff)) << 49);
808}
809
810static __inline tilepro_bundle_bits
811create_RRROpcodeExtension_Y0(int num)
812{
813 const unsigned int n = (unsigned int)num;
814 return ((n & 0x3) << 18);
815}
816
817static __inline tilepro_bundle_bits
818create_RRROpcodeExtension_Y1(int num)
819{
820 const unsigned int n = (unsigned int)num;
821 return (((tilepro_bundle_bits)(n & 0x3)) << 49);
822}
823
824static __inline tilepro_bundle_bits
825create_RouteOpcodeExtension_SN(int num)
826{
827 const unsigned int n = (unsigned int)num;
828 return ((n & 0x3ff) << 0);
829}
830
831static __inline tilepro_bundle_bits
832create_S_X0(int num)
833{
834 const unsigned int n = (unsigned int)num;
835 return ((n & 0x1) << 27);
836}
837
838static __inline tilepro_bundle_bits
839create_S_X1(int num)
840{
841 const unsigned int n = (unsigned int)num;
842 return (((tilepro_bundle_bits)(n & 0x1)) << 58);
843}
844
845static __inline tilepro_bundle_bits
846create_ShAmt_X0(int num)
847{
848 const unsigned int n = (unsigned int)num;
849 return ((n & 0x1f) << 12);
850}
851
852static __inline tilepro_bundle_bits
853create_ShAmt_X1(int num)
854{
855 const unsigned int n = (unsigned int)num;
856 return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
857}
858
859static __inline tilepro_bundle_bits
860create_ShAmt_Y0(int num)
861{
862 const unsigned int n = (unsigned int)num;
863 return ((n & 0x1f) << 12);
864}
865
866static __inline tilepro_bundle_bits
867create_ShAmt_Y1(int num)
868{
869 const unsigned int n = (unsigned int)num;
870 return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
871}
872
873static __inline tilepro_bundle_bits
874create_SrcA_X0(int num)
875{
876 const unsigned int n = (unsigned int)num;
877 return ((n & 0x3f) << 6);
878}
879
880static __inline tilepro_bundle_bits
881create_SrcA_X1(int num)
882{
883 const unsigned int n = (unsigned int)num;
884 return (((tilepro_bundle_bits)(n & 0x3f)) << 37);
885}
886
887static __inline tilepro_bundle_bits
888create_SrcA_Y0(int num)
889{
890 const unsigned int n = (unsigned int)num;
891 return ((n & 0x3f) << 6);
892}
893
894static __inline tilepro_bundle_bits
895create_SrcA_Y1(int num)
896{
897 const unsigned int n = (unsigned int)num;
898 return (((tilepro_bundle_bits)(n & 0x3f)) << 37);
899}
900
901static __inline tilepro_bundle_bits
902create_SrcA_Y2(int num)
903{
904 const unsigned int n = (unsigned int)num;
905 return ((n & 0x00000001) << 26) |
906 (((tilepro_bundle_bits)(n & 0x0000003e)) << 50);
907}
908
909static __inline tilepro_bundle_bits
910create_SrcBDest_Y2(int num)
911{
912 const unsigned int n = (unsigned int)num;
913 return ((n & 0x3f) << 20);
914}
915
916static __inline tilepro_bundle_bits
917create_SrcB_X0(int num)
918{
919 const unsigned int n = (unsigned int)num;
920 return ((n & 0x3f) << 12);
921}
922
923static __inline tilepro_bundle_bits
924create_SrcB_X1(int num)
925{
926 const unsigned int n = (unsigned int)num;
927 return (((tilepro_bundle_bits)(n & 0x3f)) << 43);
928}
929
930static __inline tilepro_bundle_bits
931create_SrcB_Y0(int num)
932{
933 const unsigned int n = (unsigned int)num;
934 return ((n & 0x3f) << 12);
935}
936
937static __inline tilepro_bundle_bits
938create_SrcB_Y1(int num)
939{
940 const unsigned int n = (unsigned int)num;
941 return (((tilepro_bundle_bits)(n & 0x3f)) << 43);
942}
943
944static __inline tilepro_bundle_bits
945create_Src_SN(int num)
946{
947 const unsigned int n = (unsigned int)num;
948 return ((n & 0x3) << 0);
949}
950
951static __inline tilepro_bundle_bits
952create_UnOpcodeExtension_X0(int num)
953{
954 const unsigned int n = (unsigned int)num;
955 return ((n & 0x1f) << 12);
956}
957
958static __inline tilepro_bundle_bits
959create_UnOpcodeExtension_X1(int num)
960{
961 const unsigned int n = (unsigned int)num;
962 return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
963}
964
965static __inline tilepro_bundle_bits
966create_UnOpcodeExtension_Y0(int num)
967{
968 const unsigned int n = (unsigned int)num;
969 return ((n & 0x1f) << 12);
970}
971
972static __inline tilepro_bundle_bits
973create_UnOpcodeExtension_Y1(int num)
974{
975 const unsigned int n = (unsigned int)num;
976 return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
977}
978
979static __inline tilepro_bundle_bits
980create_UnShOpcodeExtension_X0(int num)
981{
982 const unsigned int n = (unsigned int)num;
983 return ((n & 0x3ff) << 17);
984}
985
986static __inline tilepro_bundle_bits
987create_UnShOpcodeExtension_X1(int num)
988{
989 const unsigned int n = (unsigned int)num;
990 return (((tilepro_bundle_bits)(n & 0x3ff)) << 48);
991}
992
993static __inline tilepro_bundle_bits
994create_UnShOpcodeExtension_Y0(int num)
995{
996 const unsigned int n = (unsigned int)num;
997 return ((n & 0x7) << 17);
998}
999
1000static __inline tilepro_bundle_bits
1001create_UnShOpcodeExtension_Y1(int num)
1002{
1003 const unsigned int n = (unsigned int)num;
1004 return (((tilepro_bundle_bits)(n & 0x7)) << 48);
1005}
1006
1007
1008enum
1009{
1010 ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
1011 ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
1012 ADDB_SPECIAL_0_OPCODE_X0 = 1,
1013 ADDB_SPECIAL_0_OPCODE_X1 = 1,
1014 ADDHS_SPECIAL_0_OPCODE_X0 = 99,
1015 ADDHS_SPECIAL_0_OPCODE_X1 = 69,
1016 ADDH_SPECIAL_0_OPCODE_X0 = 2,
1017 ADDH_SPECIAL_0_OPCODE_X1 = 2,
1018 ADDIB_IMM_0_OPCODE_X0 = 1,
1019 ADDIB_IMM_0_OPCODE_X1 = 1,
1020 ADDIH_IMM_0_OPCODE_X0 = 2,
1021 ADDIH_IMM_0_OPCODE_X1 = 2,
1022 ADDI_IMM_0_OPCODE_X0 = 3,
1023 ADDI_IMM_0_OPCODE_X1 = 3,
1024 ADDI_IMM_1_OPCODE_SN = 1,
1025 ADDI_OPCODE_Y0 = 9,
1026 ADDI_OPCODE_Y1 = 7,
1027 ADDLIS_OPCODE_X0 = 1,
1028 ADDLIS_OPCODE_X1 = 2,
1029 ADDLI_OPCODE_X0 = 2,
1030 ADDLI_OPCODE_X1 = 3,
1031 ADDS_SPECIAL_0_OPCODE_X0 = 96,
1032 ADDS_SPECIAL_0_OPCODE_X1 = 66,
1033 ADD_SPECIAL_0_OPCODE_X0 = 3,
1034 ADD_SPECIAL_0_OPCODE_X1 = 3,
1035 ADD_SPECIAL_0_OPCODE_Y0 = 0,
1036 ADD_SPECIAL_0_OPCODE_Y1 = 0,
1037 ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
1038 ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
1039 ANDI_IMM_0_OPCODE_X0 = 1,
1040 ANDI_IMM_0_OPCODE_X1 = 4,
1041 ANDI_OPCODE_Y0 = 10,
1042 ANDI_OPCODE_Y1 = 8,
1043 AND_SPECIAL_0_OPCODE_X0 = 6,
1044 AND_SPECIAL_0_OPCODE_X1 = 4,
1045 AND_SPECIAL_2_OPCODE_Y0 = 0,
1046 AND_SPECIAL_2_OPCODE_Y1 = 0,
1047 AULI_OPCODE_X0 = 3,
1048 AULI_OPCODE_X1 = 4,
1049 AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
1050 AVGH_SPECIAL_0_OPCODE_X0 = 8,
1051 BBNST_BRANCH_OPCODE_X1 = 15,
1052 BBNS_BRANCH_OPCODE_X1 = 14,
1053 BBNS_OPCODE_SN = 63,
1054 BBST_BRANCH_OPCODE_X1 = 13,
1055 BBS_BRANCH_OPCODE_X1 = 12,
1056 BBS_OPCODE_SN = 62,
1057 BGEZT_BRANCH_OPCODE_X1 = 7,
1058 BGEZ_BRANCH_OPCODE_X1 = 6,
1059 BGEZ_OPCODE_SN = 61,
1060 BGZT_BRANCH_OPCODE_X1 = 5,
1061 BGZ_BRANCH_OPCODE_X1 = 4,
1062 BGZ_OPCODE_SN = 58,
1063 BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
1064 BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
1065 BLEZT_BRANCH_OPCODE_X1 = 11,
1066 BLEZ_BRANCH_OPCODE_X1 = 10,
1067 BLEZ_OPCODE_SN = 59,
1068 BLZT_BRANCH_OPCODE_X1 = 9,
1069 BLZ_BRANCH_OPCODE_X1 = 8,
1070 BLZ_OPCODE_SN = 60,
1071 BNZT_BRANCH_OPCODE_X1 = 3,
1072 BNZ_BRANCH_OPCODE_X1 = 2,
1073 BNZ_OPCODE_SN = 57,
1074 BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
1075 BRANCH_OPCODE_X1 = 5,
1076 BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
1077 BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
1078 BZT_BRANCH_OPCODE_X1 = 1,
1079 BZ_BRANCH_OPCODE_X1 = 0,
1080 BZ_OPCODE_SN = 56,
1081 CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
1082 CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
1083 CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
1084 CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
1085 CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
1086 CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
1087 DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
1088 DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
1089 DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
1090 FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
1091 FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
1092 FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
1093 FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
1094 FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
1095 FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
1096 FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
1097 HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
1098 ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
1099 ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
1100 ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
1101 IMM_0_OPCODE_SN = 0,
1102 IMM_0_OPCODE_X0 = 4,
1103 IMM_0_OPCODE_X1 = 6,
1104 IMM_1_OPCODE_SN = 1,
1105 IMM_OPCODE_0_X0 = 5,
1106 INTHB_SPECIAL_0_OPCODE_X0 = 11,
1107 INTHB_SPECIAL_0_OPCODE_X1 = 5,
1108 INTHH_SPECIAL_0_OPCODE_X0 = 12,
1109 INTHH_SPECIAL_0_OPCODE_X1 = 6,
1110 INTLB_SPECIAL_0_OPCODE_X0 = 13,
1111 INTLB_SPECIAL_0_OPCODE_X1 = 7,
1112 INTLH_SPECIAL_0_OPCODE_X0 = 14,
1113 INTLH_SPECIAL_0_OPCODE_X1 = 8,
1114 INV_UN_0_SHUN_0_OPCODE_X1 = 8,
1115 IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
1116 JALB_OPCODE_X1 = 13,
1117 JALF_OPCODE_X1 = 12,
1118 JALRP_SPECIAL_0_OPCODE_X1 = 9,
1119 JALRR_IMM_1_OPCODE_SN = 3,
1120 JALR_RR_IMM_0_OPCODE_SN = 5,
1121 JALR_SPECIAL_0_OPCODE_X1 = 10,
1122 JB_OPCODE_X1 = 11,
1123 JF_OPCODE_X1 = 10,
1124 JRP_SPECIAL_0_OPCODE_X1 = 11,
1125 JRR_IMM_1_OPCODE_SN = 2,
1126 JR_RR_IMM_0_OPCODE_SN = 4,
1127 JR_SPECIAL_0_OPCODE_X1 = 12,
1128 LBADD_IMM_0_OPCODE_X1 = 22,
1129 LBADD_U_IMM_0_OPCODE_X1 = 23,
1130 LB_OPCODE_Y2 = 0,
1131 LB_UN_0_SHUN_0_OPCODE_X1 = 10,
1132 LB_U_OPCODE_Y2 = 1,
1133 LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
1134 LHADD_IMM_0_OPCODE_X1 = 24,
1135 LHADD_U_IMM_0_OPCODE_X1 = 25,
1136 LH_OPCODE_Y2 = 2,
1137 LH_UN_0_SHUN_0_OPCODE_X1 = 12,
1138 LH_U_OPCODE_Y2 = 3,
1139 LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
1140 LNK_SPECIAL_0_OPCODE_X1 = 13,
1141 LWADD_IMM_0_OPCODE_X1 = 26,
1142 LWADD_NA_IMM_0_OPCODE_X1 = 27,
1143 LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
1144 LW_OPCODE_Y2 = 4,
1145 LW_UN_0_SHUN_0_OPCODE_X1 = 14,
1146 MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
1147 MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
1148 MAXH_SPECIAL_0_OPCODE_X0 = 16,
1149 MAXH_SPECIAL_0_OPCODE_X1 = 15,
1150 MAXIB_U_IMM_0_OPCODE_X0 = 4,
1151 MAXIB_U_IMM_0_OPCODE_X1 = 5,
1152 MAXIH_IMM_0_OPCODE_X0 = 5,
1153 MAXIH_IMM_0_OPCODE_X1 = 6,
1154 MFSPR_IMM_0_OPCODE_X1 = 7,
1155 MF_UN_0_SHUN_0_OPCODE_X1 = 15,
1156 MINB_U_SPECIAL_0_OPCODE_X0 = 17,
1157 MINB_U_SPECIAL_0_OPCODE_X1 = 16,
1158 MINH_SPECIAL_0_OPCODE_X0 = 18,
1159 MINH_SPECIAL_0_OPCODE_X1 = 17,
1160 MINIB_U_IMM_0_OPCODE_X0 = 6,
1161 MINIB_U_IMM_0_OPCODE_X1 = 8,
1162 MINIH_IMM_0_OPCODE_X0 = 7,
1163 MINIH_IMM_0_OPCODE_X1 = 9,
1164 MM_OPCODE_X0 = 6,
1165 MM_OPCODE_X1 = 7,
1166 MNZB_SPECIAL_0_OPCODE_X0 = 19,
1167 MNZB_SPECIAL_0_OPCODE_X1 = 18,
1168 MNZH_SPECIAL_0_OPCODE_X0 = 20,
1169 MNZH_SPECIAL_0_OPCODE_X1 = 19,
1170 MNZ_SPECIAL_0_OPCODE_X0 = 21,
1171 MNZ_SPECIAL_0_OPCODE_X1 = 20,
1172 MNZ_SPECIAL_1_OPCODE_Y0 = 0,
1173 MNZ_SPECIAL_1_OPCODE_Y1 = 1,
1174 MOVEI_IMM_1_OPCODE_SN = 0,
1175 MOVE_RR_IMM_0_OPCODE_SN = 8,
1176 MTSPR_IMM_0_OPCODE_X1 = 10,
1177 MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
1178 MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
1179 MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
1180 MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
1181 MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
1182 MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
1183 MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
1184 MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
1185 MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
1186 MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
1187 MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
1188 MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
1189 MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
1190 MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
1191 MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
1192 MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
1193 MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
1194 MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
1195 MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
1196 MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
1197 MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
1198 MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
1199 MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
1200 MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
1201 MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
1202 MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
1203 MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
1204 MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
1205 MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
1206 MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
1207 MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
1208 MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
1209 MVNZ_SPECIAL_0_OPCODE_X0 = 45,
1210 MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
1211 MVZ_SPECIAL_0_OPCODE_X0 = 46,
1212 MVZ_SPECIAL_1_OPCODE_Y0 = 2,
1213 MZB_SPECIAL_0_OPCODE_X0 = 47,
1214 MZB_SPECIAL_0_OPCODE_X1 = 21,
1215 MZH_SPECIAL_0_OPCODE_X0 = 48,
1216 MZH_SPECIAL_0_OPCODE_X1 = 22,
1217 MZ_SPECIAL_0_OPCODE_X0 = 49,
1218 MZ_SPECIAL_0_OPCODE_X1 = 23,
1219 MZ_SPECIAL_1_OPCODE_Y0 = 3,
1220 MZ_SPECIAL_1_OPCODE_Y1 = 2,
1221 NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
1222 NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
1223 NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
1224 NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
1225 NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
1226 NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
1227 NOREG_RR_IMM_0_OPCODE_SN = 0,
1228 NOR_SPECIAL_0_OPCODE_X0 = 50,
1229 NOR_SPECIAL_0_OPCODE_X1 = 24,
1230 NOR_SPECIAL_2_OPCODE_Y0 = 1,
1231 NOR_SPECIAL_2_OPCODE_Y1 = 1,
1232 ORI_IMM_0_OPCODE_X0 = 8,
1233 ORI_IMM_0_OPCODE_X1 = 11,
1234 ORI_OPCODE_Y0 = 11,
1235 ORI_OPCODE_Y1 = 9,
1236 OR_SPECIAL_0_OPCODE_X0 = 51,
1237 OR_SPECIAL_0_OPCODE_X1 = 25,
1238 OR_SPECIAL_2_OPCODE_Y0 = 2,
1239 OR_SPECIAL_2_OPCODE_Y1 = 2,
1240 PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
1241 PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
1242 PACKHB_SPECIAL_0_OPCODE_X0 = 52,
1243 PACKHB_SPECIAL_0_OPCODE_X1 = 26,
1244 PACKHS_SPECIAL_0_OPCODE_X0 = 102,
1245 PACKHS_SPECIAL_0_OPCODE_X1 = 72,
1246 PACKLB_SPECIAL_0_OPCODE_X0 = 53,
1247 PACKLB_SPECIAL_0_OPCODE_X1 = 27,
1248 PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
1249 PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
1250 RLI_SHUN_0_OPCODE_X0 = 1,
1251 RLI_SHUN_0_OPCODE_X1 = 1,
1252 RLI_SHUN_0_OPCODE_Y0 = 1,
1253 RLI_SHUN_0_OPCODE_Y1 = 1,
1254 RL_SPECIAL_0_OPCODE_X0 = 54,
1255 RL_SPECIAL_0_OPCODE_X1 = 28,
1256 RL_SPECIAL_3_OPCODE_Y0 = 0,
1257 RL_SPECIAL_3_OPCODE_Y1 = 0,
1258 RR_IMM_0_OPCODE_SN = 0,
1259 S1A_SPECIAL_0_OPCODE_X0 = 55,
1260 S1A_SPECIAL_0_OPCODE_X1 = 29,
1261 S1A_SPECIAL_0_OPCODE_Y0 = 1,
1262 S1A_SPECIAL_0_OPCODE_Y1 = 1,
1263 S2A_SPECIAL_0_OPCODE_X0 = 56,
1264 S2A_SPECIAL_0_OPCODE_X1 = 30,
1265 S2A_SPECIAL_0_OPCODE_Y0 = 2,
1266 S2A_SPECIAL_0_OPCODE_Y1 = 2,
1267 S3A_SPECIAL_0_OPCODE_X0 = 57,
1268 S3A_SPECIAL_0_OPCODE_X1 = 31,
1269 S3A_SPECIAL_5_OPCODE_Y0 = 1,
1270 S3A_SPECIAL_5_OPCODE_Y1 = 1,
1271 SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
1272 SADAH_SPECIAL_0_OPCODE_X0 = 59,
1273 SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
1274 SADB_U_SPECIAL_0_OPCODE_X0 = 61,
1275 SADH_SPECIAL_0_OPCODE_X0 = 62,
1276 SADH_U_SPECIAL_0_OPCODE_X0 = 63,
1277 SBADD_IMM_0_OPCODE_X1 = 28,
1278 SB_OPCODE_Y2 = 5,
1279 SB_SPECIAL_0_OPCODE_X1 = 32,
1280 SEQB_SPECIAL_0_OPCODE_X0 = 64,
1281 SEQB_SPECIAL_0_OPCODE_X1 = 33,
1282 SEQH_SPECIAL_0_OPCODE_X0 = 65,
1283 SEQH_SPECIAL_0_OPCODE_X1 = 34,
1284 SEQIB_IMM_0_OPCODE_X0 = 9,
1285 SEQIB_IMM_0_OPCODE_X1 = 12,
1286 SEQIH_IMM_0_OPCODE_X0 = 10,
1287 SEQIH_IMM_0_OPCODE_X1 = 13,
1288 SEQI_IMM_0_OPCODE_X0 = 11,
1289 SEQI_IMM_0_OPCODE_X1 = 14,
1290 SEQI_OPCODE_Y0 = 12,
1291 SEQI_OPCODE_Y1 = 10,
1292 SEQ_SPECIAL_0_OPCODE_X0 = 66,
1293 SEQ_SPECIAL_0_OPCODE_X1 = 35,
1294 SEQ_SPECIAL_5_OPCODE_Y0 = 2,
1295 SEQ_SPECIAL_5_OPCODE_Y1 = 2,
1296 SHADD_IMM_0_OPCODE_X1 = 29,
1297 SHL8II_IMM_0_OPCODE_SN = 3,
1298 SHLB_SPECIAL_0_OPCODE_X0 = 67,
1299 SHLB_SPECIAL_0_OPCODE_X1 = 36,
1300 SHLH_SPECIAL_0_OPCODE_X0 = 68,
1301 SHLH_SPECIAL_0_OPCODE_X1 = 37,
1302 SHLIB_SHUN_0_OPCODE_X0 = 2,
1303 SHLIB_SHUN_0_OPCODE_X1 = 2,
1304 SHLIH_SHUN_0_OPCODE_X0 = 3,
1305 SHLIH_SHUN_0_OPCODE_X1 = 3,
1306 SHLI_SHUN_0_OPCODE_X0 = 4,
1307 SHLI_SHUN_0_OPCODE_X1 = 4,
1308 SHLI_SHUN_0_OPCODE_Y0 = 2,
1309 SHLI_SHUN_0_OPCODE_Y1 = 2,
1310 SHL_SPECIAL_0_OPCODE_X0 = 69,
1311 SHL_SPECIAL_0_OPCODE_X1 = 38,
1312 SHL_SPECIAL_3_OPCODE_Y0 = 1,
1313 SHL_SPECIAL_3_OPCODE_Y1 = 1,
1314 SHR1_RR_IMM_0_OPCODE_SN = 9,
1315 SHRB_SPECIAL_0_OPCODE_X0 = 70,
1316 SHRB_SPECIAL_0_OPCODE_X1 = 39,
1317 SHRH_SPECIAL_0_OPCODE_X0 = 71,
1318 SHRH_SPECIAL_0_OPCODE_X1 = 40,
1319 SHRIB_SHUN_0_OPCODE_X0 = 5,
1320 SHRIB_SHUN_0_OPCODE_X1 = 5,
1321 SHRIH_SHUN_0_OPCODE_X0 = 6,
1322 SHRIH_SHUN_0_OPCODE_X1 = 6,
1323 SHRI_SHUN_0_OPCODE_X0 = 7,
1324 SHRI_SHUN_0_OPCODE_X1 = 7,
1325 SHRI_SHUN_0_OPCODE_Y0 = 3,
1326 SHRI_SHUN_0_OPCODE_Y1 = 3,
1327 SHR_SPECIAL_0_OPCODE_X0 = 72,
1328 SHR_SPECIAL_0_OPCODE_X1 = 41,
1329 SHR_SPECIAL_3_OPCODE_Y0 = 2,
1330 SHR_SPECIAL_3_OPCODE_Y1 = 2,
1331 SHUN_0_OPCODE_X0 = 7,
1332 SHUN_0_OPCODE_X1 = 8,
1333 SHUN_0_OPCODE_Y0 = 13,
1334 SHUN_0_OPCODE_Y1 = 11,
1335 SH_OPCODE_Y2 = 6,
1336 SH_SPECIAL_0_OPCODE_X1 = 42,
1337 SLTB_SPECIAL_0_OPCODE_X0 = 73,
1338 SLTB_SPECIAL_0_OPCODE_X1 = 43,
1339 SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
1340 SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
1341 SLTEB_SPECIAL_0_OPCODE_X0 = 75,
1342 SLTEB_SPECIAL_0_OPCODE_X1 = 45,
1343 SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
1344 SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
1345 SLTEH_SPECIAL_0_OPCODE_X0 = 77,
1346 SLTEH_SPECIAL_0_OPCODE_X1 = 47,
1347 SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
1348 SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
1349 SLTE_SPECIAL_0_OPCODE_X0 = 79,
1350 SLTE_SPECIAL_0_OPCODE_X1 = 49,
1351 SLTE_SPECIAL_4_OPCODE_Y0 = 0,
1352 SLTE_SPECIAL_4_OPCODE_Y1 = 0,
1353 SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
1354 SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
1355 SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
1356 SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
1357 SLTH_SPECIAL_0_OPCODE_X0 = 81,
1358 SLTH_SPECIAL_0_OPCODE_X1 = 51,
1359 SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
1360 SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
1361 SLTIB_IMM_0_OPCODE_X0 = 12,
1362 SLTIB_IMM_0_OPCODE_X1 = 15,
1363 SLTIB_U_IMM_0_OPCODE_X0 = 13,
1364 SLTIB_U_IMM_0_OPCODE_X1 = 16,
1365 SLTIH_IMM_0_OPCODE_X0 = 14,
1366 SLTIH_IMM_0_OPCODE_X1 = 17,
1367 SLTIH_U_IMM_0_OPCODE_X0 = 15,
1368 SLTIH_U_IMM_0_OPCODE_X1 = 18,
1369 SLTI_IMM_0_OPCODE_X0 = 16,
1370 SLTI_IMM_0_OPCODE_X1 = 19,
1371 SLTI_OPCODE_Y0 = 14,
1372 SLTI_OPCODE_Y1 = 12,
1373 SLTI_U_IMM_0_OPCODE_X0 = 17,
1374 SLTI_U_IMM_0_OPCODE_X1 = 20,
1375 SLTI_U_OPCODE_Y0 = 15,
1376 SLTI_U_OPCODE_Y1 = 13,
1377 SLT_SPECIAL_0_OPCODE_X0 = 83,
1378 SLT_SPECIAL_0_OPCODE_X1 = 53,
1379 SLT_SPECIAL_4_OPCODE_Y0 = 2,
1380 SLT_SPECIAL_4_OPCODE_Y1 = 2,
1381 SLT_U_SPECIAL_0_OPCODE_X0 = 84,
1382 SLT_U_SPECIAL_0_OPCODE_X1 = 54,
1383 SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
1384 SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
1385 SNEB_SPECIAL_0_OPCODE_X0 = 85,
1386 SNEB_SPECIAL_0_OPCODE_X1 = 55,
1387 SNEH_SPECIAL_0_OPCODE_X0 = 86,
1388 SNEH_SPECIAL_0_OPCODE_X1 = 56,
1389 SNE_SPECIAL_0_OPCODE_X0 = 87,
1390 SNE_SPECIAL_0_OPCODE_X1 = 57,
1391 SNE_SPECIAL_5_OPCODE_Y0 = 3,
1392 SNE_SPECIAL_5_OPCODE_Y1 = 3,
1393 SPECIAL_0_OPCODE_X0 = 0,
1394 SPECIAL_0_OPCODE_X1 = 1,
1395 SPECIAL_0_OPCODE_Y0 = 1,
1396 SPECIAL_0_OPCODE_Y1 = 1,
1397 SPECIAL_1_OPCODE_Y0 = 2,
1398 SPECIAL_1_OPCODE_Y1 = 2,
1399 SPECIAL_2_OPCODE_Y0 = 3,
1400 SPECIAL_2_OPCODE_Y1 = 3,
1401 SPECIAL_3_OPCODE_Y0 = 4,
1402 SPECIAL_3_OPCODE_Y1 = 4,
1403 SPECIAL_4_OPCODE_Y0 = 5,
1404 SPECIAL_4_OPCODE_Y1 = 5,
1405 SPECIAL_5_OPCODE_Y0 = 6,
1406 SPECIAL_5_OPCODE_Y1 = 6,
1407 SPECIAL_6_OPCODE_Y0 = 7,
1408 SPECIAL_7_OPCODE_Y0 = 8,
1409 SRAB_SPECIAL_0_OPCODE_X0 = 88,
1410 SRAB_SPECIAL_0_OPCODE_X1 = 58,
1411 SRAH_SPECIAL_0_OPCODE_X0 = 89,
1412 SRAH_SPECIAL_0_OPCODE_X1 = 59,
1413 SRAIB_SHUN_0_OPCODE_X0 = 8,
1414 SRAIB_SHUN_0_OPCODE_X1 = 8,
1415 SRAIH_SHUN_0_OPCODE_X0 = 9,
1416 SRAIH_SHUN_0_OPCODE_X1 = 9,
1417 SRAI_SHUN_0_OPCODE_X0 = 10,
1418 SRAI_SHUN_0_OPCODE_X1 = 10,
1419 SRAI_SHUN_0_OPCODE_Y0 = 4,
1420 SRAI_SHUN_0_OPCODE_Y1 = 4,
1421 SRA_SPECIAL_0_OPCODE_X0 = 90,
1422 SRA_SPECIAL_0_OPCODE_X1 = 60,
1423 SRA_SPECIAL_3_OPCODE_Y0 = 3,
1424 SRA_SPECIAL_3_OPCODE_Y1 = 3,
1425 SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
1426 SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
1427 SUBB_SPECIAL_0_OPCODE_X0 = 91,
1428 SUBB_SPECIAL_0_OPCODE_X1 = 61,
1429 SUBHS_SPECIAL_0_OPCODE_X0 = 101,
1430 SUBHS_SPECIAL_0_OPCODE_X1 = 71,
1431 SUBH_SPECIAL_0_OPCODE_X0 = 92,
1432 SUBH_SPECIAL_0_OPCODE_X1 = 62,
1433 SUBS_SPECIAL_0_OPCODE_X0 = 97,
1434 SUBS_SPECIAL_0_OPCODE_X1 = 67,
1435 SUB_SPECIAL_0_OPCODE_X0 = 93,
1436 SUB_SPECIAL_0_OPCODE_X1 = 63,
1437 SUB_SPECIAL_0_OPCODE_Y0 = 3,
1438 SUB_SPECIAL_0_OPCODE_Y1 = 3,
1439 SWADD_IMM_0_OPCODE_X1 = 30,
1440 SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
1441 SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
1442 SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
1443 SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
1444 SW_OPCODE_Y2 = 7,
1445 SW_SPECIAL_0_OPCODE_X1 = 64,
1446 TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
1447 TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
1448 TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
1449 TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
1450 TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
1451 TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
1452 TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
1453 TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
1454 TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
1455 UN_0_SHUN_0_OPCODE_X0 = 11,
1456 UN_0_SHUN_0_OPCODE_X1 = 11,
1457 UN_0_SHUN_0_OPCODE_Y0 = 5,
1458 UN_0_SHUN_0_OPCODE_Y1 = 5,
1459 WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
1460 XORI_IMM_0_OPCODE_X0 = 2,
1461 XORI_IMM_0_OPCODE_X1 = 21,
1462 XOR_SPECIAL_0_OPCODE_X0 = 94,
1463 XOR_SPECIAL_0_OPCODE_X1 = 65,
1464 XOR_SPECIAL_2_OPCODE_Y0 = 3,
1465 XOR_SPECIAL_2_OPCODE_Y1 = 3
1466};
1467
1468
1469#endif /* __ASSEMBLER__ */
1470
1471#endif /* __ARCH_OPCODE_H__ */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index aec60dc06007..0bb42642343a 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -1,5 +1,7 @@
1include include/asm-generic/Kbuild.asm 1include include/asm-generic/Kbuild.asm
2 2
3header-y += ../arch/
4
3header-y += ucontext.h 5header-y += ucontext.h
4header-y += hardwall.h 6header-y += hardwall.h
5 7
diff --git a/arch/tile/include/asm/opcode-tile_32.h b/arch/tile/include/asm/opcode-tile_32.h
deleted file mode 100644
index 03df7b1e77bf..000000000000
--- a/arch/tile/include/asm/opcode-tile_32.h
+++ /dev/null
@@ -1,1513 +0,0 @@
1/* tile.h -- Header file for TILE opcode table
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Tilera Corp. */
4
5#ifndef opcode_tile_h
6#define opcode_tile_h
7
8typedef unsigned long long tile_bundle_bits;
9
10
11enum
12{
13 TILE_MAX_OPERANDS = 5 /* mm */
14};
15
16typedef enum
17{
18 TILE_OPC_BPT,
19 TILE_OPC_INFO,
20 TILE_OPC_INFOL,
21 TILE_OPC_J,
22 TILE_OPC_JAL,
23 TILE_OPC_MOVE,
24 TILE_OPC_MOVE_SN,
25 TILE_OPC_MOVEI,
26 TILE_OPC_MOVEI_SN,
27 TILE_OPC_MOVELI,
28 TILE_OPC_MOVELI_SN,
29 TILE_OPC_MOVELIS,
30 TILE_OPC_PREFETCH,
31 TILE_OPC_RAISE,
32 TILE_OPC_ADD,
33 TILE_OPC_ADD_SN,
34 TILE_OPC_ADDB,
35 TILE_OPC_ADDB_SN,
36 TILE_OPC_ADDBS_U,
37 TILE_OPC_ADDBS_U_SN,
38 TILE_OPC_ADDH,
39 TILE_OPC_ADDH_SN,
40 TILE_OPC_ADDHS,
41 TILE_OPC_ADDHS_SN,
42 TILE_OPC_ADDI,
43 TILE_OPC_ADDI_SN,
44 TILE_OPC_ADDIB,
45 TILE_OPC_ADDIB_SN,
46 TILE_OPC_ADDIH,
47 TILE_OPC_ADDIH_SN,
48 TILE_OPC_ADDLI,
49 TILE_OPC_ADDLI_SN,
50 TILE_OPC_ADDLIS,
51 TILE_OPC_ADDS,
52 TILE_OPC_ADDS_SN,
53 TILE_OPC_ADIFFB_U,
54 TILE_OPC_ADIFFB_U_SN,
55 TILE_OPC_ADIFFH,
56 TILE_OPC_ADIFFH_SN,
57 TILE_OPC_AND,
58 TILE_OPC_AND_SN,
59 TILE_OPC_ANDI,
60 TILE_OPC_ANDI_SN,
61 TILE_OPC_AULI,
62 TILE_OPC_AVGB_U,
63 TILE_OPC_AVGB_U_SN,
64 TILE_OPC_AVGH,
65 TILE_OPC_AVGH_SN,
66 TILE_OPC_BBNS,
67 TILE_OPC_BBNS_SN,
68 TILE_OPC_BBNST,
69 TILE_OPC_BBNST_SN,
70 TILE_OPC_BBS,
71 TILE_OPC_BBS_SN,
72 TILE_OPC_BBST,
73 TILE_OPC_BBST_SN,
74 TILE_OPC_BGEZ,
75 TILE_OPC_BGEZ_SN,
76 TILE_OPC_BGEZT,
77 TILE_OPC_BGEZT_SN,
78 TILE_OPC_BGZ,
79 TILE_OPC_BGZ_SN,
80 TILE_OPC_BGZT,
81 TILE_OPC_BGZT_SN,
82 TILE_OPC_BITX,
83 TILE_OPC_BITX_SN,
84 TILE_OPC_BLEZ,
85 TILE_OPC_BLEZ_SN,
86 TILE_OPC_BLEZT,
87 TILE_OPC_BLEZT_SN,
88 TILE_OPC_BLZ,
89 TILE_OPC_BLZ_SN,
90 TILE_OPC_BLZT,
91 TILE_OPC_BLZT_SN,
92 TILE_OPC_BNZ,
93 TILE_OPC_BNZ_SN,
94 TILE_OPC_BNZT,
95 TILE_OPC_BNZT_SN,
96 TILE_OPC_BYTEX,
97 TILE_OPC_BYTEX_SN,
98 TILE_OPC_BZ,
99 TILE_OPC_BZ_SN,
100 TILE_OPC_BZT,
101 TILE_OPC_BZT_SN,
102 TILE_OPC_CLZ,
103 TILE_OPC_CLZ_SN,
104 TILE_OPC_CRC32_32,
105 TILE_OPC_CRC32_32_SN,
106 TILE_OPC_CRC32_8,
107 TILE_OPC_CRC32_8_SN,
108 TILE_OPC_CTZ,
109 TILE_OPC_CTZ_SN,
110 TILE_OPC_DRAIN,
111 TILE_OPC_DTLBPR,
112 TILE_OPC_DWORD_ALIGN,
113 TILE_OPC_DWORD_ALIGN_SN,
114 TILE_OPC_FINV,
115 TILE_OPC_FLUSH,
116 TILE_OPC_FNOP,
117 TILE_OPC_ICOH,
118 TILE_OPC_ILL,
119 TILE_OPC_INTHB,
120 TILE_OPC_INTHB_SN,
121 TILE_OPC_INTHH,
122 TILE_OPC_INTHH_SN,
123 TILE_OPC_INTLB,
124 TILE_OPC_INTLB_SN,
125 TILE_OPC_INTLH,
126 TILE_OPC_INTLH_SN,
127 TILE_OPC_INV,
128 TILE_OPC_IRET,
129 TILE_OPC_JALB,
130 TILE_OPC_JALF,
131 TILE_OPC_JALR,
132 TILE_OPC_JALRP,
133 TILE_OPC_JB,
134 TILE_OPC_JF,
135 TILE_OPC_JR,
136 TILE_OPC_JRP,
137 TILE_OPC_LB,
138 TILE_OPC_LB_SN,
139 TILE_OPC_LB_U,
140 TILE_OPC_LB_U_SN,
141 TILE_OPC_LBADD,
142 TILE_OPC_LBADD_SN,
143 TILE_OPC_LBADD_U,
144 TILE_OPC_LBADD_U_SN,
145 TILE_OPC_LH,
146 TILE_OPC_LH_SN,
147 TILE_OPC_LH_U,
148 TILE_OPC_LH_U_SN,
149 TILE_OPC_LHADD,
150 TILE_OPC_LHADD_SN,
151 TILE_OPC_LHADD_U,
152 TILE_OPC_LHADD_U_SN,
153 TILE_OPC_LNK,
154 TILE_OPC_LNK_SN,
155 TILE_OPC_LW,
156 TILE_OPC_LW_SN,
157 TILE_OPC_LW_NA,
158 TILE_OPC_LW_NA_SN,
159 TILE_OPC_LWADD,
160 TILE_OPC_LWADD_SN,
161 TILE_OPC_LWADD_NA,
162 TILE_OPC_LWADD_NA_SN,
163 TILE_OPC_MAXB_U,
164 TILE_OPC_MAXB_U_SN,
165 TILE_OPC_MAXH,
166 TILE_OPC_MAXH_SN,
167 TILE_OPC_MAXIB_U,
168 TILE_OPC_MAXIB_U_SN,
169 TILE_OPC_MAXIH,
170 TILE_OPC_MAXIH_SN,
171 TILE_OPC_MF,
172 TILE_OPC_MFSPR,
173 TILE_OPC_MINB_U,
174 TILE_OPC_MINB_U_SN,
175 TILE_OPC_MINH,
176 TILE_OPC_MINH_SN,
177 TILE_OPC_MINIB_U,
178 TILE_OPC_MINIB_U_SN,
179 TILE_OPC_MINIH,
180 TILE_OPC_MINIH_SN,
181 TILE_OPC_MM,
182 TILE_OPC_MNZ,
183 TILE_OPC_MNZ_SN,
184 TILE_OPC_MNZB,
185 TILE_OPC_MNZB_SN,
186 TILE_OPC_MNZH,
187 TILE_OPC_MNZH_SN,
188 TILE_OPC_MTSPR,
189 TILE_OPC_MULHH_SS,
190 TILE_OPC_MULHH_SS_SN,
191 TILE_OPC_MULHH_SU,
192 TILE_OPC_MULHH_SU_SN,
193 TILE_OPC_MULHH_UU,
194 TILE_OPC_MULHH_UU_SN,
195 TILE_OPC_MULHHA_SS,
196 TILE_OPC_MULHHA_SS_SN,
197 TILE_OPC_MULHHA_SU,
198 TILE_OPC_MULHHA_SU_SN,
199 TILE_OPC_MULHHA_UU,
200 TILE_OPC_MULHHA_UU_SN,
201 TILE_OPC_MULHHSA_UU,
202 TILE_OPC_MULHHSA_UU_SN,
203 TILE_OPC_MULHL_SS,
204 TILE_OPC_MULHL_SS_SN,
205 TILE_OPC_MULHL_SU,
206 TILE_OPC_MULHL_SU_SN,
207 TILE_OPC_MULHL_US,
208 TILE_OPC_MULHL_US_SN,
209 TILE_OPC_MULHL_UU,
210 TILE_OPC_MULHL_UU_SN,
211 TILE_OPC_MULHLA_SS,
212 TILE_OPC_MULHLA_SS_SN,
213 TILE_OPC_MULHLA_SU,
214 TILE_OPC_MULHLA_SU_SN,
215 TILE_OPC_MULHLA_US,
216 TILE_OPC_MULHLA_US_SN,
217 TILE_OPC_MULHLA_UU,
218 TILE_OPC_MULHLA_UU_SN,
219 TILE_OPC_MULHLSA_UU,
220 TILE_OPC_MULHLSA_UU_SN,
221 TILE_OPC_MULLL_SS,
222 TILE_OPC_MULLL_SS_SN,
223 TILE_OPC_MULLL_SU,
224 TILE_OPC_MULLL_SU_SN,
225 TILE_OPC_MULLL_UU,
226 TILE_OPC_MULLL_UU_SN,
227 TILE_OPC_MULLLA_SS,
228 TILE_OPC_MULLLA_SS_SN,
229 TILE_OPC_MULLLA_SU,
230 TILE_OPC_MULLLA_SU_SN,
231 TILE_OPC_MULLLA_UU,
232 TILE_OPC_MULLLA_UU_SN,
233 TILE_OPC_MULLLSA_UU,
234 TILE_OPC_MULLLSA_UU_SN,
235 TILE_OPC_MVNZ,
236 TILE_OPC_MVNZ_SN,
237 TILE_OPC_MVZ,
238 TILE_OPC_MVZ_SN,
239 TILE_OPC_MZ,
240 TILE_OPC_MZ_SN,
241 TILE_OPC_MZB,
242 TILE_OPC_MZB_SN,
243 TILE_OPC_MZH,
244 TILE_OPC_MZH_SN,
245 TILE_OPC_NAP,
246 TILE_OPC_NOP,
247 TILE_OPC_NOR,
248 TILE_OPC_NOR_SN,
249 TILE_OPC_OR,
250 TILE_OPC_OR_SN,
251 TILE_OPC_ORI,
252 TILE_OPC_ORI_SN,
253 TILE_OPC_PACKBS_U,
254 TILE_OPC_PACKBS_U_SN,
255 TILE_OPC_PACKHB,
256 TILE_OPC_PACKHB_SN,
257 TILE_OPC_PACKHS,
258 TILE_OPC_PACKHS_SN,
259 TILE_OPC_PACKLB,
260 TILE_OPC_PACKLB_SN,
261 TILE_OPC_PCNT,
262 TILE_OPC_PCNT_SN,
263 TILE_OPC_RL,
264 TILE_OPC_RL_SN,
265 TILE_OPC_RLI,
266 TILE_OPC_RLI_SN,
267 TILE_OPC_S1A,
268 TILE_OPC_S1A_SN,
269 TILE_OPC_S2A,
270 TILE_OPC_S2A_SN,
271 TILE_OPC_S3A,
272 TILE_OPC_S3A_SN,
273 TILE_OPC_SADAB_U,
274 TILE_OPC_SADAB_U_SN,
275 TILE_OPC_SADAH,
276 TILE_OPC_SADAH_SN,
277 TILE_OPC_SADAH_U,
278 TILE_OPC_SADAH_U_SN,
279 TILE_OPC_SADB_U,
280 TILE_OPC_SADB_U_SN,
281 TILE_OPC_SADH,
282 TILE_OPC_SADH_SN,
283 TILE_OPC_SADH_U,
284 TILE_OPC_SADH_U_SN,
285 TILE_OPC_SB,
286 TILE_OPC_SBADD,
287 TILE_OPC_SEQ,
288 TILE_OPC_SEQ_SN,
289 TILE_OPC_SEQB,
290 TILE_OPC_SEQB_SN,
291 TILE_OPC_SEQH,
292 TILE_OPC_SEQH_SN,
293 TILE_OPC_SEQI,
294 TILE_OPC_SEQI_SN,
295 TILE_OPC_SEQIB,
296 TILE_OPC_SEQIB_SN,
297 TILE_OPC_SEQIH,
298 TILE_OPC_SEQIH_SN,
299 TILE_OPC_SH,
300 TILE_OPC_SHADD,
301 TILE_OPC_SHL,
302 TILE_OPC_SHL_SN,
303 TILE_OPC_SHLB,
304 TILE_OPC_SHLB_SN,
305 TILE_OPC_SHLH,
306 TILE_OPC_SHLH_SN,
307 TILE_OPC_SHLI,
308 TILE_OPC_SHLI_SN,
309 TILE_OPC_SHLIB,
310 TILE_OPC_SHLIB_SN,
311 TILE_OPC_SHLIH,
312 TILE_OPC_SHLIH_SN,
313 TILE_OPC_SHR,
314 TILE_OPC_SHR_SN,
315 TILE_OPC_SHRB,
316 TILE_OPC_SHRB_SN,
317 TILE_OPC_SHRH,
318 TILE_OPC_SHRH_SN,
319 TILE_OPC_SHRI,
320 TILE_OPC_SHRI_SN,
321 TILE_OPC_SHRIB,
322 TILE_OPC_SHRIB_SN,
323 TILE_OPC_SHRIH,
324 TILE_OPC_SHRIH_SN,
325 TILE_OPC_SLT,
326 TILE_OPC_SLT_SN,
327 TILE_OPC_SLT_U,
328 TILE_OPC_SLT_U_SN,
329 TILE_OPC_SLTB,
330 TILE_OPC_SLTB_SN,
331 TILE_OPC_SLTB_U,
332 TILE_OPC_SLTB_U_SN,
333 TILE_OPC_SLTE,
334 TILE_OPC_SLTE_SN,
335 TILE_OPC_SLTE_U,
336 TILE_OPC_SLTE_U_SN,
337 TILE_OPC_SLTEB,
338 TILE_OPC_SLTEB_SN,
339 TILE_OPC_SLTEB_U,
340 TILE_OPC_SLTEB_U_SN,
341 TILE_OPC_SLTEH,
342 TILE_OPC_SLTEH_SN,
343 TILE_OPC_SLTEH_U,
344 TILE_OPC_SLTEH_U_SN,
345 TILE_OPC_SLTH,
346 TILE_OPC_SLTH_SN,
347 TILE_OPC_SLTH_U,
348 TILE_OPC_SLTH_U_SN,
349 TILE_OPC_SLTI,
350 TILE_OPC_SLTI_SN,
351 TILE_OPC_SLTI_U,
352 TILE_OPC_SLTI_U_SN,
353 TILE_OPC_SLTIB,
354 TILE_OPC_SLTIB_SN,
355 TILE_OPC_SLTIB_U,
356 TILE_OPC_SLTIB_U_SN,
357 TILE_OPC_SLTIH,
358 TILE_OPC_SLTIH_SN,
359 TILE_OPC_SLTIH_U,
360 TILE_OPC_SLTIH_U_SN,
361 TILE_OPC_SNE,
362 TILE_OPC_SNE_SN,
363 TILE_OPC_SNEB,
364 TILE_OPC_SNEB_SN,
365 TILE_OPC_SNEH,
366 TILE_OPC_SNEH_SN,
367 TILE_OPC_SRA,
368 TILE_OPC_SRA_SN,
369 TILE_OPC_SRAB,
370 TILE_OPC_SRAB_SN,
371 TILE_OPC_SRAH,
372 TILE_OPC_SRAH_SN,
373 TILE_OPC_SRAI,
374 TILE_OPC_SRAI_SN,
375 TILE_OPC_SRAIB,
376 TILE_OPC_SRAIB_SN,
377 TILE_OPC_SRAIH,
378 TILE_OPC_SRAIH_SN,
379 TILE_OPC_SUB,
380 TILE_OPC_SUB_SN,
381 TILE_OPC_SUBB,
382 TILE_OPC_SUBB_SN,
383 TILE_OPC_SUBBS_U,
384 TILE_OPC_SUBBS_U_SN,
385 TILE_OPC_SUBH,
386 TILE_OPC_SUBH_SN,
387 TILE_OPC_SUBHS,
388 TILE_OPC_SUBHS_SN,
389 TILE_OPC_SUBS,
390 TILE_OPC_SUBS_SN,
391 TILE_OPC_SW,
392 TILE_OPC_SWADD,
393 TILE_OPC_SWINT0,
394 TILE_OPC_SWINT1,
395 TILE_OPC_SWINT2,
396 TILE_OPC_SWINT3,
397 TILE_OPC_TBLIDXB0,
398 TILE_OPC_TBLIDXB0_SN,
399 TILE_OPC_TBLIDXB1,
400 TILE_OPC_TBLIDXB1_SN,
401 TILE_OPC_TBLIDXB2,
402 TILE_OPC_TBLIDXB2_SN,
403 TILE_OPC_TBLIDXB3,
404 TILE_OPC_TBLIDXB3_SN,
405 TILE_OPC_TNS,
406 TILE_OPC_TNS_SN,
407 TILE_OPC_WH64,
408 TILE_OPC_XOR,
409 TILE_OPC_XOR_SN,
410 TILE_OPC_XORI,
411 TILE_OPC_XORI_SN,
412 TILE_OPC_NONE
413} tile_mnemonic;
414
415/* 64-bit pattern for a { bpt ; nop } bundle. */
416#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
417
418
419#define TILE_ELF_MACHINE_CODE EM_TILEPRO
420
421#define TILE_ELF_NAME "elf32-tilepro"
422
423
424static __inline unsigned int
425get_BrOff_SN(tile_bundle_bits num)
426{
427 const unsigned int n = (unsigned int)num;
428 return (((n >> 0)) & 0x3ff);
429}
430
431static __inline unsigned int
432get_BrOff_X1(tile_bundle_bits n)
433{
434 return (((unsigned int)(n >> 43)) & 0x00007fff) |
435 (((unsigned int)(n >> 20)) & 0x00018000);
436}
437
438static __inline unsigned int
439get_BrType_X1(tile_bundle_bits n)
440{
441 return (((unsigned int)(n >> 31)) & 0xf);
442}
443
444static __inline unsigned int
445get_Dest_Imm8_X1(tile_bundle_bits n)
446{
447 return (((unsigned int)(n >> 31)) & 0x0000003f) |
448 (((unsigned int)(n >> 43)) & 0x000000c0);
449}
450
451static __inline unsigned int
452get_Dest_SN(tile_bundle_bits num)
453{
454 const unsigned int n = (unsigned int)num;
455 return (((n >> 2)) & 0x3);
456}
457
458static __inline unsigned int
459get_Dest_X0(tile_bundle_bits num)
460{
461 const unsigned int n = (unsigned int)num;
462 return (((n >> 0)) & 0x3f);
463}
464
465static __inline unsigned int
466get_Dest_X1(tile_bundle_bits n)
467{
468 return (((unsigned int)(n >> 31)) & 0x3f);
469}
470
471static __inline unsigned int
472get_Dest_Y0(tile_bundle_bits num)
473{
474 const unsigned int n = (unsigned int)num;
475 return (((n >> 0)) & 0x3f);
476}
477
478static __inline unsigned int
479get_Dest_Y1(tile_bundle_bits n)
480{
481 return (((unsigned int)(n >> 31)) & 0x3f);
482}
483
484static __inline unsigned int
485get_Imm16_X0(tile_bundle_bits num)
486{
487 const unsigned int n = (unsigned int)num;
488 return (((n >> 12)) & 0xffff);
489}
490
491static __inline unsigned int
492get_Imm16_X1(tile_bundle_bits n)
493{
494 return (((unsigned int)(n >> 43)) & 0xffff);
495}
496
497static __inline unsigned int
498get_Imm8_SN(tile_bundle_bits num)
499{
500 const unsigned int n = (unsigned int)num;
501 return (((n >> 0)) & 0xff);
502}
503
504static __inline unsigned int
505get_Imm8_X0(tile_bundle_bits num)
506{
507 const unsigned int n = (unsigned int)num;
508 return (((n >> 12)) & 0xff);
509}
510
511static __inline unsigned int
512get_Imm8_X1(tile_bundle_bits n)
513{
514 return (((unsigned int)(n >> 43)) & 0xff);
515}
516
517static __inline unsigned int
518get_Imm8_Y0(tile_bundle_bits num)
519{
520 const unsigned int n = (unsigned int)num;
521 return (((n >> 12)) & 0xff);
522}
523
524static __inline unsigned int
525get_Imm8_Y1(tile_bundle_bits n)
526{
527 return (((unsigned int)(n >> 43)) & 0xff);
528}
529
530static __inline unsigned int
531get_ImmOpcodeExtension_X0(tile_bundle_bits num)
532{
533 const unsigned int n = (unsigned int)num;
534 return (((n >> 20)) & 0x7f);
535}
536
537static __inline unsigned int
538get_ImmOpcodeExtension_X1(tile_bundle_bits n)
539{
540 return (((unsigned int)(n >> 51)) & 0x7f);
541}
542
543static __inline unsigned int
544get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
545{
546 const unsigned int n = (unsigned int)num;
547 return (((n >> 8)) & 0x3);
548}
549
550static __inline unsigned int
551get_JOffLong_X1(tile_bundle_bits n)
552{
553 return (((unsigned int)(n >> 43)) & 0x00007fff) |
554 (((unsigned int)(n >> 20)) & 0x00018000) |
555 (((unsigned int)(n >> 14)) & 0x001e0000) |
556 (((unsigned int)(n >> 16)) & 0x07e00000) |
557 (((unsigned int)(n >> 31)) & 0x18000000);
558}
559
560static __inline unsigned int
561get_JOff_X1(tile_bundle_bits n)
562{
563 return (((unsigned int)(n >> 43)) & 0x00007fff) |
564 (((unsigned int)(n >> 20)) & 0x00018000) |
565 (((unsigned int)(n >> 14)) & 0x001e0000) |
566 (((unsigned int)(n >> 16)) & 0x07e00000) |
567 (((unsigned int)(n >> 31)) & 0x08000000);
568}
569
570static __inline unsigned int
571get_MF_Imm15_X1(tile_bundle_bits n)
572{
573 return (((unsigned int)(n >> 37)) & 0x00003fff) |
574 (((unsigned int)(n >> 44)) & 0x00004000);
575}
576
577static __inline unsigned int
578get_MMEnd_X0(tile_bundle_bits num)
579{
580 const unsigned int n = (unsigned int)num;
581 return (((n >> 18)) & 0x1f);
582}
583
584static __inline unsigned int
585get_MMEnd_X1(tile_bundle_bits n)
586{
587 return (((unsigned int)(n >> 49)) & 0x1f);
588}
589
590static __inline unsigned int
591get_MMStart_X0(tile_bundle_bits num)
592{
593 const unsigned int n = (unsigned int)num;
594 return (((n >> 23)) & 0x1f);
595}
596
597static __inline unsigned int
598get_MMStart_X1(tile_bundle_bits n)
599{
600 return (((unsigned int)(n >> 54)) & 0x1f);
601}
602
603static __inline unsigned int
604get_MT_Imm15_X1(tile_bundle_bits n)
605{
606 return (((unsigned int)(n >> 31)) & 0x0000003f) |
607 (((unsigned int)(n >> 37)) & 0x00003fc0) |
608 (((unsigned int)(n >> 44)) & 0x00004000);
609}
610
611static __inline unsigned int
612get_Mode(tile_bundle_bits n)
613{
614 return (((unsigned int)(n >> 63)) & 0x1);
615}
616
617static __inline unsigned int
618get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
619{
620 const unsigned int n = (unsigned int)num;
621 return (((n >> 0)) & 0xf);
622}
623
624static __inline unsigned int
625get_Opcode_SN(tile_bundle_bits num)
626{
627 const unsigned int n = (unsigned int)num;
628 return (((n >> 10)) & 0x3f);
629}
630
631static __inline unsigned int
632get_Opcode_X0(tile_bundle_bits num)
633{
634 const unsigned int n = (unsigned int)num;
635 return (((n >> 28)) & 0x7);
636}
637
638static __inline unsigned int
639get_Opcode_X1(tile_bundle_bits n)
640{
641 return (((unsigned int)(n >> 59)) & 0xf);
642}
643
644static __inline unsigned int
645get_Opcode_Y0(tile_bundle_bits num)
646{
647 const unsigned int n = (unsigned int)num;
648 return (((n >> 27)) & 0xf);
649}
650
651static __inline unsigned int
652get_Opcode_Y1(tile_bundle_bits n)
653{
654 return (((unsigned int)(n >> 59)) & 0xf);
655}
656
657static __inline unsigned int
658get_Opcode_Y2(tile_bundle_bits n)
659{
660 return (((unsigned int)(n >> 56)) & 0x7);
661}
662
663static __inline unsigned int
664get_RROpcodeExtension_SN(tile_bundle_bits num)
665{
666 const unsigned int n = (unsigned int)num;
667 return (((n >> 4)) & 0xf);
668}
669
670static __inline unsigned int
671get_RRROpcodeExtension_X0(tile_bundle_bits num)
672{
673 const unsigned int n = (unsigned int)num;
674 return (((n >> 18)) & 0x1ff);
675}
676
677static __inline unsigned int
678get_RRROpcodeExtension_X1(tile_bundle_bits n)
679{
680 return (((unsigned int)(n >> 49)) & 0x1ff);
681}
682
683static __inline unsigned int
684get_RRROpcodeExtension_Y0(tile_bundle_bits num)
685{
686 const unsigned int n = (unsigned int)num;
687 return (((n >> 18)) & 0x3);
688}
689
690static __inline unsigned int
691get_RRROpcodeExtension_Y1(tile_bundle_bits n)
692{
693 return (((unsigned int)(n >> 49)) & 0x3);
694}
695
696static __inline unsigned int
697get_RouteOpcodeExtension_SN(tile_bundle_bits num)
698{
699 const unsigned int n = (unsigned int)num;
700 return (((n >> 0)) & 0x3ff);
701}
702
703static __inline unsigned int
704get_S_X0(tile_bundle_bits num)
705{
706 const unsigned int n = (unsigned int)num;
707 return (((n >> 27)) & 0x1);
708}
709
710static __inline unsigned int
711get_S_X1(tile_bundle_bits n)
712{
713 return (((unsigned int)(n >> 58)) & 0x1);
714}
715
716static __inline unsigned int
717get_ShAmt_X0(tile_bundle_bits num)
718{
719 const unsigned int n = (unsigned int)num;
720 return (((n >> 12)) & 0x1f);
721}
722
723static __inline unsigned int
724get_ShAmt_X1(tile_bundle_bits n)
725{
726 return (((unsigned int)(n >> 43)) & 0x1f);
727}
728
729static __inline unsigned int
730get_ShAmt_Y0(tile_bundle_bits num)
731{
732 const unsigned int n = (unsigned int)num;
733 return (((n >> 12)) & 0x1f);
734}
735
736static __inline unsigned int
737get_ShAmt_Y1(tile_bundle_bits n)
738{
739 return (((unsigned int)(n >> 43)) & 0x1f);
740}
741
742static __inline unsigned int
743get_SrcA_X0(tile_bundle_bits num)
744{
745 const unsigned int n = (unsigned int)num;
746 return (((n >> 6)) & 0x3f);
747}
748
749static __inline unsigned int
750get_SrcA_X1(tile_bundle_bits n)
751{
752 return (((unsigned int)(n >> 37)) & 0x3f);
753}
754
755static __inline unsigned int
756get_SrcA_Y0(tile_bundle_bits num)
757{
758 const unsigned int n = (unsigned int)num;
759 return (((n >> 6)) & 0x3f);
760}
761
762static __inline unsigned int
763get_SrcA_Y1(tile_bundle_bits n)
764{
765 return (((unsigned int)(n >> 37)) & 0x3f);
766}
767
768static __inline unsigned int
769get_SrcA_Y2(tile_bundle_bits n)
770{
771 return (((n >> 26)) & 0x00000001) |
772 (((unsigned int)(n >> 50)) & 0x0000003e);
773}
774
775static __inline unsigned int
776get_SrcBDest_Y2(tile_bundle_bits num)
777{
778 const unsigned int n = (unsigned int)num;
779 return (((n >> 20)) & 0x3f);
780}
781
782static __inline unsigned int
783get_SrcB_X0(tile_bundle_bits num)
784{
785 const unsigned int n = (unsigned int)num;
786 return (((n >> 12)) & 0x3f);
787}
788
789static __inline unsigned int
790get_SrcB_X1(tile_bundle_bits n)
791{
792 return (((unsigned int)(n >> 43)) & 0x3f);
793}
794
795static __inline unsigned int
796get_SrcB_Y0(tile_bundle_bits num)
797{
798 const unsigned int n = (unsigned int)num;
799 return (((n >> 12)) & 0x3f);
800}
801
802static __inline unsigned int
803get_SrcB_Y1(tile_bundle_bits n)
804{
805 return (((unsigned int)(n >> 43)) & 0x3f);
806}
807
808static __inline unsigned int
809get_Src_SN(tile_bundle_bits num)
810{
811 const unsigned int n = (unsigned int)num;
812 return (((n >> 0)) & 0x3);
813}
814
815static __inline unsigned int
816get_UnOpcodeExtension_X0(tile_bundle_bits num)
817{
818 const unsigned int n = (unsigned int)num;
819 return (((n >> 12)) & 0x1f);
820}
821
822static __inline unsigned int
823get_UnOpcodeExtension_X1(tile_bundle_bits n)
824{
825 return (((unsigned int)(n >> 43)) & 0x1f);
826}
827
828static __inline unsigned int
829get_UnOpcodeExtension_Y0(tile_bundle_bits num)
830{
831 const unsigned int n = (unsigned int)num;
832 return (((n >> 12)) & 0x1f);
833}
834
835static __inline unsigned int
836get_UnOpcodeExtension_Y1(tile_bundle_bits n)
837{
838 return (((unsigned int)(n >> 43)) & 0x1f);
839}
840
841static __inline unsigned int
842get_UnShOpcodeExtension_X0(tile_bundle_bits num)
843{
844 const unsigned int n = (unsigned int)num;
845 return (((n >> 17)) & 0x3ff);
846}
847
848static __inline unsigned int
849get_UnShOpcodeExtension_X1(tile_bundle_bits n)
850{
851 return (((unsigned int)(n >> 48)) & 0x3ff);
852}
853
854static __inline unsigned int
855get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
856{
857 const unsigned int n = (unsigned int)num;
858 return (((n >> 17)) & 0x7);
859}
860
861static __inline unsigned int
862get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
863{
864 return (((unsigned int)(n >> 48)) & 0x7);
865}
866
867
868static __inline int
869sign_extend(int n, int num_bits)
870{
871 int shift = (int)(sizeof(int) * 8 - num_bits);
872 return (n << shift) >> shift;
873}
874
875
876
877static __inline tile_bundle_bits
878create_BrOff_SN(int num)
879{
880 const unsigned int n = (unsigned int)num;
881 return ((n & 0x3ff) << 0);
882}
883
884static __inline tile_bundle_bits
885create_BrOff_X1(int num)
886{
887 const unsigned int n = (unsigned int)num;
888 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
889 (((tile_bundle_bits)(n & 0x00018000)) << 20);
890}
891
892static __inline tile_bundle_bits
893create_BrType_X1(int num)
894{
895 const unsigned int n = (unsigned int)num;
896 return (((tile_bundle_bits)(n & 0xf)) << 31);
897}
898
899static __inline tile_bundle_bits
900create_Dest_Imm8_X1(int num)
901{
902 const unsigned int n = (unsigned int)num;
903 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
904 (((tile_bundle_bits)(n & 0x000000c0)) << 43);
905}
906
907static __inline tile_bundle_bits
908create_Dest_SN(int num)
909{
910 const unsigned int n = (unsigned int)num;
911 return ((n & 0x3) << 2);
912}
913
914static __inline tile_bundle_bits
915create_Dest_X0(int num)
916{
917 const unsigned int n = (unsigned int)num;
918 return ((n & 0x3f) << 0);
919}
920
921static __inline tile_bundle_bits
922create_Dest_X1(int num)
923{
924 const unsigned int n = (unsigned int)num;
925 return (((tile_bundle_bits)(n & 0x3f)) << 31);
926}
927
928static __inline tile_bundle_bits
929create_Dest_Y0(int num)
930{
931 const unsigned int n = (unsigned int)num;
932 return ((n & 0x3f) << 0);
933}
934
935static __inline tile_bundle_bits
936create_Dest_Y1(int num)
937{
938 const unsigned int n = (unsigned int)num;
939 return (((tile_bundle_bits)(n & 0x3f)) << 31);
940}
941
942static __inline tile_bundle_bits
943create_Imm16_X0(int num)
944{
945 const unsigned int n = (unsigned int)num;
946 return ((n & 0xffff) << 12);
947}
948
949static __inline tile_bundle_bits
950create_Imm16_X1(int num)
951{
952 const unsigned int n = (unsigned int)num;
953 return (((tile_bundle_bits)(n & 0xffff)) << 43);
954}
955
956static __inline tile_bundle_bits
957create_Imm8_SN(int num)
958{
959 const unsigned int n = (unsigned int)num;
960 return ((n & 0xff) << 0);
961}
962
963static __inline tile_bundle_bits
964create_Imm8_X0(int num)
965{
966 const unsigned int n = (unsigned int)num;
967 return ((n & 0xff) << 12);
968}
969
970static __inline tile_bundle_bits
971create_Imm8_X1(int num)
972{
973 const unsigned int n = (unsigned int)num;
974 return (((tile_bundle_bits)(n & 0xff)) << 43);
975}
976
977static __inline tile_bundle_bits
978create_Imm8_Y0(int num)
979{
980 const unsigned int n = (unsigned int)num;
981 return ((n & 0xff) << 12);
982}
983
984static __inline tile_bundle_bits
985create_Imm8_Y1(int num)
986{
987 const unsigned int n = (unsigned int)num;
988 return (((tile_bundle_bits)(n & 0xff)) << 43);
989}
990
991static __inline tile_bundle_bits
992create_ImmOpcodeExtension_X0(int num)
993{
994 const unsigned int n = (unsigned int)num;
995 return ((n & 0x7f) << 20);
996}
997
998static __inline tile_bundle_bits
999create_ImmOpcodeExtension_X1(int num)
1000{
1001 const unsigned int n = (unsigned int)num;
1002 return (((tile_bundle_bits)(n & 0x7f)) << 51);
1003}
1004
1005static __inline tile_bundle_bits
1006create_ImmRROpcodeExtension_SN(int num)
1007{
1008 const unsigned int n = (unsigned int)num;
1009 return ((n & 0x3) << 8);
1010}
1011
1012static __inline tile_bundle_bits
1013create_JOffLong_X1(int num)
1014{
1015 const unsigned int n = (unsigned int)num;
1016 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1017 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1018 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1019 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1020 (((tile_bundle_bits)(n & 0x18000000)) << 31);
1021}
1022
1023static __inline tile_bundle_bits
1024create_JOff_X1(int num)
1025{
1026 const unsigned int n = (unsigned int)num;
1027 return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
1028 (((tile_bundle_bits)(n & 0x00018000)) << 20) |
1029 (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
1030 (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
1031 (((tile_bundle_bits)(n & 0x08000000)) << 31);
1032}
1033
1034static __inline tile_bundle_bits
1035create_MF_Imm15_X1(int num)
1036{
1037 const unsigned int n = (unsigned int)num;
1038 return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
1039 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1040}
1041
1042static __inline tile_bundle_bits
1043create_MMEnd_X0(int num)
1044{
1045 const unsigned int n = (unsigned int)num;
1046 return ((n & 0x1f) << 18);
1047}
1048
1049static __inline tile_bundle_bits
1050create_MMEnd_X1(int num)
1051{
1052 const unsigned int n = (unsigned int)num;
1053 return (((tile_bundle_bits)(n & 0x1f)) << 49);
1054}
1055
1056static __inline tile_bundle_bits
1057create_MMStart_X0(int num)
1058{
1059 const unsigned int n = (unsigned int)num;
1060 return ((n & 0x1f) << 23);
1061}
1062
1063static __inline tile_bundle_bits
1064create_MMStart_X1(int num)
1065{
1066 const unsigned int n = (unsigned int)num;
1067 return (((tile_bundle_bits)(n & 0x1f)) << 54);
1068}
1069
1070static __inline tile_bundle_bits
1071create_MT_Imm15_X1(int num)
1072{
1073 const unsigned int n = (unsigned int)num;
1074 return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
1075 (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
1076 (((tile_bundle_bits)(n & 0x00004000)) << 44);
1077}
1078
1079static __inline tile_bundle_bits
1080create_Mode(int num)
1081{
1082 const unsigned int n = (unsigned int)num;
1083 return (((tile_bundle_bits)(n & 0x1)) << 63);
1084}
1085
1086static __inline tile_bundle_bits
1087create_NoRegOpcodeExtension_SN(int num)
1088{
1089 const unsigned int n = (unsigned int)num;
1090 return ((n & 0xf) << 0);
1091}
1092
1093static __inline tile_bundle_bits
1094create_Opcode_SN(int num)
1095{
1096 const unsigned int n = (unsigned int)num;
1097 return ((n & 0x3f) << 10);
1098}
1099
1100static __inline tile_bundle_bits
1101create_Opcode_X0(int num)
1102{
1103 const unsigned int n = (unsigned int)num;
1104 return ((n & 0x7) << 28);
1105}
1106
1107static __inline tile_bundle_bits
1108create_Opcode_X1(int num)
1109{
1110 const unsigned int n = (unsigned int)num;
1111 return (((tile_bundle_bits)(n & 0xf)) << 59);
1112}
1113
1114static __inline tile_bundle_bits
1115create_Opcode_Y0(int num)
1116{
1117 const unsigned int n = (unsigned int)num;
1118 return ((n & 0xf) << 27);
1119}
1120
1121static __inline tile_bundle_bits
1122create_Opcode_Y1(int num)
1123{
1124 const unsigned int n = (unsigned int)num;
1125 return (((tile_bundle_bits)(n & 0xf)) << 59);
1126}
1127
1128static __inline tile_bundle_bits
1129create_Opcode_Y2(int num)
1130{
1131 const unsigned int n = (unsigned int)num;
1132 return (((tile_bundle_bits)(n & 0x7)) << 56);
1133}
1134
1135static __inline tile_bundle_bits
1136create_RROpcodeExtension_SN(int num)
1137{
1138 const unsigned int n = (unsigned int)num;
1139 return ((n & 0xf) << 4);
1140}
1141
1142static __inline tile_bundle_bits
1143create_RRROpcodeExtension_X0(int num)
1144{
1145 const unsigned int n = (unsigned int)num;
1146 return ((n & 0x1ff) << 18);
1147}
1148
1149static __inline tile_bundle_bits
1150create_RRROpcodeExtension_X1(int num)
1151{
1152 const unsigned int n = (unsigned int)num;
1153 return (((tile_bundle_bits)(n & 0x1ff)) << 49);
1154}
1155
1156static __inline tile_bundle_bits
1157create_RRROpcodeExtension_Y0(int num)
1158{
1159 const unsigned int n = (unsigned int)num;
1160 return ((n & 0x3) << 18);
1161}
1162
1163static __inline tile_bundle_bits
1164create_RRROpcodeExtension_Y1(int num)
1165{
1166 const unsigned int n = (unsigned int)num;
1167 return (((tile_bundle_bits)(n & 0x3)) << 49);
1168}
1169
1170static __inline tile_bundle_bits
1171create_RouteOpcodeExtension_SN(int num)
1172{
1173 const unsigned int n = (unsigned int)num;
1174 return ((n & 0x3ff) << 0);
1175}
1176
1177static __inline tile_bundle_bits
1178create_S_X0(int num)
1179{
1180 const unsigned int n = (unsigned int)num;
1181 return ((n & 0x1) << 27);
1182}
1183
1184static __inline tile_bundle_bits
1185create_S_X1(int num)
1186{
1187 const unsigned int n = (unsigned int)num;
1188 return (((tile_bundle_bits)(n & 0x1)) << 58);
1189}
1190
1191static __inline tile_bundle_bits
1192create_ShAmt_X0(int num)
1193{
1194 const unsigned int n = (unsigned int)num;
1195 return ((n & 0x1f) << 12);
1196}
1197
1198static __inline tile_bundle_bits
1199create_ShAmt_X1(int num)
1200{
1201 const unsigned int n = (unsigned int)num;
1202 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1203}
1204
1205static __inline tile_bundle_bits
1206create_ShAmt_Y0(int num)
1207{
1208 const unsigned int n = (unsigned int)num;
1209 return ((n & 0x1f) << 12);
1210}
1211
1212static __inline tile_bundle_bits
1213create_ShAmt_Y1(int num)
1214{
1215 const unsigned int n = (unsigned int)num;
1216 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1217}
1218
1219static __inline tile_bundle_bits
1220create_SrcA_X0(int num)
1221{
1222 const unsigned int n = (unsigned int)num;
1223 return ((n & 0x3f) << 6);
1224}
1225
1226static __inline tile_bundle_bits
1227create_SrcA_X1(int num)
1228{
1229 const unsigned int n = (unsigned int)num;
1230 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1231}
1232
1233static __inline tile_bundle_bits
1234create_SrcA_Y0(int num)
1235{
1236 const unsigned int n = (unsigned int)num;
1237 return ((n & 0x3f) << 6);
1238}
1239
1240static __inline tile_bundle_bits
1241create_SrcA_Y1(int num)
1242{
1243 const unsigned int n = (unsigned int)num;
1244 return (((tile_bundle_bits)(n & 0x3f)) << 37);
1245}
1246
1247static __inline tile_bundle_bits
1248create_SrcA_Y2(int num)
1249{
1250 const unsigned int n = (unsigned int)num;
1251 return ((n & 0x00000001) << 26) |
1252 (((tile_bundle_bits)(n & 0x0000003e)) << 50);
1253}
1254
1255static __inline tile_bundle_bits
1256create_SrcBDest_Y2(int num)
1257{
1258 const unsigned int n = (unsigned int)num;
1259 return ((n & 0x3f) << 20);
1260}
1261
1262static __inline tile_bundle_bits
1263create_SrcB_X0(int num)
1264{
1265 const unsigned int n = (unsigned int)num;
1266 return ((n & 0x3f) << 12);
1267}
1268
1269static __inline tile_bundle_bits
1270create_SrcB_X1(int num)
1271{
1272 const unsigned int n = (unsigned int)num;
1273 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1274}
1275
1276static __inline tile_bundle_bits
1277create_SrcB_Y0(int num)
1278{
1279 const unsigned int n = (unsigned int)num;
1280 return ((n & 0x3f) << 12);
1281}
1282
1283static __inline tile_bundle_bits
1284create_SrcB_Y1(int num)
1285{
1286 const unsigned int n = (unsigned int)num;
1287 return (((tile_bundle_bits)(n & 0x3f)) << 43);
1288}
1289
1290static __inline tile_bundle_bits
1291create_Src_SN(int num)
1292{
1293 const unsigned int n = (unsigned int)num;
1294 return ((n & 0x3) << 0);
1295}
1296
1297static __inline tile_bundle_bits
1298create_UnOpcodeExtension_X0(int num)
1299{
1300 const unsigned int n = (unsigned int)num;
1301 return ((n & 0x1f) << 12);
1302}
1303
1304static __inline tile_bundle_bits
1305create_UnOpcodeExtension_X1(int num)
1306{
1307 const unsigned int n = (unsigned int)num;
1308 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1309}
1310
1311static __inline tile_bundle_bits
1312create_UnOpcodeExtension_Y0(int num)
1313{
1314 const unsigned int n = (unsigned int)num;
1315 return ((n & 0x1f) << 12);
1316}
1317
1318static __inline tile_bundle_bits
1319create_UnOpcodeExtension_Y1(int num)
1320{
1321 const unsigned int n = (unsigned int)num;
1322 return (((tile_bundle_bits)(n & 0x1f)) << 43);
1323}
1324
1325static __inline tile_bundle_bits
1326create_UnShOpcodeExtension_X0(int num)
1327{
1328 const unsigned int n = (unsigned int)num;
1329 return ((n & 0x3ff) << 17);
1330}
1331
1332static __inline tile_bundle_bits
1333create_UnShOpcodeExtension_X1(int num)
1334{
1335 const unsigned int n = (unsigned int)num;
1336 return (((tile_bundle_bits)(n & 0x3ff)) << 48);
1337}
1338
1339static __inline tile_bundle_bits
1340create_UnShOpcodeExtension_Y0(int num)
1341{
1342 const unsigned int n = (unsigned int)num;
1343 return ((n & 0x7) << 17);
1344}
1345
1346static __inline tile_bundle_bits
1347create_UnShOpcodeExtension_Y1(int num)
1348{
1349 const unsigned int n = (unsigned int)num;
1350 return (((tile_bundle_bits)(n & 0x7)) << 48);
1351}
1352
1353
1354
1355typedef enum
1356{
1357 TILE_PIPELINE_X0,
1358 TILE_PIPELINE_X1,
1359 TILE_PIPELINE_Y0,
1360 TILE_PIPELINE_Y1,
1361 TILE_PIPELINE_Y2,
1362} tile_pipeline;
1363
1364#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
1365
1366typedef enum
1367{
1368 TILE_OP_TYPE_REGISTER,
1369 TILE_OP_TYPE_IMMEDIATE,
1370 TILE_OP_TYPE_ADDRESS,
1371 TILE_OP_TYPE_SPR
1372} tile_operand_type;
1373
1374/* This is the bit that determines if a bundle is in the Y encoding. */
1375#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
1376
1377enum
1378{
1379 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
1380 TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
1381
1382 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
1383 TILE_NUM_PIPELINE_ENCODINGS = 5,
1384
1385 /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
1386 TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
1387
1388 /* Instructions take this many bytes. */
1389 TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
1390
1391 /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
1392 TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
1393
1394 /* Bundles should be aligned modulo this number of bytes. */
1395 TILE_BUNDLE_ALIGNMENT_IN_BYTES =
1396 (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
1397
1398 /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
1399 TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
1400
1401 /* Static network instructions take this many bytes. */
1402 TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
1403 (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
1404
1405 /* Number of registers (some are magic, such as network I/O). */
1406 TILE_NUM_REGISTERS = 64,
1407
1408 /* Number of static network registers. */
1409 TILE_NUM_SN_REGISTERS = 4
1410};
1411
1412
1413struct tile_operand
1414{
1415 /* Is this operand a register, immediate or address? */
1416 tile_operand_type type;
1417
1418 /* The default relocation type for this operand. */
1419 signed int default_reloc : 16;
1420
1421 /* How many bits is this value? (used for range checking) */
1422 unsigned int num_bits : 5;
1423
1424 /* Is the value signed? (used for range checking) */
1425 unsigned int is_signed : 1;
1426
1427 /* Is this operand a source register? */
1428 unsigned int is_src_reg : 1;
1429
1430 /* Is this operand written? (i.e. is it a destination register) */
1431 unsigned int is_dest_reg : 1;
1432
1433 /* Is this operand PC-relative? */
1434 unsigned int is_pc_relative : 1;
1435
1436 /* By how many bits do we right shift the value before inserting? */
1437 unsigned int rightshift : 2;
1438
1439 /* Return the bits for this operand to be ORed into an existing bundle. */
1440 tile_bundle_bits (*insert) (int op);
1441
1442 /* Extract this operand and return it. */
1443 unsigned int (*extract) (tile_bundle_bits bundle);
1444};
1445
1446
1447extern const struct tile_operand tile_operands[];
1448
1449/* One finite-state machine per pipe for rapid instruction decoding. */
1450extern const unsigned short * const
1451tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
1452
1453
1454struct tile_opcode
1455{
1456 /* The opcode mnemonic, e.g. "add" */
1457 const char *name;
1458
1459 /* The enum value for this mnemonic. */
1460 tile_mnemonic mnemonic;
1461
1462 /* A bit mask of which of the five pipes this instruction
1463 is compatible with:
1464 X0 0x01
1465 X1 0x02
1466 Y0 0x04
1467 Y1 0x08
1468 Y2 0x10 */
1469 unsigned char pipes;
1470
1471 /* How many operands are there? */
1472 unsigned char num_operands;
1473
1474 /* Which register does this write implicitly, or TREG_ZERO if none? */
1475 unsigned char implicitly_written_register;
1476
1477 /* Can this be bundled with other instructions (almost always true). */
1478 unsigned char can_bundle;
1479
1480 /* The description of the operands. Each of these is an
1481 * index into the tile_operands[] table. */
1482 unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
1483
1484};
1485
1486extern const struct tile_opcode tile_opcodes[];
1487
1488
1489/* Used for non-textual disassembly into structs. */
1490struct tile_decoded_instruction
1491{
1492 const struct tile_opcode *opcode;
1493 const struct tile_operand *operands[TILE_MAX_OPERANDS];
1494 int operand_values[TILE_MAX_OPERANDS];
1495};
1496
1497
1498/* Disassemble a bundle into a struct for machine processing. */
1499extern int parse_insn_tile(tile_bundle_bits bits,
1500 unsigned int pc,
1501 struct tile_decoded_instruction
1502 decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
1503
1504
1505/* Given a set of bundle bits and a specific pipe, returns which
1506 * instruction the bundle contains in that pipe.
1507 */
1508extern const struct tile_opcode *
1509find_opcode(tile_bundle_bits bits, tile_pipeline pipe);
1510
1511
1512
1513#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode-tile_64.h b/arch/tile/include/asm/opcode-tile_64.h
deleted file mode 100644
index c0633466cd5c..000000000000
--- a/arch/tile/include/asm/opcode-tile_64.h
+++ /dev/null
@@ -1,1248 +0,0 @@
1/* tile.h -- Header file for TILE opcode table
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Tilera Corp. */
4
5#ifndef opcode_tile_h
6#define opcode_tile_h
7
8typedef unsigned long long tilegx_bundle_bits;
9
10
11enum
12{
13 TILEGX_MAX_OPERANDS = 4 /* bfexts */
14};
15
16typedef enum
17{
18 TILEGX_OPC_BPT,
19 TILEGX_OPC_INFO,
20 TILEGX_OPC_INFOL,
21 TILEGX_OPC_MOVE,
22 TILEGX_OPC_MOVEI,
23 TILEGX_OPC_MOVELI,
24 TILEGX_OPC_PREFETCH,
25 TILEGX_OPC_PREFETCH_ADD_L1,
26 TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
27 TILEGX_OPC_PREFETCH_ADD_L2,
28 TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
29 TILEGX_OPC_PREFETCH_ADD_L3,
30 TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
31 TILEGX_OPC_PREFETCH_L1,
32 TILEGX_OPC_PREFETCH_L1_FAULT,
33 TILEGX_OPC_PREFETCH_L2,
34 TILEGX_OPC_PREFETCH_L2_FAULT,
35 TILEGX_OPC_PREFETCH_L3,
36 TILEGX_OPC_PREFETCH_L3_FAULT,
37 TILEGX_OPC_RAISE,
38 TILEGX_OPC_ADD,
39 TILEGX_OPC_ADDI,
40 TILEGX_OPC_ADDLI,
41 TILEGX_OPC_ADDX,
42 TILEGX_OPC_ADDXI,
43 TILEGX_OPC_ADDXLI,
44 TILEGX_OPC_ADDXSC,
45 TILEGX_OPC_AND,
46 TILEGX_OPC_ANDI,
47 TILEGX_OPC_BEQZ,
48 TILEGX_OPC_BEQZT,
49 TILEGX_OPC_BFEXTS,
50 TILEGX_OPC_BFEXTU,
51 TILEGX_OPC_BFINS,
52 TILEGX_OPC_BGEZ,
53 TILEGX_OPC_BGEZT,
54 TILEGX_OPC_BGTZ,
55 TILEGX_OPC_BGTZT,
56 TILEGX_OPC_BLBC,
57 TILEGX_OPC_BLBCT,
58 TILEGX_OPC_BLBS,
59 TILEGX_OPC_BLBST,
60 TILEGX_OPC_BLEZ,
61 TILEGX_OPC_BLEZT,
62 TILEGX_OPC_BLTZ,
63 TILEGX_OPC_BLTZT,
64 TILEGX_OPC_BNEZ,
65 TILEGX_OPC_BNEZT,
66 TILEGX_OPC_CLZ,
67 TILEGX_OPC_CMOVEQZ,
68 TILEGX_OPC_CMOVNEZ,
69 TILEGX_OPC_CMPEQ,
70 TILEGX_OPC_CMPEQI,
71 TILEGX_OPC_CMPEXCH,
72 TILEGX_OPC_CMPEXCH4,
73 TILEGX_OPC_CMPLES,
74 TILEGX_OPC_CMPLEU,
75 TILEGX_OPC_CMPLTS,
76 TILEGX_OPC_CMPLTSI,
77 TILEGX_OPC_CMPLTU,
78 TILEGX_OPC_CMPLTUI,
79 TILEGX_OPC_CMPNE,
80 TILEGX_OPC_CMUL,
81 TILEGX_OPC_CMULA,
82 TILEGX_OPC_CMULAF,
83 TILEGX_OPC_CMULF,
84 TILEGX_OPC_CMULFR,
85 TILEGX_OPC_CMULH,
86 TILEGX_OPC_CMULHR,
87 TILEGX_OPC_CRC32_32,
88 TILEGX_OPC_CRC32_8,
89 TILEGX_OPC_CTZ,
90 TILEGX_OPC_DBLALIGN,
91 TILEGX_OPC_DBLALIGN2,
92 TILEGX_OPC_DBLALIGN4,
93 TILEGX_OPC_DBLALIGN6,
94 TILEGX_OPC_DRAIN,
95 TILEGX_OPC_DTLBPR,
96 TILEGX_OPC_EXCH,
97 TILEGX_OPC_EXCH4,
98 TILEGX_OPC_FDOUBLE_ADD_FLAGS,
99 TILEGX_OPC_FDOUBLE_ADDSUB,
100 TILEGX_OPC_FDOUBLE_MUL_FLAGS,
101 TILEGX_OPC_FDOUBLE_PACK1,
102 TILEGX_OPC_FDOUBLE_PACK2,
103 TILEGX_OPC_FDOUBLE_SUB_FLAGS,
104 TILEGX_OPC_FDOUBLE_UNPACK_MAX,
105 TILEGX_OPC_FDOUBLE_UNPACK_MIN,
106 TILEGX_OPC_FETCHADD,
107 TILEGX_OPC_FETCHADD4,
108 TILEGX_OPC_FETCHADDGEZ,
109 TILEGX_OPC_FETCHADDGEZ4,
110 TILEGX_OPC_FETCHAND,
111 TILEGX_OPC_FETCHAND4,
112 TILEGX_OPC_FETCHOR,
113 TILEGX_OPC_FETCHOR4,
114 TILEGX_OPC_FINV,
115 TILEGX_OPC_FLUSH,
116 TILEGX_OPC_FLUSHWB,
117 TILEGX_OPC_FNOP,
118 TILEGX_OPC_FSINGLE_ADD1,
119 TILEGX_OPC_FSINGLE_ADDSUB2,
120 TILEGX_OPC_FSINGLE_MUL1,
121 TILEGX_OPC_FSINGLE_MUL2,
122 TILEGX_OPC_FSINGLE_PACK1,
123 TILEGX_OPC_FSINGLE_PACK2,
124 TILEGX_OPC_FSINGLE_SUB1,
125 TILEGX_OPC_ICOH,
126 TILEGX_OPC_ILL,
127 TILEGX_OPC_INV,
128 TILEGX_OPC_IRET,
129 TILEGX_OPC_J,
130 TILEGX_OPC_JAL,
131 TILEGX_OPC_JALR,
132 TILEGX_OPC_JALRP,
133 TILEGX_OPC_JR,
134 TILEGX_OPC_JRP,
135 TILEGX_OPC_LD,
136 TILEGX_OPC_LD1S,
137 TILEGX_OPC_LD1S_ADD,
138 TILEGX_OPC_LD1U,
139 TILEGX_OPC_LD1U_ADD,
140 TILEGX_OPC_LD2S,
141 TILEGX_OPC_LD2S_ADD,
142 TILEGX_OPC_LD2U,
143 TILEGX_OPC_LD2U_ADD,
144 TILEGX_OPC_LD4S,
145 TILEGX_OPC_LD4S_ADD,
146 TILEGX_OPC_LD4U,
147 TILEGX_OPC_LD4U_ADD,
148 TILEGX_OPC_LD_ADD,
149 TILEGX_OPC_LDNA,
150 TILEGX_OPC_LDNA_ADD,
151 TILEGX_OPC_LDNT,
152 TILEGX_OPC_LDNT1S,
153 TILEGX_OPC_LDNT1S_ADD,
154 TILEGX_OPC_LDNT1U,
155 TILEGX_OPC_LDNT1U_ADD,
156 TILEGX_OPC_LDNT2S,
157 TILEGX_OPC_LDNT2S_ADD,
158 TILEGX_OPC_LDNT2U,
159 TILEGX_OPC_LDNT2U_ADD,
160 TILEGX_OPC_LDNT4S,
161 TILEGX_OPC_LDNT4S_ADD,
162 TILEGX_OPC_LDNT4U,
163 TILEGX_OPC_LDNT4U_ADD,
164 TILEGX_OPC_LDNT_ADD,
165 TILEGX_OPC_LNK,
166 TILEGX_OPC_MF,
167 TILEGX_OPC_MFSPR,
168 TILEGX_OPC_MM,
169 TILEGX_OPC_MNZ,
170 TILEGX_OPC_MTSPR,
171 TILEGX_OPC_MUL_HS_HS,
172 TILEGX_OPC_MUL_HS_HU,
173 TILEGX_OPC_MUL_HS_LS,
174 TILEGX_OPC_MUL_HS_LU,
175 TILEGX_OPC_MUL_HU_HU,
176 TILEGX_OPC_MUL_HU_LS,
177 TILEGX_OPC_MUL_HU_LU,
178 TILEGX_OPC_MUL_LS_LS,
179 TILEGX_OPC_MUL_LS_LU,
180 TILEGX_OPC_MUL_LU_LU,
181 TILEGX_OPC_MULA_HS_HS,
182 TILEGX_OPC_MULA_HS_HU,
183 TILEGX_OPC_MULA_HS_LS,
184 TILEGX_OPC_MULA_HS_LU,
185 TILEGX_OPC_MULA_HU_HU,
186 TILEGX_OPC_MULA_HU_LS,
187 TILEGX_OPC_MULA_HU_LU,
188 TILEGX_OPC_MULA_LS_LS,
189 TILEGX_OPC_MULA_LS_LU,
190 TILEGX_OPC_MULA_LU_LU,
191 TILEGX_OPC_MULAX,
192 TILEGX_OPC_MULX,
193 TILEGX_OPC_MZ,
194 TILEGX_OPC_NAP,
195 TILEGX_OPC_NOP,
196 TILEGX_OPC_NOR,
197 TILEGX_OPC_OR,
198 TILEGX_OPC_ORI,
199 TILEGX_OPC_PCNT,
200 TILEGX_OPC_REVBITS,
201 TILEGX_OPC_REVBYTES,
202 TILEGX_OPC_ROTL,
203 TILEGX_OPC_ROTLI,
204 TILEGX_OPC_SHL,
205 TILEGX_OPC_SHL16INSLI,
206 TILEGX_OPC_SHL1ADD,
207 TILEGX_OPC_SHL1ADDX,
208 TILEGX_OPC_SHL2ADD,
209 TILEGX_OPC_SHL2ADDX,
210 TILEGX_OPC_SHL3ADD,
211 TILEGX_OPC_SHL3ADDX,
212 TILEGX_OPC_SHLI,
213 TILEGX_OPC_SHLX,
214 TILEGX_OPC_SHLXI,
215 TILEGX_OPC_SHRS,
216 TILEGX_OPC_SHRSI,
217 TILEGX_OPC_SHRU,
218 TILEGX_OPC_SHRUI,
219 TILEGX_OPC_SHRUX,
220 TILEGX_OPC_SHRUXI,
221 TILEGX_OPC_SHUFFLEBYTES,
222 TILEGX_OPC_ST,
223 TILEGX_OPC_ST1,
224 TILEGX_OPC_ST1_ADD,
225 TILEGX_OPC_ST2,
226 TILEGX_OPC_ST2_ADD,
227 TILEGX_OPC_ST4,
228 TILEGX_OPC_ST4_ADD,
229 TILEGX_OPC_ST_ADD,
230 TILEGX_OPC_STNT,
231 TILEGX_OPC_STNT1,
232 TILEGX_OPC_STNT1_ADD,
233 TILEGX_OPC_STNT2,
234 TILEGX_OPC_STNT2_ADD,
235 TILEGX_OPC_STNT4,
236 TILEGX_OPC_STNT4_ADD,
237 TILEGX_OPC_STNT_ADD,
238 TILEGX_OPC_SUB,
239 TILEGX_OPC_SUBX,
240 TILEGX_OPC_SUBXSC,
241 TILEGX_OPC_SWINT0,
242 TILEGX_OPC_SWINT1,
243 TILEGX_OPC_SWINT2,
244 TILEGX_OPC_SWINT3,
245 TILEGX_OPC_TBLIDXB0,
246 TILEGX_OPC_TBLIDXB1,
247 TILEGX_OPC_TBLIDXB2,
248 TILEGX_OPC_TBLIDXB3,
249 TILEGX_OPC_V1ADD,
250 TILEGX_OPC_V1ADDI,
251 TILEGX_OPC_V1ADDUC,
252 TILEGX_OPC_V1ADIFFU,
253 TILEGX_OPC_V1AVGU,
254 TILEGX_OPC_V1CMPEQ,
255 TILEGX_OPC_V1CMPEQI,
256 TILEGX_OPC_V1CMPLES,
257 TILEGX_OPC_V1CMPLEU,
258 TILEGX_OPC_V1CMPLTS,
259 TILEGX_OPC_V1CMPLTSI,
260 TILEGX_OPC_V1CMPLTU,
261 TILEGX_OPC_V1CMPLTUI,
262 TILEGX_OPC_V1CMPNE,
263 TILEGX_OPC_V1DDOTPU,
264 TILEGX_OPC_V1DDOTPUA,
265 TILEGX_OPC_V1DDOTPUS,
266 TILEGX_OPC_V1DDOTPUSA,
267 TILEGX_OPC_V1DOTP,
268 TILEGX_OPC_V1DOTPA,
269 TILEGX_OPC_V1DOTPU,
270 TILEGX_OPC_V1DOTPUA,
271 TILEGX_OPC_V1DOTPUS,
272 TILEGX_OPC_V1DOTPUSA,
273 TILEGX_OPC_V1INT_H,
274 TILEGX_OPC_V1INT_L,
275 TILEGX_OPC_V1MAXU,
276 TILEGX_OPC_V1MAXUI,
277 TILEGX_OPC_V1MINU,
278 TILEGX_OPC_V1MINUI,
279 TILEGX_OPC_V1MNZ,
280 TILEGX_OPC_V1MULTU,
281 TILEGX_OPC_V1MULU,
282 TILEGX_OPC_V1MULUS,
283 TILEGX_OPC_V1MZ,
284 TILEGX_OPC_V1SADAU,
285 TILEGX_OPC_V1SADU,
286 TILEGX_OPC_V1SHL,
287 TILEGX_OPC_V1SHLI,
288 TILEGX_OPC_V1SHRS,
289 TILEGX_OPC_V1SHRSI,
290 TILEGX_OPC_V1SHRU,
291 TILEGX_OPC_V1SHRUI,
292 TILEGX_OPC_V1SUB,
293 TILEGX_OPC_V1SUBUC,
294 TILEGX_OPC_V2ADD,
295 TILEGX_OPC_V2ADDI,
296 TILEGX_OPC_V2ADDSC,
297 TILEGX_OPC_V2ADIFFS,
298 TILEGX_OPC_V2AVGS,
299 TILEGX_OPC_V2CMPEQ,
300 TILEGX_OPC_V2CMPEQI,
301 TILEGX_OPC_V2CMPLES,
302 TILEGX_OPC_V2CMPLEU,
303 TILEGX_OPC_V2CMPLTS,
304 TILEGX_OPC_V2CMPLTSI,
305 TILEGX_OPC_V2CMPLTU,
306 TILEGX_OPC_V2CMPLTUI,
307 TILEGX_OPC_V2CMPNE,
308 TILEGX_OPC_V2DOTP,
309 TILEGX_OPC_V2DOTPA,
310 TILEGX_OPC_V2INT_H,
311 TILEGX_OPC_V2INT_L,
312 TILEGX_OPC_V2MAXS,
313 TILEGX_OPC_V2MAXSI,
314 TILEGX_OPC_V2MINS,
315 TILEGX_OPC_V2MINSI,
316 TILEGX_OPC_V2MNZ,
317 TILEGX_OPC_V2MULFSC,
318 TILEGX_OPC_V2MULS,
319 TILEGX_OPC_V2MULTS,
320 TILEGX_OPC_V2MZ,
321 TILEGX_OPC_V2PACKH,
322 TILEGX_OPC_V2PACKL,
323 TILEGX_OPC_V2PACKUC,
324 TILEGX_OPC_V2SADAS,
325 TILEGX_OPC_V2SADAU,
326 TILEGX_OPC_V2SADS,
327 TILEGX_OPC_V2SADU,
328 TILEGX_OPC_V2SHL,
329 TILEGX_OPC_V2SHLI,
330 TILEGX_OPC_V2SHLSC,
331 TILEGX_OPC_V2SHRS,
332 TILEGX_OPC_V2SHRSI,
333 TILEGX_OPC_V2SHRU,
334 TILEGX_OPC_V2SHRUI,
335 TILEGX_OPC_V2SUB,
336 TILEGX_OPC_V2SUBSC,
337 TILEGX_OPC_V4ADD,
338 TILEGX_OPC_V4ADDSC,
339 TILEGX_OPC_V4INT_H,
340 TILEGX_OPC_V4INT_L,
341 TILEGX_OPC_V4PACKSC,
342 TILEGX_OPC_V4SHL,
343 TILEGX_OPC_V4SHLSC,
344 TILEGX_OPC_V4SHRS,
345 TILEGX_OPC_V4SHRU,
346 TILEGX_OPC_V4SUB,
347 TILEGX_OPC_V4SUBSC,
348 TILEGX_OPC_WH64,
349 TILEGX_OPC_XOR,
350 TILEGX_OPC_XORI,
351 TILEGX_OPC_NONE
352} tilegx_mnemonic;
353
354/* 64-bit pattern for a { bpt ; nop } bundle. */
355#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
356
357
358#define TILE_ELF_MACHINE_CODE EM_TILE64
359
360#define TILE_ELF_NAME "elf32-tile64"
361
362
363static __inline unsigned int
364get_BFEnd_X0(tilegx_bundle_bits num)
365{
366 const unsigned int n = (unsigned int)num;
367 return (((n >> 12)) & 0x3f);
368}
369
370static __inline unsigned int
371get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
372{
373 const unsigned int n = (unsigned int)num;
374 return (((n >> 24)) & 0xf);
375}
376
377static __inline unsigned int
378get_BFStart_X0(tilegx_bundle_bits num)
379{
380 const unsigned int n = (unsigned int)num;
381 return (((n >> 18)) & 0x3f);
382}
383
384static __inline unsigned int
385get_BrOff_X1(tilegx_bundle_bits n)
386{
387 return (((unsigned int)(n >> 31)) & 0x0000003f) |
388 (((unsigned int)(n >> 37)) & 0x0001ffc0);
389}
390
391static __inline unsigned int
392get_BrType_X1(tilegx_bundle_bits n)
393{
394 return (((unsigned int)(n >> 54)) & 0x1f);
395}
396
397static __inline unsigned int
398get_Dest_Imm8_X1(tilegx_bundle_bits n)
399{
400 return (((unsigned int)(n >> 31)) & 0x0000003f) |
401 (((unsigned int)(n >> 43)) & 0x000000c0);
402}
403
404static __inline unsigned int
405get_Dest_X0(tilegx_bundle_bits num)
406{
407 const unsigned int n = (unsigned int)num;
408 return (((n >> 0)) & 0x3f);
409}
410
411static __inline unsigned int
412get_Dest_X1(tilegx_bundle_bits n)
413{
414 return (((unsigned int)(n >> 31)) & 0x3f);
415}
416
417static __inline unsigned int
418get_Dest_Y0(tilegx_bundle_bits num)
419{
420 const unsigned int n = (unsigned int)num;
421 return (((n >> 0)) & 0x3f);
422}
423
424static __inline unsigned int
425get_Dest_Y1(tilegx_bundle_bits n)
426{
427 return (((unsigned int)(n >> 31)) & 0x3f);
428}
429
430static __inline unsigned int
431get_Imm16_X0(tilegx_bundle_bits num)
432{
433 const unsigned int n = (unsigned int)num;
434 return (((n >> 12)) & 0xffff);
435}
436
437static __inline unsigned int
438get_Imm16_X1(tilegx_bundle_bits n)
439{
440 return (((unsigned int)(n >> 43)) & 0xffff);
441}
442
443static __inline unsigned int
444get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
445{
446 const unsigned int n = (unsigned int)num;
447 return (((n >> 20)) & 0xff);
448}
449
450static __inline unsigned int
451get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
452{
453 return (((unsigned int)(n >> 51)) & 0xff);
454}
455
456static __inline unsigned int
457get_Imm8_X0(tilegx_bundle_bits num)
458{
459 const unsigned int n = (unsigned int)num;
460 return (((n >> 12)) & 0xff);
461}
462
463static __inline unsigned int
464get_Imm8_X1(tilegx_bundle_bits n)
465{
466 return (((unsigned int)(n >> 43)) & 0xff);
467}
468
469static __inline unsigned int
470get_Imm8_Y0(tilegx_bundle_bits num)
471{
472 const unsigned int n = (unsigned int)num;
473 return (((n >> 12)) & 0xff);
474}
475
476static __inline unsigned int
477get_Imm8_Y1(tilegx_bundle_bits n)
478{
479 return (((unsigned int)(n >> 43)) & 0xff);
480}
481
482static __inline unsigned int
483get_JumpOff_X1(tilegx_bundle_bits n)
484{
485 return (((unsigned int)(n >> 31)) & 0x7ffffff);
486}
487
488static __inline unsigned int
489get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
490{
491 return (((unsigned int)(n >> 58)) & 0x1);
492}
493
494static __inline unsigned int
495get_MF_Imm14_X1(tilegx_bundle_bits n)
496{
497 return (((unsigned int)(n >> 37)) & 0x3fff);
498}
499
500static __inline unsigned int
501get_MT_Imm14_X1(tilegx_bundle_bits n)
502{
503 return (((unsigned int)(n >> 31)) & 0x0000003f) |
504 (((unsigned int)(n >> 37)) & 0x00003fc0);
505}
506
507static __inline unsigned int
508get_Mode(tilegx_bundle_bits n)
509{
510 return (((unsigned int)(n >> 62)) & 0x3);
511}
512
513static __inline unsigned int
514get_Opcode_X0(tilegx_bundle_bits num)
515{
516 const unsigned int n = (unsigned int)num;
517 return (((n >> 28)) & 0x7);
518}
519
520static __inline unsigned int
521get_Opcode_X1(tilegx_bundle_bits n)
522{
523 return (((unsigned int)(n >> 59)) & 0x7);
524}
525
526static __inline unsigned int
527get_Opcode_Y0(tilegx_bundle_bits num)
528{
529 const unsigned int n = (unsigned int)num;
530 return (((n >> 27)) & 0xf);
531}
532
533static __inline unsigned int
534get_Opcode_Y1(tilegx_bundle_bits n)
535{
536 return (((unsigned int)(n >> 58)) & 0xf);
537}
538
539static __inline unsigned int
540get_Opcode_Y2(tilegx_bundle_bits n)
541{
542 return (((n >> 26)) & 0x00000001) |
543 (((unsigned int)(n >> 56)) & 0x00000002);
544}
545
546static __inline unsigned int
547get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
548{
549 const unsigned int n = (unsigned int)num;
550 return (((n >> 18)) & 0x3ff);
551}
552
553static __inline unsigned int
554get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
555{
556 return (((unsigned int)(n >> 49)) & 0x3ff);
557}
558
559static __inline unsigned int
560get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
561{
562 const unsigned int n = (unsigned int)num;
563 return (((n >> 18)) & 0x3);
564}
565
566static __inline unsigned int
567get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
568{
569 return (((unsigned int)(n >> 49)) & 0x3);
570}
571
572static __inline unsigned int
573get_ShAmt_X0(tilegx_bundle_bits num)
574{
575 const unsigned int n = (unsigned int)num;
576 return (((n >> 12)) & 0x3f);
577}
578
579static __inline unsigned int
580get_ShAmt_X1(tilegx_bundle_bits n)
581{
582 return (((unsigned int)(n >> 43)) & 0x3f);
583}
584
585static __inline unsigned int
586get_ShAmt_Y0(tilegx_bundle_bits num)
587{
588 const unsigned int n = (unsigned int)num;
589 return (((n >> 12)) & 0x3f);
590}
591
592static __inline unsigned int
593get_ShAmt_Y1(tilegx_bundle_bits n)
594{
595 return (((unsigned int)(n >> 43)) & 0x3f);
596}
597
598static __inline unsigned int
599get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
600{
601 const unsigned int n = (unsigned int)num;
602 return (((n >> 18)) & 0x3ff);
603}
604
605static __inline unsigned int
606get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
607{
608 return (((unsigned int)(n >> 49)) & 0x3ff);
609}
610
611static __inline unsigned int
612get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
613{
614 const unsigned int n = (unsigned int)num;
615 return (((n >> 18)) & 0x3);
616}
617
618static __inline unsigned int
619get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
620{
621 return (((unsigned int)(n >> 49)) & 0x3);
622}
623
624static __inline unsigned int
625get_SrcA_X0(tilegx_bundle_bits num)
626{
627 const unsigned int n = (unsigned int)num;
628 return (((n >> 6)) & 0x3f);
629}
630
631static __inline unsigned int
632get_SrcA_X1(tilegx_bundle_bits n)
633{
634 return (((unsigned int)(n >> 37)) & 0x3f);
635}
636
637static __inline unsigned int
638get_SrcA_Y0(tilegx_bundle_bits num)
639{
640 const unsigned int n = (unsigned int)num;
641 return (((n >> 6)) & 0x3f);
642}
643
644static __inline unsigned int
645get_SrcA_Y1(tilegx_bundle_bits n)
646{
647 return (((unsigned int)(n >> 37)) & 0x3f);
648}
649
650static __inline unsigned int
651get_SrcA_Y2(tilegx_bundle_bits num)
652{
653 const unsigned int n = (unsigned int)num;
654 return (((n >> 20)) & 0x3f);
655}
656
657static __inline unsigned int
658get_SrcBDest_Y2(tilegx_bundle_bits n)
659{
660 return (((unsigned int)(n >> 51)) & 0x3f);
661}
662
663static __inline unsigned int
664get_SrcB_X0(tilegx_bundle_bits num)
665{
666 const unsigned int n = (unsigned int)num;
667 return (((n >> 12)) & 0x3f);
668}
669
670static __inline unsigned int
671get_SrcB_X1(tilegx_bundle_bits n)
672{
673 return (((unsigned int)(n >> 43)) & 0x3f);
674}
675
676static __inline unsigned int
677get_SrcB_Y0(tilegx_bundle_bits num)
678{
679 const unsigned int n = (unsigned int)num;
680 return (((n >> 12)) & 0x3f);
681}
682
683static __inline unsigned int
684get_SrcB_Y1(tilegx_bundle_bits n)
685{
686 return (((unsigned int)(n >> 43)) & 0x3f);
687}
688
689static __inline unsigned int
690get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
691{
692 const unsigned int n = (unsigned int)num;
693 return (((n >> 12)) & 0x3f);
694}
695
696static __inline unsigned int
697get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
698{
699 return (((unsigned int)(n >> 43)) & 0x3f);
700}
701
702static __inline unsigned int
703get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
704{
705 const unsigned int n = (unsigned int)num;
706 return (((n >> 12)) & 0x3f);
707}
708
709static __inline unsigned int
710get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
711{
712 return (((unsigned int)(n >> 43)) & 0x3f);
713}
714
715
716static __inline int
717sign_extend(int n, int num_bits)
718{
719 int shift = (int)(sizeof(int) * 8 - num_bits);
720 return (n << shift) >> shift;
721}
722
723
724
725static __inline tilegx_bundle_bits
726create_BFEnd_X0(int num)
727{
728 const unsigned int n = (unsigned int)num;
729 return ((n & 0x3f) << 12);
730}
731
732static __inline tilegx_bundle_bits
733create_BFOpcodeExtension_X0(int num)
734{
735 const unsigned int n = (unsigned int)num;
736 return ((n & 0xf) << 24);
737}
738
739static __inline tilegx_bundle_bits
740create_BFStart_X0(int num)
741{
742 const unsigned int n = (unsigned int)num;
743 return ((n & 0x3f) << 18);
744}
745
746static __inline tilegx_bundle_bits
747create_BrOff_X1(int num)
748{
749 const unsigned int n = (unsigned int)num;
750 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
751 (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
752}
753
754static __inline tilegx_bundle_bits
755create_BrType_X1(int num)
756{
757 const unsigned int n = (unsigned int)num;
758 return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
759}
760
761static __inline tilegx_bundle_bits
762create_Dest_Imm8_X1(int num)
763{
764 const unsigned int n = (unsigned int)num;
765 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
766 (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
767}
768
769static __inline tilegx_bundle_bits
770create_Dest_X0(int num)
771{
772 const unsigned int n = (unsigned int)num;
773 return ((n & 0x3f) << 0);
774}
775
776static __inline tilegx_bundle_bits
777create_Dest_X1(int num)
778{
779 const unsigned int n = (unsigned int)num;
780 return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
781}
782
783static __inline tilegx_bundle_bits
784create_Dest_Y0(int num)
785{
786 const unsigned int n = (unsigned int)num;
787 return ((n & 0x3f) << 0);
788}
789
790static __inline tilegx_bundle_bits
791create_Dest_Y1(int num)
792{
793 const unsigned int n = (unsigned int)num;
794 return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
795}
796
797static __inline tilegx_bundle_bits
798create_Imm16_X0(int num)
799{
800 const unsigned int n = (unsigned int)num;
801 return ((n & 0xffff) << 12);
802}
803
804static __inline tilegx_bundle_bits
805create_Imm16_X1(int num)
806{
807 const unsigned int n = (unsigned int)num;
808 return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
809}
810
811static __inline tilegx_bundle_bits
812create_Imm8OpcodeExtension_X0(int num)
813{
814 const unsigned int n = (unsigned int)num;
815 return ((n & 0xff) << 20);
816}
817
818static __inline tilegx_bundle_bits
819create_Imm8OpcodeExtension_X1(int num)
820{
821 const unsigned int n = (unsigned int)num;
822 return (((tilegx_bundle_bits)(n & 0xff)) << 51);
823}
824
825static __inline tilegx_bundle_bits
826create_Imm8_X0(int num)
827{
828 const unsigned int n = (unsigned int)num;
829 return ((n & 0xff) << 12);
830}
831
832static __inline tilegx_bundle_bits
833create_Imm8_X1(int num)
834{
835 const unsigned int n = (unsigned int)num;
836 return (((tilegx_bundle_bits)(n & 0xff)) << 43);
837}
838
839static __inline tilegx_bundle_bits
840create_Imm8_Y0(int num)
841{
842 const unsigned int n = (unsigned int)num;
843 return ((n & 0xff) << 12);
844}
845
846static __inline tilegx_bundle_bits
847create_Imm8_Y1(int num)
848{
849 const unsigned int n = (unsigned int)num;
850 return (((tilegx_bundle_bits)(n & 0xff)) << 43);
851}
852
853static __inline tilegx_bundle_bits
854create_JumpOff_X1(int num)
855{
856 const unsigned int n = (unsigned int)num;
857 return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
858}
859
860static __inline tilegx_bundle_bits
861create_JumpOpcodeExtension_X1(int num)
862{
863 const unsigned int n = (unsigned int)num;
864 return (((tilegx_bundle_bits)(n & 0x1)) << 58);
865}
866
867static __inline tilegx_bundle_bits
868create_MF_Imm14_X1(int num)
869{
870 const unsigned int n = (unsigned int)num;
871 return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
872}
873
874static __inline tilegx_bundle_bits
875create_MT_Imm14_X1(int num)
876{
877 const unsigned int n = (unsigned int)num;
878 return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
879 (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
880}
881
882static __inline tilegx_bundle_bits
883create_Mode(int num)
884{
885 const unsigned int n = (unsigned int)num;
886 return (((tilegx_bundle_bits)(n & 0x3)) << 62);
887}
888
889static __inline tilegx_bundle_bits
890create_Opcode_X0(int num)
891{
892 const unsigned int n = (unsigned int)num;
893 return ((n & 0x7) << 28);
894}
895
896static __inline tilegx_bundle_bits
897create_Opcode_X1(int num)
898{
899 const unsigned int n = (unsigned int)num;
900 return (((tilegx_bundle_bits)(n & 0x7)) << 59);
901}
902
903static __inline tilegx_bundle_bits
904create_Opcode_Y0(int num)
905{
906 const unsigned int n = (unsigned int)num;
907 return ((n & 0xf) << 27);
908}
909
910static __inline tilegx_bundle_bits
911create_Opcode_Y1(int num)
912{
913 const unsigned int n = (unsigned int)num;
914 return (((tilegx_bundle_bits)(n & 0xf)) << 58);
915}
916
917static __inline tilegx_bundle_bits
918create_Opcode_Y2(int num)
919{
920 const unsigned int n = (unsigned int)num;
921 return ((n & 0x00000001) << 26) |
922 (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
923}
924
925static __inline tilegx_bundle_bits
926create_RRROpcodeExtension_X0(int num)
927{
928 const unsigned int n = (unsigned int)num;
929 return ((n & 0x3ff) << 18);
930}
931
932static __inline tilegx_bundle_bits
933create_RRROpcodeExtension_X1(int num)
934{
935 const unsigned int n = (unsigned int)num;
936 return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
937}
938
939static __inline tilegx_bundle_bits
940create_RRROpcodeExtension_Y0(int num)
941{
942 const unsigned int n = (unsigned int)num;
943 return ((n & 0x3) << 18);
944}
945
946static __inline tilegx_bundle_bits
947create_RRROpcodeExtension_Y1(int num)
948{
949 const unsigned int n = (unsigned int)num;
950 return (((tilegx_bundle_bits)(n & 0x3)) << 49);
951}
952
953static __inline tilegx_bundle_bits
954create_ShAmt_X0(int num)
955{
956 const unsigned int n = (unsigned int)num;
957 return ((n & 0x3f) << 12);
958}
959
960static __inline tilegx_bundle_bits
961create_ShAmt_X1(int num)
962{
963 const unsigned int n = (unsigned int)num;
964 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
965}
966
967static __inline tilegx_bundle_bits
968create_ShAmt_Y0(int num)
969{
970 const unsigned int n = (unsigned int)num;
971 return ((n & 0x3f) << 12);
972}
973
974static __inline tilegx_bundle_bits
975create_ShAmt_Y1(int num)
976{
977 const unsigned int n = (unsigned int)num;
978 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
979}
980
981static __inline tilegx_bundle_bits
982create_ShiftOpcodeExtension_X0(int num)
983{
984 const unsigned int n = (unsigned int)num;
985 return ((n & 0x3ff) << 18);
986}
987
988static __inline tilegx_bundle_bits
989create_ShiftOpcodeExtension_X1(int num)
990{
991 const unsigned int n = (unsigned int)num;
992 return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
993}
994
995static __inline tilegx_bundle_bits
996create_ShiftOpcodeExtension_Y0(int num)
997{
998 const unsigned int n = (unsigned int)num;
999 return ((n & 0x3) << 18);
1000}
1001
1002static __inline tilegx_bundle_bits
1003create_ShiftOpcodeExtension_Y1(int num)
1004{
1005 const unsigned int n = (unsigned int)num;
1006 return (((tilegx_bundle_bits)(n & 0x3)) << 49);
1007}
1008
1009static __inline tilegx_bundle_bits
1010create_SrcA_X0(int num)
1011{
1012 const unsigned int n = (unsigned int)num;
1013 return ((n & 0x3f) << 6);
1014}
1015
1016static __inline tilegx_bundle_bits
1017create_SrcA_X1(int num)
1018{
1019 const unsigned int n = (unsigned int)num;
1020 return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
1021}
1022
1023static __inline tilegx_bundle_bits
1024create_SrcA_Y0(int num)
1025{
1026 const unsigned int n = (unsigned int)num;
1027 return ((n & 0x3f) << 6);
1028}
1029
1030static __inline tilegx_bundle_bits
1031create_SrcA_Y1(int num)
1032{
1033 const unsigned int n = (unsigned int)num;
1034 return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
1035}
1036
1037static __inline tilegx_bundle_bits
1038create_SrcA_Y2(int num)
1039{
1040 const unsigned int n = (unsigned int)num;
1041 return ((n & 0x3f) << 20);
1042}
1043
1044static __inline tilegx_bundle_bits
1045create_SrcBDest_Y2(int num)
1046{
1047 const unsigned int n = (unsigned int)num;
1048 return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
1049}
1050
1051static __inline tilegx_bundle_bits
1052create_SrcB_X0(int num)
1053{
1054 const unsigned int n = (unsigned int)num;
1055 return ((n & 0x3f) << 12);
1056}
1057
1058static __inline tilegx_bundle_bits
1059create_SrcB_X1(int num)
1060{
1061 const unsigned int n = (unsigned int)num;
1062 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
1063}
1064
1065static __inline tilegx_bundle_bits
1066create_SrcB_Y0(int num)
1067{
1068 const unsigned int n = (unsigned int)num;
1069 return ((n & 0x3f) << 12);
1070}
1071
1072static __inline tilegx_bundle_bits
1073create_SrcB_Y1(int num)
1074{
1075 const unsigned int n = (unsigned int)num;
1076 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
1077}
1078
1079static __inline tilegx_bundle_bits
1080create_UnaryOpcodeExtension_X0(int num)
1081{
1082 const unsigned int n = (unsigned int)num;
1083 return ((n & 0x3f) << 12);
1084}
1085
1086static __inline tilegx_bundle_bits
1087create_UnaryOpcodeExtension_X1(int num)
1088{
1089 const unsigned int n = (unsigned int)num;
1090 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
1091}
1092
1093static __inline tilegx_bundle_bits
1094create_UnaryOpcodeExtension_Y0(int num)
1095{
1096 const unsigned int n = (unsigned int)num;
1097 return ((n & 0x3f) << 12);
1098}
1099
1100static __inline tilegx_bundle_bits
1101create_UnaryOpcodeExtension_Y1(int num)
1102{
1103 const unsigned int n = (unsigned int)num;
1104 return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
1105}
1106
1107
1108typedef enum
1109{
1110 TILEGX_PIPELINE_X0,
1111 TILEGX_PIPELINE_X1,
1112 TILEGX_PIPELINE_Y0,
1113 TILEGX_PIPELINE_Y1,
1114 TILEGX_PIPELINE_Y2,
1115} tilegx_pipeline;
1116
1117#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
1118
1119typedef enum
1120{
1121 TILEGX_OP_TYPE_REGISTER,
1122 TILEGX_OP_TYPE_IMMEDIATE,
1123 TILEGX_OP_TYPE_ADDRESS,
1124 TILEGX_OP_TYPE_SPR
1125} tilegx_operand_type;
1126
1127/* These are the bits that determine if a bundle is in the X encoding. */
1128#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
1129
1130enum
1131{
1132 /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
1133 TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
1134
1135 /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
1136 TILEGX_NUM_PIPELINE_ENCODINGS = 5,
1137
1138 /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
1139 TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
1140
1141 /* Instructions take this many bytes. */
1142 TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
1143
1144 /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
1145 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
1146
1147 /* Bundles should be aligned modulo this number of bytes. */
1148 TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
1149 (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
1150
1151 /* Number of registers (some are magic, such as network I/O). */
1152 TILEGX_NUM_REGISTERS = 64,
1153};
1154
1155
1156struct tilegx_operand
1157{
1158 /* Is this operand a register, immediate or address? */
1159 tilegx_operand_type type;
1160
1161 /* The default relocation type for this operand. */
1162 signed int default_reloc : 16;
1163
1164 /* How many bits is this value? (used for range checking) */
1165 unsigned int num_bits : 5;
1166
1167 /* Is the value signed? (used for range checking) */
1168 unsigned int is_signed : 1;
1169
1170 /* Is this operand a source register? */
1171 unsigned int is_src_reg : 1;
1172
1173 /* Is this operand written? (i.e. is it a destination register) */
1174 unsigned int is_dest_reg : 1;
1175
1176 /* Is this operand PC-relative? */
1177 unsigned int is_pc_relative : 1;
1178
1179 /* By how many bits do we right shift the value before inserting? */
1180 unsigned int rightshift : 2;
1181
1182 /* Return the bits for this operand to be ORed into an existing bundle. */
1183 tilegx_bundle_bits (*insert) (int op);
1184
1185 /* Extract this operand and return it. */
1186 unsigned int (*extract) (tilegx_bundle_bits bundle);
1187};
1188
1189
1190extern const struct tilegx_operand tilegx_operands[];
1191
1192/* One finite-state machine per pipe for rapid instruction decoding. */
1193extern const unsigned short * const
1194tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS];
1195
1196
1197struct tilegx_opcode
1198{
1199 /* The opcode mnemonic, e.g. "add" */
1200 const char *name;
1201
1202 /* The enum value for this mnemonic. */
1203 tilegx_mnemonic mnemonic;
1204
1205 /* A bit mask of which of the five pipes this instruction
1206 is compatible with:
1207 X0 0x01
1208 X1 0x02
1209 Y0 0x04
1210 Y1 0x08
1211 Y2 0x10 */
1212 unsigned char pipes;
1213
1214 /* How many operands are there? */
1215 unsigned char num_operands;
1216
1217 /* Which register does this write implicitly, or TREG_ZERO if none? */
1218 unsigned char implicitly_written_register;
1219
1220 /* Can this be bundled with other instructions (almost always true). */
1221 unsigned char can_bundle;
1222
1223 /* The description of the operands. Each of these is an
1224 * index into the tilegx_operands[] table. */
1225 unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
1226
1227};
1228
1229extern const struct tilegx_opcode tilegx_opcodes[];
1230
1231/* Used for non-textual disassembly into structs. */
1232struct tilegx_decoded_instruction
1233{
1234 const struct tilegx_opcode *opcode;
1235 const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
1236 long long operand_values[TILEGX_MAX_OPERANDS];
1237};
1238
1239
1240/* Disassemble a bundle into a struct for machine processing. */
1241extern int parse_insn_tilegx(tilegx_bundle_bits bits,
1242 unsigned long long pc,
1243 struct tilegx_decoded_instruction
1244 decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]);
1245
1246
1247
1248#endif /* opcode_tilegx_h */
diff --git a/arch/tile/include/asm/opcode_constants_32.h b/arch/tile/include/asm/opcode_constants_32.h
deleted file mode 100644
index 227d033b180c..000000000000
--- a/arch/tile/include/asm/opcode_constants_32.h
+++ /dev/null
@@ -1,480 +0,0 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/* This file is machine-generated; DO NOT EDIT! */
16
17
18#ifndef _TILE_OPCODE_CONSTANTS_H
19#define _TILE_OPCODE_CONSTANTS_H
20enum
21{
22 ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
23 ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
24 ADDB_SPECIAL_0_OPCODE_X0 = 1,
25 ADDB_SPECIAL_0_OPCODE_X1 = 1,
26 ADDHS_SPECIAL_0_OPCODE_X0 = 99,
27 ADDHS_SPECIAL_0_OPCODE_X1 = 69,
28 ADDH_SPECIAL_0_OPCODE_X0 = 2,
29 ADDH_SPECIAL_0_OPCODE_X1 = 2,
30 ADDIB_IMM_0_OPCODE_X0 = 1,
31 ADDIB_IMM_0_OPCODE_X1 = 1,
32 ADDIH_IMM_0_OPCODE_X0 = 2,
33 ADDIH_IMM_0_OPCODE_X1 = 2,
34 ADDI_IMM_0_OPCODE_X0 = 3,
35 ADDI_IMM_0_OPCODE_X1 = 3,
36 ADDI_IMM_1_OPCODE_SN = 1,
37 ADDI_OPCODE_Y0 = 9,
38 ADDI_OPCODE_Y1 = 7,
39 ADDLIS_OPCODE_X0 = 1,
40 ADDLIS_OPCODE_X1 = 2,
41 ADDLI_OPCODE_X0 = 2,
42 ADDLI_OPCODE_X1 = 3,
43 ADDS_SPECIAL_0_OPCODE_X0 = 96,
44 ADDS_SPECIAL_0_OPCODE_X1 = 66,
45 ADD_SPECIAL_0_OPCODE_X0 = 3,
46 ADD_SPECIAL_0_OPCODE_X1 = 3,
47 ADD_SPECIAL_0_OPCODE_Y0 = 0,
48 ADD_SPECIAL_0_OPCODE_Y1 = 0,
49 ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
50 ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
51 ANDI_IMM_0_OPCODE_X0 = 1,
52 ANDI_IMM_0_OPCODE_X1 = 4,
53 ANDI_OPCODE_Y0 = 10,
54 ANDI_OPCODE_Y1 = 8,
55 AND_SPECIAL_0_OPCODE_X0 = 6,
56 AND_SPECIAL_0_OPCODE_X1 = 4,
57 AND_SPECIAL_2_OPCODE_Y0 = 0,
58 AND_SPECIAL_2_OPCODE_Y1 = 0,
59 AULI_OPCODE_X0 = 3,
60 AULI_OPCODE_X1 = 4,
61 AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
62 AVGH_SPECIAL_0_OPCODE_X0 = 8,
63 BBNST_BRANCH_OPCODE_X1 = 15,
64 BBNS_BRANCH_OPCODE_X1 = 14,
65 BBNS_OPCODE_SN = 63,
66 BBST_BRANCH_OPCODE_X1 = 13,
67 BBS_BRANCH_OPCODE_X1 = 12,
68 BBS_OPCODE_SN = 62,
69 BGEZT_BRANCH_OPCODE_X1 = 7,
70 BGEZ_BRANCH_OPCODE_X1 = 6,
71 BGEZ_OPCODE_SN = 61,
72 BGZT_BRANCH_OPCODE_X1 = 5,
73 BGZ_BRANCH_OPCODE_X1 = 4,
74 BGZ_OPCODE_SN = 58,
75 BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
76 BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
77 BLEZT_BRANCH_OPCODE_X1 = 11,
78 BLEZ_BRANCH_OPCODE_X1 = 10,
79 BLEZ_OPCODE_SN = 59,
80 BLZT_BRANCH_OPCODE_X1 = 9,
81 BLZ_BRANCH_OPCODE_X1 = 8,
82 BLZ_OPCODE_SN = 60,
83 BNZT_BRANCH_OPCODE_X1 = 3,
84 BNZ_BRANCH_OPCODE_X1 = 2,
85 BNZ_OPCODE_SN = 57,
86 BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
87 BRANCH_OPCODE_X1 = 5,
88 BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
89 BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
90 BZT_BRANCH_OPCODE_X1 = 1,
91 BZ_BRANCH_OPCODE_X1 = 0,
92 BZ_OPCODE_SN = 56,
93 CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
94 CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
95 CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
96 CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
97 CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
98 CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
99 DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
100 DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
101 DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
102 FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
103 FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
104 FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
105 FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
106 FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
107 FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
108 FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
109 HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
110 ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
111 ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
112 ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
113 IMM_0_OPCODE_SN = 0,
114 IMM_0_OPCODE_X0 = 4,
115 IMM_0_OPCODE_X1 = 6,
116 IMM_1_OPCODE_SN = 1,
117 IMM_OPCODE_0_X0 = 5,
118 INTHB_SPECIAL_0_OPCODE_X0 = 11,
119 INTHB_SPECIAL_0_OPCODE_X1 = 5,
120 INTHH_SPECIAL_0_OPCODE_X0 = 12,
121 INTHH_SPECIAL_0_OPCODE_X1 = 6,
122 INTLB_SPECIAL_0_OPCODE_X0 = 13,
123 INTLB_SPECIAL_0_OPCODE_X1 = 7,
124 INTLH_SPECIAL_0_OPCODE_X0 = 14,
125 INTLH_SPECIAL_0_OPCODE_X1 = 8,
126 INV_UN_0_SHUN_0_OPCODE_X1 = 8,
127 IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
128 JALB_OPCODE_X1 = 13,
129 JALF_OPCODE_X1 = 12,
130 JALRP_SPECIAL_0_OPCODE_X1 = 9,
131 JALRR_IMM_1_OPCODE_SN = 3,
132 JALR_RR_IMM_0_OPCODE_SN = 5,
133 JALR_SPECIAL_0_OPCODE_X1 = 10,
134 JB_OPCODE_X1 = 11,
135 JF_OPCODE_X1 = 10,
136 JRP_SPECIAL_0_OPCODE_X1 = 11,
137 JRR_IMM_1_OPCODE_SN = 2,
138 JR_RR_IMM_0_OPCODE_SN = 4,
139 JR_SPECIAL_0_OPCODE_X1 = 12,
140 LBADD_IMM_0_OPCODE_X1 = 22,
141 LBADD_U_IMM_0_OPCODE_X1 = 23,
142 LB_OPCODE_Y2 = 0,
143 LB_UN_0_SHUN_0_OPCODE_X1 = 10,
144 LB_U_OPCODE_Y2 = 1,
145 LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
146 LHADD_IMM_0_OPCODE_X1 = 24,
147 LHADD_U_IMM_0_OPCODE_X1 = 25,
148 LH_OPCODE_Y2 = 2,
149 LH_UN_0_SHUN_0_OPCODE_X1 = 12,
150 LH_U_OPCODE_Y2 = 3,
151 LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
152 LNK_SPECIAL_0_OPCODE_X1 = 13,
153 LWADD_IMM_0_OPCODE_X1 = 26,
154 LWADD_NA_IMM_0_OPCODE_X1 = 27,
155 LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
156 LW_OPCODE_Y2 = 4,
157 LW_UN_0_SHUN_0_OPCODE_X1 = 14,
158 MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
159 MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
160 MAXH_SPECIAL_0_OPCODE_X0 = 16,
161 MAXH_SPECIAL_0_OPCODE_X1 = 15,
162 MAXIB_U_IMM_0_OPCODE_X0 = 4,
163 MAXIB_U_IMM_0_OPCODE_X1 = 5,
164 MAXIH_IMM_0_OPCODE_X0 = 5,
165 MAXIH_IMM_0_OPCODE_X1 = 6,
166 MFSPR_IMM_0_OPCODE_X1 = 7,
167 MF_UN_0_SHUN_0_OPCODE_X1 = 15,
168 MINB_U_SPECIAL_0_OPCODE_X0 = 17,
169 MINB_U_SPECIAL_0_OPCODE_X1 = 16,
170 MINH_SPECIAL_0_OPCODE_X0 = 18,
171 MINH_SPECIAL_0_OPCODE_X1 = 17,
172 MINIB_U_IMM_0_OPCODE_X0 = 6,
173 MINIB_U_IMM_0_OPCODE_X1 = 8,
174 MINIH_IMM_0_OPCODE_X0 = 7,
175 MINIH_IMM_0_OPCODE_X1 = 9,
176 MM_OPCODE_X0 = 6,
177 MM_OPCODE_X1 = 7,
178 MNZB_SPECIAL_0_OPCODE_X0 = 19,
179 MNZB_SPECIAL_0_OPCODE_X1 = 18,
180 MNZH_SPECIAL_0_OPCODE_X0 = 20,
181 MNZH_SPECIAL_0_OPCODE_X1 = 19,
182 MNZ_SPECIAL_0_OPCODE_X0 = 21,
183 MNZ_SPECIAL_0_OPCODE_X1 = 20,
184 MNZ_SPECIAL_1_OPCODE_Y0 = 0,
185 MNZ_SPECIAL_1_OPCODE_Y1 = 1,
186 MOVEI_IMM_1_OPCODE_SN = 0,
187 MOVE_RR_IMM_0_OPCODE_SN = 8,
188 MTSPR_IMM_0_OPCODE_X1 = 10,
189 MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
190 MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
191 MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
192 MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
193 MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
194 MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
195 MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
196 MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
197 MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
198 MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
199 MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
200 MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
201 MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
202 MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
203 MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
204 MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
205 MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
206 MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
207 MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
208 MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
209 MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
210 MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
211 MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
212 MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
213 MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
214 MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
215 MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
216 MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
217 MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
218 MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
219 MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
220 MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
221 MVNZ_SPECIAL_0_OPCODE_X0 = 45,
222 MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
223 MVZ_SPECIAL_0_OPCODE_X0 = 46,
224 MVZ_SPECIAL_1_OPCODE_Y0 = 2,
225 MZB_SPECIAL_0_OPCODE_X0 = 47,
226 MZB_SPECIAL_0_OPCODE_X1 = 21,
227 MZH_SPECIAL_0_OPCODE_X0 = 48,
228 MZH_SPECIAL_0_OPCODE_X1 = 22,
229 MZ_SPECIAL_0_OPCODE_X0 = 49,
230 MZ_SPECIAL_0_OPCODE_X1 = 23,
231 MZ_SPECIAL_1_OPCODE_Y0 = 3,
232 MZ_SPECIAL_1_OPCODE_Y1 = 2,
233 NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
234 NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
235 NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
236 NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
237 NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
238 NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
239 NOREG_RR_IMM_0_OPCODE_SN = 0,
240 NOR_SPECIAL_0_OPCODE_X0 = 50,
241 NOR_SPECIAL_0_OPCODE_X1 = 24,
242 NOR_SPECIAL_2_OPCODE_Y0 = 1,
243 NOR_SPECIAL_2_OPCODE_Y1 = 1,
244 ORI_IMM_0_OPCODE_X0 = 8,
245 ORI_IMM_0_OPCODE_X1 = 11,
246 ORI_OPCODE_Y0 = 11,
247 ORI_OPCODE_Y1 = 9,
248 OR_SPECIAL_0_OPCODE_X0 = 51,
249 OR_SPECIAL_0_OPCODE_X1 = 25,
250 OR_SPECIAL_2_OPCODE_Y0 = 2,
251 OR_SPECIAL_2_OPCODE_Y1 = 2,
252 PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
253 PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
254 PACKHB_SPECIAL_0_OPCODE_X0 = 52,
255 PACKHB_SPECIAL_0_OPCODE_X1 = 26,
256 PACKHS_SPECIAL_0_OPCODE_X0 = 102,
257 PACKHS_SPECIAL_0_OPCODE_X1 = 72,
258 PACKLB_SPECIAL_0_OPCODE_X0 = 53,
259 PACKLB_SPECIAL_0_OPCODE_X1 = 27,
260 PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
261 PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
262 RLI_SHUN_0_OPCODE_X0 = 1,
263 RLI_SHUN_0_OPCODE_X1 = 1,
264 RLI_SHUN_0_OPCODE_Y0 = 1,
265 RLI_SHUN_0_OPCODE_Y1 = 1,
266 RL_SPECIAL_0_OPCODE_X0 = 54,
267 RL_SPECIAL_0_OPCODE_X1 = 28,
268 RL_SPECIAL_3_OPCODE_Y0 = 0,
269 RL_SPECIAL_3_OPCODE_Y1 = 0,
270 RR_IMM_0_OPCODE_SN = 0,
271 S1A_SPECIAL_0_OPCODE_X0 = 55,
272 S1A_SPECIAL_0_OPCODE_X1 = 29,
273 S1A_SPECIAL_0_OPCODE_Y0 = 1,
274 S1A_SPECIAL_0_OPCODE_Y1 = 1,
275 S2A_SPECIAL_0_OPCODE_X0 = 56,
276 S2A_SPECIAL_0_OPCODE_X1 = 30,
277 S2A_SPECIAL_0_OPCODE_Y0 = 2,
278 S2A_SPECIAL_0_OPCODE_Y1 = 2,
279 S3A_SPECIAL_0_OPCODE_X0 = 57,
280 S3A_SPECIAL_0_OPCODE_X1 = 31,
281 S3A_SPECIAL_5_OPCODE_Y0 = 1,
282 S3A_SPECIAL_5_OPCODE_Y1 = 1,
283 SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
284 SADAH_SPECIAL_0_OPCODE_X0 = 59,
285 SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
286 SADB_U_SPECIAL_0_OPCODE_X0 = 61,
287 SADH_SPECIAL_0_OPCODE_X0 = 62,
288 SADH_U_SPECIAL_0_OPCODE_X0 = 63,
289 SBADD_IMM_0_OPCODE_X1 = 28,
290 SB_OPCODE_Y2 = 5,
291 SB_SPECIAL_0_OPCODE_X1 = 32,
292 SEQB_SPECIAL_0_OPCODE_X0 = 64,
293 SEQB_SPECIAL_0_OPCODE_X1 = 33,
294 SEQH_SPECIAL_0_OPCODE_X0 = 65,
295 SEQH_SPECIAL_0_OPCODE_X1 = 34,
296 SEQIB_IMM_0_OPCODE_X0 = 9,
297 SEQIB_IMM_0_OPCODE_X1 = 12,
298 SEQIH_IMM_0_OPCODE_X0 = 10,
299 SEQIH_IMM_0_OPCODE_X1 = 13,
300 SEQI_IMM_0_OPCODE_X0 = 11,
301 SEQI_IMM_0_OPCODE_X1 = 14,
302 SEQI_OPCODE_Y0 = 12,
303 SEQI_OPCODE_Y1 = 10,
304 SEQ_SPECIAL_0_OPCODE_X0 = 66,
305 SEQ_SPECIAL_0_OPCODE_X1 = 35,
306 SEQ_SPECIAL_5_OPCODE_Y0 = 2,
307 SEQ_SPECIAL_5_OPCODE_Y1 = 2,
308 SHADD_IMM_0_OPCODE_X1 = 29,
309 SHL8II_IMM_0_OPCODE_SN = 3,
310 SHLB_SPECIAL_0_OPCODE_X0 = 67,
311 SHLB_SPECIAL_0_OPCODE_X1 = 36,
312 SHLH_SPECIAL_0_OPCODE_X0 = 68,
313 SHLH_SPECIAL_0_OPCODE_X1 = 37,
314 SHLIB_SHUN_0_OPCODE_X0 = 2,
315 SHLIB_SHUN_0_OPCODE_X1 = 2,
316 SHLIH_SHUN_0_OPCODE_X0 = 3,
317 SHLIH_SHUN_0_OPCODE_X1 = 3,
318 SHLI_SHUN_0_OPCODE_X0 = 4,
319 SHLI_SHUN_0_OPCODE_X1 = 4,
320 SHLI_SHUN_0_OPCODE_Y0 = 2,
321 SHLI_SHUN_0_OPCODE_Y1 = 2,
322 SHL_SPECIAL_0_OPCODE_X0 = 69,
323 SHL_SPECIAL_0_OPCODE_X1 = 38,
324 SHL_SPECIAL_3_OPCODE_Y0 = 1,
325 SHL_SPECIAL_3_OPCODE_Y1 = 1,
326 SHR1_RR_IMM_0_OPCODE_SN = 9,
327 SHRB_SPECIAL_0_OPCODE_X0 = 70,
328 SHRB_SPECIAL_0_OPCODE_X1 = 39,
329 SHRH_SPECIAL_0_OPCODE_X0 = 71,
330 SHRH_SPECIAL_0_OPCODE_X1 = 40,
331 SHRIB_SHUN_0_OPCODE_X0 = 5,
332 SHRIB_SHUN_0_OPCODE_X1 = 5,
333 SHRIH_SHUN_0_OPCODE_X0 = 6,
334 SHRIH_SHUN_0_OPCODE_X1 = 6,
335 SHRI_SHUN_0_OPCODE_X0 = 7,
336 SHRI_SHUN_0_OPCODE_X1 = 7,
337 SHRI_SHUN_0_OPCODE_Y0 = 3,
338 SHRI_SHUN_0_OPCODE_Y1 = 3,
339 SHR_SPECIAL_0_OPCODE_X0 = 72,
340 SHR_SPECIAL_0_OPCODE_X1 = 41,
341 SHR_SPECIAL_3_OPCODE_Y0 = 2,
342 SHR_SPECIAL_3_OPCODE_Y1 = 2,
343 SHUN_0_OPCODE_X0 = 7,
344 SHUN_0_OPCODE_X1 = 8,
345 SHUN_0_OPCODE_Y0 = 13,
346 SHUN_0_OPCODE_Y1 = 11,
347 SH_OPCODE_Y2 = 6,
348 SH_SPECIAL_0_OPCODE_X1 = 42,
349 SLTB_SPECIAL_0_OPCODE_X0 = 73,
350 SLTB_SPECIAL_0_OPCODE_X1 = 43,
351 SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
352 SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
353 SLTEB_SPECIAL_0_OPCODE_X0 = 75,
354 SLTEB_SPECIAL_0_OPCODE_X1 = 45,
355 SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
356 SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
357 SLTEH_SPECIAL_0_OPCODE_X0 = 77,
358 SLTEH_SPECIAL_0_OPCODE_X1 = 47,
359 SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
360 SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
361 SLTE_SPECIAL_0_OPCODE_X0 = 79,
362 SLTE_SPECIAL_0_OPCODE_X1 = 49,
363 SLTE_SPECIAL_4_OPCODE_Y0 = 0,
364 SLTE_SPECIAL_4_OPCODE_Y1 = 0,
365 SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
366 SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
367 SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
368 SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
369 SLTH_SPECIAL_0_OPCODE_X0 = 81,
370 SLTH_SPECIAL_0_OPCODE_X1 = 51,
371 SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
372 SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
373 SLTIB_IMM_0_OPCODE_X0 = 12,
374 SLTIB_IMM_0_OPCODE_X1 = 15,
375 SLTIB_U_IMM_0_OPCODE_X0 = 13,
376 SLTIB_U_IMM_0_OPCODE_X1 = 16,
377 SLTIH_IMM_0_OPCODE_X0 = 14,
378 SLTIH_IMM_0_OPCODE_X1 = 17,
379 SLTIH_U_IMM_0_OPCODE_X0 = 15,
380 SLTIH_U_IMM_0_OPCODE_X1 = 18,
381 SLTI_IMM_0_OPCODE_X0 = 16,
382 SLTI_IMM_0_OPCODE_X1 = 19,
383 SLTI_OPCODE_Y0 = 14,
384 SLTI_OPCODE_Y1 = 12,
385 SLTI_U_IMM_0_OPCODE_X0 = 17,
386 SLTI_U_IMM_0_OPCODE_X1 = 20,
387 SLTI_U_OPCODE_Y0 = 15,
388 SLTI_U_OPCODE_Y1 = 13,
389 SLT_SPECIAL_0_OPCODE_X0 = 83,
390 SLT_SPECIAL_0_OPCODE_X1 = 53,
391 SLT_SPECIAL_4_OPCODE_Y0 = 2,
392 SLT_SPECIAL_4_OPCODE_Y1 = 2,
393 SLT_U_SPECIAL_0_OPCODE_X0 = 84,
394 SLT_U_SPECIAL_0_OPCODE_X1 = 54,
395 SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
396 SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
397 SNEB_SPECIAL_0_OPCODE_X0 = 85,
398 SNEB_SPECIAL_0_OPCODE_X1 = 55,
399 SNEH_SPECIAL_0_OPCODE_X0 = 86,
400 SNEH_SPECIAL_0_OPCODE_X1 = 56,
401 SNE_SPECIAL_0_OPCODE_X0 = 87,
402 SNE_SPECIAL_0_OPCODE_X1 = 57,
403 SNE_SPECIAL_5_OPCODE_Y0 = 3,
404 SNE_SPECIAL_5_OPCODE_Y1 = 3,
405 SPECIAL_0_OPCODE_X0 = 0,
406 SPECIAL_0_OPCODE_X1 = 1,
407 SPECIAL_0_OPCODE_Y0 = 1,
408 SPECIAL_0_OPCODE_Y1 = 1,
409 SPECIAL_1_OPCODE_Y0 = 2,
410 SPECIAL_1_OPCODE_Y1 = 2,
411 SPECIAL_2_OPCODE_Y0 = 3,
412 SPECIAL_2_OPCODE_Y1 = 3,
413 SPECIAL_3_OPCODE_Y0 = 4,
414 SPECIAL_3_OPCODE_Y1 = 4,
415 SPECIAL_4_OPCODE_Y0 = 5,
416 SPECIAL_4_OPCODE_Y1 = 5,
417 SPECIAL_5_OPCODE_Y0 = 6,
418 SPECIAL_5_OPCODE_Y1 = 6,
419 SPECIAL_6_OPCODE_Y0 = 7,
420 SPECIAL_7_OPCODE_Y0 = 8,
421 SRAB_SPECIAL_0_OPCODE_X0 = 88,
422 SRAB_SPECIAL_0_OPCODE_X1 = 58,
423 SRAH_SPECIAL_0_OPCODE_X0 = 89,
424 SRAH_SPECIAL_0_OPCODE_X1 = 59,
425 SRAIB_SHUN_0_OPCODE_X0 = 8,
426 SRAIB_SHUN_0_OPCODE_X1 = 8,
427 SRAIH_SHUN_0_OPCODE_X0 = 9,
428 SRAIH_SHUN_0_OPCODE_X1 = 9,
429 SRAI_SHUN_0_OPCODE_X0 = 10,
430 SRAI_SHUN_0_OPCODE_X1 = 10,
431 SRAI_SHUN_0_OPCODE_Y0 = 4,
432 SRAI_SHUN_0_OPCODE_Y1 = 4,
433 SRA_SPECIAL_0_OPCODE_X0 = 90,
434 SRA_SPECIAL_0_OPCODE_X1 = 60,
435 SRA_SPECIAL_3_OPCODE_Y0 = 3,
436 SRA_SPECIAL_3_OPCODE_Y1 = 3,
437 SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
438 SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
439 SUBB_SPECIAL_0_OPCODE_X0 = 91,
440 SUBB_SPECIAL_0_OPCODE_X1 = 61,
441 SUBHS_SPECIAL_0_OPCODE_X0 = 101,
442 SUBHS_SPECIAL_0_OPCODE_X1 = 71,
443 SUBH_SPECIAL_0_OPCODE_X0 = 92,
444 SUBH_SPECIAL_0_OPCODE_X1 = 62,
445 SUBS_SPECIAL_0_OPCODE_X0 = 97,
446 SUBS_SPECIAL_0_OPCODE_X1 = 67,
447 SUB_SPECIAL_0_OPCODE_X0 = 93,
448 SUB_SPECIAL_0_OPCODE_X1 = 63,
449 SUB_SPECIAL_0_OPCODE_Y0 = 3,
450 SUB_SPECIAL_0_OPCODE_Y1 = 3,
451 SWADD_IMM_0_OPCODE_X1 = 30,
452 SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
453 SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
454 SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
455 SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
456 SW_OPCODE_Y2 = 7,
457 SW_SPECIAL_0_OPCODE_X1 = 64,
458 TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
459 TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
460 TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
461 TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
462 TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
463 TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
464 TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
465 TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
466 TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
467 UN_0_SHUN_0_OPCODE_X0 = 11,
468 UN_0_SHUN_0_OPCODE_X1 = 11,
469 UN_0_SHUN_0_OPCODE_Y0 = 5,
470 UN_0_SHUN_0_OPCODE_Y1 = 5,
471 WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
472 XORI_IMM_0_OPCODE_X0 = 2,
473 XORI_IMM_0_OPCODE_X1 = 21,
474 XOR_SPECIAL_0_OPCODE_X0 = 94,
475 XOR_SPECIAL_0_OPCODE_X1 = 65,
476 XOR_SPECIAL_2_OPCODE_Y0 = 3,
477 XOR_SPECIAL_2_OPCODE_Y1 = 3
478};
479
480#endif /* !_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/asm/sigcontext.h
index 5e2d03336f53..6348e59d3724 100644
--- a/arch/tile/include/asm/sigcontext.h
+++ b/arch/tile/include/asm/sigcontext.h
@@ -15,6 +15,8 @@
15#ifndef _ASM_TILE_SIGCONTEXT_H 15#ifndef _ASM_TILE_SIGCONTEXT_H
16#define _ASM_TILE_SIGCONTEXT_H 16#define _ASM_TILE_SIGCONTEXT_H
17 17
18/* Don't pollute the namespace since <signal.h> includes this file. */
19#define __need_int_reg_t
18#include <arch/abi.h> 20#include <arch/abi.h>
19 21
20/* 22/*
@@ -22,14 +24,14 @@
22 * but is simplified since we know the fault is from userspace. 24 * but is simplified since we know the fault is from userspace.
23 */ 25 */
24struct sigcontext { 26struct sigcontext {
25 uint_reg_t gregs[53]; /* General-purpose registers. */ 27 __uint_reg_t gregs[53]; /* General-purpose registers. */
26 uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ 28 __uint_reg_t tp; /* Aliases gregs[TREG_TP]. */
27 uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ 29 __uint_reg_t sp; /* Aliases gregs[TREG_SP]. */
28 uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ 30 __uint_reg_t lr; /* Aliases gregs[TREG_LR]. */
29 uint_reg_t pc; /* Program counter. */ 31 __uint_reg_t pc; /* Program counter. */
30 uint_reg_t ics; /* In Interrupt Critical Section? */ 32 __uint_reg_t ics; /* In Interrupt Critical Section? */
31 uint_reg_t faultnum; /* Fault number. */ 33 __uint_reg_t faultnum; /* Fault number. */
32 uint_reg_t pad[5]; 34 __uint_reg_t pad[5];
33}; 35};
34 36
35#endif /* _ASM_TILE_SIGCONTEXT_H */ 37#endif /* _ASM_TILE_SIGCONTEXT_H */
diff --git a/arch/tile/include/asm/opcode-tile.h b/arch/tile/include/asm/tile-desc.h
index ba38959137d7..43849bf79dcb 100644
--- a/arch/tile/include/asm/opcode-tile.h
+++ b/arch/tile/include/asm/tile-desc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -12,19 +12,8 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#ifndef _ASM_TILE_OPCODE_TILE_H 15#ifndef __tilegx__
16#define _ASM_TILE_OPCODE_TILE_H 16#include <asm/tile-desc_32.h>
17
18#include <arch/chip.h>
19
20#if CHIP_WORD_SIZE() == 64
21#include <asm/opcode-tile_64.h>
22#else 17#else
23#include <asm/opcode-tile_32.h> 18#include <asm/tile-desc_64.h>
24#endif 19#endif
25
26/* These definitions are not correct for TILE64, so just avoid them. */
27#undef TILE_ELF_MACHINE_CODE
28#undef TILE_ELF_NAME
29
30#endif /* _ASM_TILE_OPCODE_TILE_H */
diff --git a/arch/tile/include/asm/tile-desc_32.h b/arch/tile/include/asm/tile-desc_32.h
new file mode 100644
index 000000000000..f09c5c43b0b2
--- /dev/null
+++ b/arch/tile/include/asm/tile-desc_32.h
@@ -0,0 +1,553 @@
1/* TILEPro opcode information.
2 *
3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 *
16 *
17 *
18 *
19 */
20
21#ifndef opcode_tilepro_h
22#define opcode_tilepro_h
23
24#include <arch/opcode.h>
25
26
27enum
28{
29 TILEPRO_MAX_OPERANDS = 5 /* mm */
30};
31
32typedef enum
33{
34 TILEPRO_OPC_BPT,
35 TILEPRO_OPC_INFO,
36 TILEPRO_OPC_INFOL,
37 TILEPRO_OPC_J,
38 TILEPRO_OPC_JAL,
39 TILEPRO_OPC_MOVE,
40 TILEPRO_OPC_MOVE_SN,
41 TILEPRO_OPC_MOVEI,
42 TILEPRO_OPC_MOVEI_SN,
43 TILEPRO_OPC_MOVELI,
44 TILEPRO_OPC_MOVELI_SN,
45 TILEPRO_OPC_MOVELIS,
46 TILEPRO_OPC_PREFETCH,
47 TILEPRO_OPC_RAISE,
48 TILEPRO_OPC_ADD,
49 TILEPRO_OPC_ADD_SN,
50 TILEPRO_OPC_ADDB,
51 TILEPRO_OPC_ADDB_SN,
52 TILEPRO_OPC_ADDBS_U,
53 TILEPRO_OPC_ADDBS_U_SN,
54 TILEPRO_OPC_ADDH,
55 TILEPRO_OPC_ADDH_SN,
56 TILEPRO_OPC_ADDHS,
57 TILEPRO_OPC_ADDHS_SN,
58 TILEPRO_OPC_ADDI,
59 TILEPRO_OPC_ADDI_SN,
60 TILEPRO_OPC_ADDIB,
61 TILEPRO_OPC_ADDIB_SN,
62 TILEPRO_OPC_ADDIH,
63 TILEPRO_OPC_ADDIH_SN,
64 TILEPRO_OPC_ADDLI,
65 TILEPRO_OPC_ADDLI_SN,
66 TILEPRO_OPC_ADDLIS,
67 TILEPRO_OPC_ADDS,
68 TILEPRO_OPC_ADDS_SN,
69 TILEPRO_OPC_ADIFFB_U,
70 TILEPRO_OPC_ADIFFB_U_SN,
71 TILEPRO_OPC_ADIFFH,
72 TILEPRO_OPC_ADIFFH_SN,
73 TILEPRO_OPC_AND,
74 TILEPRO_OPC_AND_SN,
75 TILEPRO_OPC_ANDI,
76 TILEPRO_OPC_ANDI_SN,
77 TILEPRO_OPC_AULI,
78 TILEPRO_OPC_AVGB_U,
79 TILEPRO_OPC_AVGB_U_SN,
80 TILEPRO_OPC_AVGH,
81 TILEPRO_OPC_AVGH_SN,
82 TILEPRO_OPC_BBNS,
83 TILEPRO_OPC_BBNS_SN,
84 TILEPRO_OPC_BBNST,
85 TILEPRO_OPC_BBNST_SN,
86 TILEPRO_OPC_BBS,
87 TILEPRO_OPC_BBS_SN,
88 TILEPRO_OPC_BBST,
89 TILEPRO_OPC_BBST_SN,
90 TILEPRO_OPC_BGEZ,
91 TILEPRO_OPC_BGEZ_SN,
92 TILEPRO_OPC_BGEZT,
93 TILEPRO_OPC_BGEZT_SN,
94 TILEPRO_OPC_BGZ,
95 TILEPRO_OPC_BGZ_SN,
96 TILEPRO_OPC_BGZT,
97 TILEPRO_OPC_BGZT_SN,
98 TILEPRO_OPC_BITX,
99 TILEPRO_OPC_BITX_SN,
100 TILEPRO_OPC_BLEZ,
101 TILEPRO_OPC_BLEZ_SN,
102 TILEPRO_OPC_BLEZT,
103 TILEPRO_OPC_BLEZT_SN,
104 TILEPRO_OPC_BLZ,
105 TILEPRO_OPC_BLZ_SN,
106 TILEPRO_OPC_BLZT,
107 TILEPRO_OPC_BLZT_SN,
108 TILEPRO_OPC_BNZ,
109 TILEPRO_OPC_BNZ_SN,
110 TILEPRO_OPC_BNZT,
111 TILEPRO_OPC_BNZT_SN,
112 TILEPRO_OPC_BYTEX,
113 TILEPRO_OPC_BYTEX_SN,
114 TILEPRO_OPC_BZ,
115 TILEPRO_OPC_BZ_SN,
116 TILEPRO_OPC_BZT,
117 TILEPRO_OPC_BZT_SN,
118 TILEPRO_OPC_CLZ,
119 TILEPRO_OPC_CLZ_SN,
120 TILEPRO_OPC_CRC32_32,
121 TILEPRO_OPC_CRC32_32_SN,
122 TILEPRO_OPC_CRC32_8,
123 TILEPRO_OPC_CRC32_8_SN,
124 TILEPRO_OPC_CTZ,
125 TILEPRO_OPC_CTZ_SN,
126 TILEPRO_OPC_DRAIN,
127 TILEPRO_OPC_DTLBPR,
128 TILEPRO_OPC_DWORD_ALIGN,
129 TILEPRO_OPC_DWORD_ALIGN_SN,
130 TILEPRO_OPC_FINV,
131 TILEPRO_OPC_FLUSH,
132 TILEPRO_OPC_FNOP,
133 TILEPRO_OPC_ICOH,
134 TILEPRO_OPC_ILL,
135 TILEPRO_OPC_INTHB,
136 TILEPRO_OPC_INTHB_SN,
137 TILEPRO_OPC_INTHH,
138 TILEPRO_OPC_INTHH_SN,
139 TILEPRO_OPC_INTLB,
140 TILEPRO_OPC_INTLB_SN,
141 TILEPRO_OPC_INTLH,
142 TILEPRO_OPC_INTLH_SN,
143 TILEPRO_OPC_INV,
144 TILEPRO_OPC_IRET,
145 TILEPRO_OPC_JALB,
146 TILEPRO_OPC_JALF,
147 TILEPRO_OPC_JALR,
148 TILEPRO_OPC_JALRP,
149 TILEPRO_OPC_JB,
150 TILEPRO_OPC_JF,
151 TILEPRO_OPC_JR,
152 TILEPRO_OPC_JRP,
153 TILEPRO_OPC_LB,
154 TILEPRO_OPC_LB_SN,
155 TILEPRO_OPC_LB_U,
156 TILEPRO_OPC_LB_U_SN,
157 TILEPRO_OPC_LBADD,
158 TILEPRO_OPC_LBADD_SN,
159 TILEPRO_OPC_LBADD_U,
160 TILEPRO_OPC_LBADD_U_SN,
161 TILEPRO_OPC_LH,
162 TILEPRO_OPC_LH_SN,
163 TILEPRO_OPC_LH_U,
164 TILEPRO_OPC_LH_U_SN,
165 TILEPRO_OPC_LHADD,
166 TILEPRO_OPC_LHADD_SN,
167 TILEPRO_OPC_LHADD_U,
168 TILEPRO_OPC_LHADD_U_SN,
169 TILEPRO_OPC_LNK,
170 TILEPRO_OPC_LNK_SN,
171 TILEPRO_OPC_LW,
172 TILEPRO_OPC_LW_SN,
173 TILEPRO_OPC_LW_NA,
174 TILEPRO_OPC_LW_NA_SN,
175 TILEPRO_OPC_LWADD,
176 TILEPRO_OPC_LWADD_SN,
177 TILEPRO_OPC_LWADD_NA,
178 TILEPRO_OPC_LWADD_NA_SN,
179 TILEPRO_OPC_MAXB_U,
180 TILEPRO_OPC_MAXB_U_SN,
181 TILEPRO_OPC_MAXH,
182 TILEPRO_OPC_MAXH_SN,
183 TILEPRO_OPC_MAXIB_U,
184 TILEPRO_OPC_MAXIB_U_SN,
185 TILEPRO_OPC_MAXIH,
186 TILEPRO_OPC_MAXIH_SN,
187 TILEPRO_OPC_MF,
188 TILEPRO_OPC_MFSPR,
189 TILEPRO_OPC_MINB_U,
190 TILEPRO_OPC_MINB_U_SN,
191 TILEPRO_OPC_MINH,
192 TILEPRO_OPC_MINH_SN,
193 TILEPRO_OPC_MINIB_U,
194 TILEPRO_OPC_MINIB_U_SN,
195 TILEPRO_OPC_MINIH,
196 TILEPRO_OPC_MINIH_SN,
197 TILEPRO_OPC_MM,
198 TILEPRO_OPC_MNZ,
199 TILEPRO_OPC_MNZ_SN,
200 TILEPRO_OPC_MNZB,
201 TILEPRO_OPC_MNZB_SN,
202 TILEPRO_OPC_MNZH,
203 TILEPRO_OPC_MNZH_SN,
204 TILEPRO_OPC_MTSPR,
205 TILEPRO_OPC_MULHH_SS,
206 TILEPRO_OPC_MULHH_SS_SN,
207 TILEPRO_OPC_MULHH_SU,
208 TILEPRO_OPC_MULHH_SU_SN,
209 TILEPRO_OPC_MULHH_UU,
210 TILEPRO_OPC_MULHH_UU_SN,
211 TILEPRO_OPC_MULHHA_SS,
212 TILEPRO_OPC_MULHHA_SS_SN,
213 TILEPRO_OPC_MULHHA_SU,
214 TILEPRO_OPC_MULHHA_SU_SN,
215 TILEPRO_OPC_MULHHA_UU,
216 TILEPRO_OPC_MULHHA_UU_SN,
217 TILEPRO_OPC_MULHHSA_UU,
218 TILEPRO_OPC_MULHHSA_UU_SN,
219 TILEPRO_OPC_MULHL_SS,
220 TILEPRO_OPC_MULHL_SS_SN,
221 TILEPRO_OPC_MULHL_SU,
222 TILEPRO_OPC_MULHL_SU_SN,
223 TILEPRO_OPC_MULHL_US,
224 TILEPRO_OPC_MULHL_US_SN,
225 TILEPRO_OPC_MULHL_UU,
226 TILEPRO_OPC_MULHL_UU_SN,
227 TILEPRO_OPC_MULHLA_SS,
228 TILEPRO_OPC_MULHLA_SS_SN,
229 TILEPRO_OPC_MULHLA_SU,
230 TILEPRO_OPC_MULHLA_SU_SN,
231 TILEPRO_OPC_MULHLA_US,
232 TILEPRO_OPC_MULHLA_US_SN,
233 TILEPRO_OPC_MULHLA_UU,
234 TILEPRO_OPC_MULHLA_UU_SN,
235 TILEPRO_OPC_MULHLSA_UU,
236 TILEPRO_OPC_MULHLSA_UU_SN,
237 TILEPRO_OPC_MULLL_SS,
238 TILEPRO_OPC_MULLL_SS_SN,
239 TILEPRO_OPC_MULLL_SU,
240 TILEPRO_OPC_MULLL_SU_SN,
241 TILEPRO_OPC_MULLL_UU,
242 TILEPRO_OPC_MULLL_UU_SN,
243 TILEPRO_OPC_MULLLA_SS,
244 TILEPRO_OPC_MULLLA_SS_SN,
245 TILEPRO_OPC_MULLLA_SU,
246 TILEPRO_OPC_MULLLA_SU_SN,
247 TILEPRO_OPC_MULLLA_UU,
248 TILEPRO_OPC_MULLLA_UU_SN,
249 TILEPRO_OPC_MULLLSA_UU,
250 TILEPRO_OPC_MULLLSA_UU_SN,
251 TILEPRO_OPC_MVNZ,
252 TILEPRO_OPC_MVNZ_SN,
253 TILEPRO_OPC_MVZ,
254 TILEPRO_OPC_MVZ_SN,
255 TILEPRO_OPC_MZ,
256 TILEPRO_OPC_MZ_SN,
257 TILEPRO_OPC_MZB,
258 TILEPRO_OPC_MZB_SN,
259 TILEPRO_OPC_MZH,
260 TILEPRO_OPC_MZH_SN,
261 TILEPRO_OPC_NAP,
262 TILEPRO_OPC_NOP,
263 TILEPRO_OPC_NOR,
264 TILEPRO_OPC_NOR_SN,
265 TILEPRO_OPC_OR,
266 TILEPRO_OPC_OR_SN,
267 TILEPRO_OPC_ORI,
268 TILEPRO_OPC_ORI_SN,
269 TILEPRO_OPC_PACKBS_U,
270 TILEPRO_OPC_PACKBS_U_SN,
271 TILEPRO_OPC_PACKHB,
272 TILEPRO_OPC_PACKHB_SN,
273 TILEPRO_OPC_PACKHS,
274 TILEPRO_OPC_PACKHS_SN,
275 TILEPRO_OPC_PACKLB,
276 TILEPRO_OPC_PACKLB_SN,
277 TILEPRO_OPC_PCNT,
278 TILEPRO_OPC_PCNT_SN,
279 TILEPRO_OPC_RL,
280 TILEPRO_OPC_RL_SN,
281 TILEPRO_OPC_RLI,
282 TILEPRO_OPC_RLI_SN,
283 TILEPRO_OPC_S1A,
284 TILEPRO_OPC_S1A_SN,
285 TILEPRO_OPC_S2A,
286 TILEPRO_OPC_S2A_SN,
287 TILEPRO_OPC_S3A,
288 TILEPRO_OPC_S3A_SN,
289 TILEPRO_OPC_SADAB_U,
290 TILEPRO_OPC_SADAB_U_SN,
291 TILEPRO_OPC_SADAH,
292 TILEPRO_OPC_SADAH_SN,
293 TILEPRO_OPC_SADAH_U,
294 TILEPRO_OPC_SADAH_U_SN,
295 TILEPRO_OPC_SADB_U,
296 TILEPRO_OPC_SADB_U_SN,
297 TILEPRO_OPC_SADH,
298 TILEPRO_OPC_SADH_SN,
299 TILEPRO_OPC_SADH_U,
300 TILEPRO_OPC_SADH_U_SN,
301 TILEPRO_OPC_SB,
302 TILEPRO_OPC_SBADD,
303 TILEPRO_OPC_SEQ,
304 TILEPRO_OPC_SEQ_SN,
305 TILEPRO_OPC_SEQB,
306 TILEPRO_OPC_SEQB_SN,
307 TILEPRO_OPC_SEQH,
308 TILEPRO_OPC_SEQH_SN,
309 TILEPRO_OPC_SEQI,
310 TILEPRO_OPC_SEQI_SN,
311 TILEPRO_OPC_SEQIB,
312 TILEPRO_OPC_SEQIB_SN,
313 TILEPRO_OPC_SEQIH,
314 TILEPRO_OPC_SEQIH_SN,
315 TILEPRO_OPC_SH,
316 TILEPRO_OPC_SHADD,
317 TILEPRO_OPC_SHL,
318 TILEPRO_OPC_SHL_SN,
319 TILEPRO_OPC_SHLB,
320 TILEPRO_OPC_SHLB_SN,
321 TILEPRO_OPC_SHLH,
322 TILEPRO_OPC_SHLH_SN,
323 TILEPRO_OPC_SHLI,
324 TILEPRO_OPC_SHLI_SN,
325 TILEPRO_OPC_SHLIB,
326 TILEPRO_OPC_SHLIB_SN,
327 TILEPRO_OPC_SHLIH,
328 TILEPRO_OPC_SHLIH_SN,
329 TILEPRO_OPC_SHR,
330 TILEPRO_OPC_SHR_SN,
331 TILEPRO_OPC_SHRB,
332 TILEPRO_OPC_SHRB_SN,
333 TILEPRO_OPC_SHRH,
334 TILEPRO_OPC_SHRH_SN,
335 TILEPRO_OPC_SHRI,
336 TILEPRO_OPC_SHRI_SN,
337 TILEPRO_OPC_SHRIB,
338 TILEPRO_OPC_SHRIB_SN,
339 TILEPRO_OPC_SHRIH,
340 TILEPRO_OPC_SHRIH_SN,
341 TILEPRO_OPC_SLT,
342 TILEPRO_OPC_SLT_SN,
343 TILEPRO_OPC_SLT_U,
344 TILEPRO_OPC_SLT_U_SN,
345 TILEPRO_OPC_SLTB,
346 TILEPRO_OPC_SLTB_SN,
347 TILEPRO_OPC_SLTB_U,
348 TILEPRO_OPC_SLTB_U_SN,
349 TILEPRO_OPC_SLTE,
350 TILEPRO_OPC_SLTE_SN,
351 TILEPRO_OPC_SLTE_U,
352 TILEPRO_OPC_SLTE_U_SN,
353 TILEPRO_OPC_SLTEB,
354 TILEPRO_OPC_SLTEB_SN,
355 TILEPRO_OPC_SLTEB_U,
356 TILEPRO_OPC_SLTEB_U_SN,
357 TILEPRO_OPC_SLTEH,
358 TILEPRO_OPC_SLTEH_SN,
359 TILEPRO_OPC_SLTEH_U,
360 TILEPRO_OPC_SLTEH_U_SN,
361 TILEPRO_OPC_SLTH,
362 TILEPRO_OPC_SLTH_SN,
363 TILEPRO_OPC_SLTH_U,
364 TILEPRO_OPC_SLTH_U_SN,
365 TILEPRO_OPC_SLTI,
366 TILEPRO_OPC_SLTI_SN,
367 TILEPRO_OPC_SLTI_U,
368 TILEPRO_OPC_SLTI_U_SN,
369 TILEPRO_OPC_SLTIB,
370 TILEPRO_OPC_SLTIB_SN,
371 TILEPRO_OPC_SLTIB_U,
372 TILEPRO_OPC_SLTIB_U_SN,
373 TILEPRO_OPC_SLTIH,
374 TILEPRO_OPC_SLTIH_SN,
375 TILEPRO_OPC_SLTIH_U,
376 TILEPRO_OPC_SLTIH_U_SN,
377 TILEPRO_OPC_SNE,
378 TILEPRO_OPC_SNE_SN,
379 TILEPRO_OPC_SNEB,
380 TILEPRO_OPC_SNEB_SN,
381 TILEPRO_OPC_SNEH,
382 TILEPRO_OPC_SNEH_SN,
383 TILEPRO_OPC_SRA,
384 TILEPRO_OPC_SRA_SN,
385 TILEPRO_OPC_SRAB,
386 TILEPRO_OPC_SRAB_SN,
387 TILEPRO_OPC_SRAH,
388 TILEPRO_OPC_SRAH_SN,
389 TILEPRO_OPC_SRAI,
390 TILEPRO_OPC_SRAI_SN,
391 TILEPRO_OPC_SRAIB,
392 TILEPRO_OPC_SRAIB_SN,
393 TILEPRO_OPC_SRAIH,
394 TILEPRO_OPC_SRAIH_SN,
395 TILEPRO_OPC_SUB,
396 TILEPRO_OPC_SUB_SN,
397 TILEPRO_OPC_SUBB,
398 TILEPRO_OPC_SUBB_SN,
399 TILEPRO_OPC_SUBBS_U,
400 TILEPRO_OPC_SUBBS_U_SN,
401 TILEPRO_OPC_SUBH,
402 TILEPRO_OPC_SUBH_SN,
403 TILEPRO_OPC_SUBHS,
404 TILEPRO_OPC_SUBHS_SN,
405 TILEPRO_OPC_SUBS,
406 TILEPRO_OPC_SUBS_SN,
407 TILEPRO_OPC_SW,
408 TILEPRO_OPC_SWADD,
409 TILEPRO_OPC_SWINT0,
410 TILEPRO_OPC_SWINT1,
411 TILEPRO_OPC_SWINT2,
412 TILEPRO_OPC_SWINT3,
413 TILEPRO_OPC_TBLIDXB0,
414 TILEPRO_OPC_TBLIDXB0_SN,
415 TILEPRO_OPC_TBLIDXB1,
416 TILEPRO_OPC_TBLIDXB1_SN,
417 TILEPRO_OPC_TBLIDXB2,
418 TILEPRO_OPC_TBLIDXB2_SN,
419 TILEPRO_OPC_TBLIDXB3,
420 TILEPRO_OPC_TBLIDXB3_SN,
421 TILEPRO_OPC_TNS,
422 TILEPRO_OPC_TNS_SN,
423 TILEPRO_OPC_WH64,
424 TILEPRO_OPC_XOR,
425 TILEPRO_OPC_XOR_SN,
426 TILEPRO_OPC_XORI,
427 TILEPRO_OPC_XORI_SN,
428 TILEPRO_OPC_NONE
429} tilepro_mnemonic;
430
431
432
433
434typedef enum
435{
436 TILEPRO_PIPELINE_X0,
437 TILEPRO_PIPELINE_X1,
438 TILEPRO_PIPELINE_Y0,
439 TILEPRO_PIPELINE_Y1,
440 TILEPRO_PIPELINE_Y2,
441} tilepro_pipeline;
442
443#define tilepro_is_x_pipeline(p) ((int)(p) <= (int)TILEPRO_PIPELINE_X1)
444
445typedef enum
446{
447 TILEPRO_OP_TYPE_REGISTER,
448 TILEPRO_OP_TYPE_IMMEDIATE,
449 TILEPRO_OP_TYPE_ADDRESS,
450 TILEPRO_OP_TYPE_SPR
451} tilepro_operand_type;
452
453struct tilepro_operand
454{
455 /* Is this operand a register, immediate or address? */
456 tilepro_operand_type type;
457
458 /* The default relocation type for this operand. */
459 signed int default_reloc : 16;
460
461 /* How many bits is this value? (used for range checking) */
462 unsigned int num_bits : 5;
463
464 /* Is the value signed? (used for range checking) */
465 unsigned int is_signed : 1;
466
467 /* Is this operand a source register? */
468 unsigned int is_src_reg : 1;
469
470 /* Is this operand written? (i.e. is it a destination register) */
471 unsigned int is_dest_reg : 1;
472
473 /* Is this operand PC-relative? */
474 unsigned int is_pc_relative : 1;
475
476 /* By how many bits do we right shift the value before inserting? */
477 unsigned int rightshift : 2;
478
479 /* Return the bits for this operand to be ORed into an existing bundle. */
480 tilepro_bundle_bits (*insert) (int op);
481
482 /* Extract this operand and return it. */
483 unsigned int (*extract) (tilepro_bundle_bits bundle);
484};
485
486
487extern const struct tilepro_operand tilepro_operands[];
488
489/* One finite-state machine per pipe for rapid instruction decoding. */
490extern const unsigned short * const
491tilepro_bundle_decoder_fsms[TILEPRO_NUM_PIPELINE_ENCODINGS];
492
493
494struct tilepro_opcode
495{
496 /* The opcode mnemonic, e.g. "add" */
497 const char *name;
498
499 /* The enum value for this mnemonic. */
500 tilepro_mnemonic mnemonic;
501
502 /* A bit mask of which of the five pipes this instruction
503 is compatible with:
504 X0 0x01
505 X1 0x02
506 Y0 0x04
507 Y1 0x08
508 Y2 0x10 */
509 unsigned char pipes;
510
511 /* How many operands are there? */
512 unsigned char num_operands;
513
514 /* Which register does this write implicitly, or TREG_ZERO if none? */
515 unsigned char implicitly_written_register;
516
517 /* Can this be bundled with other instructions (almost always true). */
518 unsigned char can_bundle;
519
520 /* The description of the operands. Each of these is an
521 * index into the tilepro_operands[] table. */
522 unsigned char operands[TILEPRO_NUM_PIPELINE_ENCODINGS][TILEPRO_MAX_OPERANDS];
523
524};
525
526extern const struct tilepro_opcode tilepro_opcodes[];
527
528
529/* Used for non-textual disassembly into structs. */
530struct tilepro_decoded_instruction
531{
532 const struct tilepro_opcode *opcode;
533 const struct tilepro_operand *operands[TILEPRO_MAX_OPERANDS];
534 int operand_values[TILEPRO_MAX_OPERANDS];
535};
536
537
538/* Disassemble a bundle into a struct for machine processing. */
539extern int parse_insn_tilepro(tilepro_bundle_bits bits,
540 unsigned int pc,
541 struct tilepro_decoded_instruction
542 decoded[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE]);
543
544
545/* Given a set of bundle bits and a specific pipe, returns which
546 * instruction the bundle contains in that pipe.
547 */
548extern const struct tilepro_opcode *
549find_opcode(tilepro_bundle_bits bits, tilepro_pipeline pipe);
550
551
552
553#endif /* opcode_tilepro_h */
diff --git a/arch/tile/include/asm/tile-desc_64.h b/arch/tile/include/asm/tile-desc_64.h
new file mode 100644
index 000000000000..1819efcba54d
--- /dev/null
+++ b/arch/tile/include/asm/tile-desc_64.h
@@ -0,0 +1,483 @@
1/* TILE-Gx opcode information.
2 *
3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 *
16 *
17 *
18 *
19 */
20
21#ifndef opcode_tile_h
22#define opcode_tile_h
23
24#include <arch/opcode.h>
25
26
27enum
28{
29 TILEGX_MAX_OPERANDS = 4 /* bfexts */
30};
31
32typedef enum
33{
34 TILEGX_OPC_BPT,
35 TILEGX_OPC_INFO,
36 TILEGX_OPC_INFOL,
37 TILEGX_OPC_MOVE,
38 TILEGX_OPC_MOVEI,
39 TILEGX_OPC_MOVELI,
40 TILEGX_OPC_PREFETCH,
41 TILEGX_OPC_PREFETCH_ADD_L1,
42 TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
43 TILEGX_OPC_PREFETCH_ADD_L2,
44 TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
45 TILEGX_OPC_PREFETCH_ADD_L3,
46 TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
47 TILEGX_OPC_PREFETCH_L1,
48 TILEGX_OPC_PREFETCH_L1_FAULT,
49 TILEGX_OPC_PREFETCH_L2,
50 TILEGX_OPC_PREFETCH_L2_FAULT,
51 TILEGX_OPC_PREFETCH_L3,
52 TILEGX_OPC_PREFETCH_L3_FAULT,
53 TILEGX_OPC_RAISE,
54 TILEGX_OPC_ADD,
55 TILEGX_OPC_ADDI,
56 TILEGX_OPC_ADDLI,
57 TILEGX_OPC_ADDX,
58 TILEGX_OPC_ADDXI,
59 TILEGX_OPC_ADDXLI,
60 TILEGX_OPC_ADDXSC,
61 TILEGX_OPC_AND,
62 TILEGX_OPC_ANDI,
63 TILEGX_OPC_BEQZ,
64 TILEGX_OPC_BEQZT,
65 TILEGX_OPC_BFEXTS,
66 TILEGX_OPC_BFEXTU,
67 TILEGX_OPC_BFINS,
68 TILEGX_OPC_BGEZ,
69 TILEGX_OPC_BGEZT,
70 TILEGX_OPC_BGTZ,
71 TILEGX_OPC_BGTZT,
72 TILEGX_OPC_BLBC,
73 TILEGX_OPC_BLBCT,
74 TILEGX_OPC_BLBS,
75 TILEGX_OPC_BLBST,
76 TILEGX_OPC_BLEZ,
77 TILEGX_OPC_BLEZT,
78 TILEGX_OPC_BLTZ,
79 TILEGX_OPC_BLTZT,
80 TILEGX_OPC_BNEZ,
81 TILEGX_OPC_BNEZT,
82 TILEGX_OPC_CLZ,
83 TILEGX_OPC_CMOVEQZ,
84 TILEGX_OPC_CMOVNEZ,
85 TILEGX_OPC_CMPEQ,
86 TILEGX_OPC_CMPEQI,
87 TILEGX_OPC_CMPEXCH,
88 TILEGX_OPC_CMPEXCH4,
89 TILEGX_OPC_CMPLES,
90 TILEGX_OPC_CMPLEU,
91 TILEGX_OPC_CMPLTS,
92 TILEGX_OPC_CMPLTSI,
93 TILEGX_OPC_CMPLTU,
94 TILEGX_OPC_CMPLTUI,
95 TILEGX_OPC_CMPNE,
96 TILEGX_OPC_CMUL,
97 TILEGX_OPC_CMULA,
98 TILEGX_OPC_CMULAF,
99 TILEGX_OPC_CMULF,
100 TILEGX_OPC_CMULFR,
101 TILEGX_OPC_CMULH,
102 TILEGX_OPC_CMULHR,
103 TILEGX_OPC_CRC32_32,
104 TILEGX_OPC_CRC32_8,
105 TILEGX_OPC_CTZ,
106 TILEGX_OPC_DBLALIGN,
107 TILEGX_OPC_DBLALIGN2,
108 TILEGX_OPC_DBLALIGN4,
109 TILEGX_OPC_DBLALIGN6,
110 TILEGX_OPC_DRAIN,
111 TILEGX_OPC_DTLBPR,
112 TILEGX_OPC_EXCH,
113 TILEGX_OPC_EXCH4,
114 TILEGX_OPC_FDOUBLE_ADD_FLAGS,
115 TILEGX_OPC_FDOUBLE_ADDSUB,
116 TILEGX_OPC_FDOUBLE_MUL_FLAGS,
117 TILEGX_OPC_FDOUBLE_PACK1,
118 TILEGX_OPC_FDOUBLE_PACK2,
119 TILEGX_OPC_FDOUBLE_SUB_FLAGS,
120 TILEGX_OPC_FDOUBLE_UNPACK_MAX,
121 TILEGX_OPC_FDOUBLE_UNPACK_MIN,
122 TILEGX_OPC_FETCHADD,
123 TILEGX_OPC_FETCHADD4,
124 TILEGX_OPC_FETCHADDGEZ,
125 TILEGX_OPC_FETCHADDGEZ4,
126 TILEGX_OPC_FETCHAND,
127 TILEGX_OPC_FETCHAND4,
128 TILEGX_OPC_FETCHOR,
129 TILEGX_OPC_FETCHOR4,
130 TILEGX_OPC_FINV,
131 TILEGX_OPC_FLUSH,
132 TILEGX_OPC_FLUSHWB,
133 TILEGX_OPC_FNOP,
134 TILEGX_OPC_FSINGLE_ADD1,
135 TILEGX_OPC_FSINGLE_ADDSUB2,
136 TILEGX_OPC_FSINGLE_MUL1,
137 TILEGX_OPC_FSINGLE_MUL2,
138 TILEGX_OPC_FSINGLE_PACK1,
139 TILEGX_OPC_FSINGLE_PACK2,
140 TILEGX_OPC_FSINGLE_SUB1,
141 TILEGX_OPC_ICOH,
142 TILEGX_OPC_ILL,
143 TILEGX_OPC_INV,
144 TILEGX_OPC_IRET,
145 TILEGX_OPC_J,
146 TILEGX_OPC_JAL,
147 TILEGX_OPC_JALR,
148 TILEGX_OPC_JALRP,
149 TILEGX_OPC_JR,
150 TILEGX_OPC_JRP,
151 TILEGX_OPC_LD,
152 TILEGX_OPC_LD1S,
153 TILEGX_OPC_LD1S_ADD,
154 TILEGX_OPC_LD1U,
155 TILEGX_OPC_LD1U_ADD,
156 TILEGX_OPC_LD2S,
157 TILEGX_OPC_LD2S_ADD,
158 TILEGX_OPC_LD2U,
159 TILEGX_OPC_LD2U_ADD,
160 TILEGX_OPC_LD4S,
161 TILEGX_OPC_LD4S_ADD,
162 TILEGX_OPC_LD4U,
163 TILEGX_OPC_LD4U_ADD,
164 TILEGX_OPC_LD_ADD,
165 TILEGX_OPC_LDNA,
166 TILEGX_OPC_LDNA_ADD,
167 TILEGX_OPC_LDNT,
168 TILEGX_OPC_LDNT1S,
169 TILEGX_OPC_LDNT1S_ADD,
170 TILEGX_OPC_LDNT1U,
171 TILEGX_OPC_LDNT1U_ADD,
172 TILEGX_OPC_LDNT2S,
173 TILEGX_OPC_LDNT2S_ADD,
174 TILEGX_OPC_LDNT2U,
175 TILEGX_OPC_LDNT2U_ADD,
176 TILEGX_OPC_LDNT4S,
177 TILEGX_OPC_LDNT4S_ADD,
178 TILEGX_OPC_LDNT4U,
179 TILEGX_OPC_LDNT4U_ADD,
180 TILEGX_OPC_LDNT_ADD,
181 TILEGX_OPC_LNK,
182 TILEGX_OPC_MF,
183 TILEGX_OPC_MFSPR,
184 TILEGX_OPC_MM,
185 TILEGX_OPC_MNZ,
186 TILEGX_OPC_MTSPR,
187 TILEGX_OPC_MUL_HS_HS,
188 TILEGX_OPC_MUL_HS_HU,
189 TILEGX_OPC_MUL_HS_LS,
190 TILEGX_OPC_MUL_HS_LU,
191 TILEGX_OPC_MUL_HU_HU,
192 TILEGX_OPC_MUL_HU_LS,
193 TILEGX_OPC_MUL_HU_LU,
194 TILEGX_OPC_MUL_LS_LS,
195 TILEGX_OPC_MUL_LS_LU,
196 TILEGX_OPC_MUL_LU_LU,
197 TILEGX_OPC_MULA_HS_HS,
198 TILEGX_OPC_MULA_HS_HU,
199 TILEGX_OPC_MULA_HS_LS,
200 TILEGX_OPC_MULA_HS_LU,
201 TILEGX_OPC_MULA_HU_HU,
202 TILEGX_OPC_MULA_HU_LS,
203 TILEGX_OPC_MULA_HU_LU,
204 TILEGX_OPC_MULA_LS_LS,
205 TILEGX_OPC_MULA_LS_LU,
206 TILEGX_OPC_MULA_LU_LU,
207 TILEGX_OPC_MULAX,
208 TILEGX_OPC_MULX,
209 TILEGX_OPC_MZ,
210 TILEGX_OPC_NAP,
211 TILEGX_OPC_NOP,
212 TILEGX_OPC_NOR,
213 TILEGX_OPC_OR,
214 TILEGX_OPC_ORI,
215 TILEGX_OPC_PCNT,
216 TILEGX_OPC_REVBITS,
217 TILEGX_OPC_REVBYTES,
218 TILEGX_OPC_ROTL,
219 TILEGX_OPC_ROTLI,
220 TILEGX_OPC_SHL,
221 TILEGX_OPC_SHL16INSLI,
222 TILEGX_OPC_SHL1ADD,
223 TILEGX_OPC_SHL1ADDX,
224 TILEGX_OPC_SHL2ADD,
225 TILEGX_OPC_SHL2ADDX,
226 TILEGX_OPC_SHL3ADD,
227 TILEGX_OPC_SHL3ADDX,
228 TILEGX_OPC_SHLI,
229 TILEGX_OPC_SHLX,
230 TILEGX_OPC_SHLXI,
231 TILEGX_OPC_SHRS,
232 TILEGX_OPC_SHRSI,
233 TILEGX_OPC_SHRU,
234 TILEGX_OPC_SHRUI,
235 TILEGX_OPC_SHRUX,
236 TILEGX_OPC_SHRUXI,
237 TILEGX_OPC_SHUFFLEBYTES,
238 TILEGX_OPC_ST,
239 TILEGX_OPC_ST1,
240 TILEGX_OPC_ST1_ADD,
241 TILEGX_OPC_ST2,
242 TILEGX_OPC_ST2_ADD,
243 TILEGX_OPC_ST4,
244 TILEGX_OPC_ST4_ADD,
245 TILEGX_OPC_ST_ADD,
246 TILEGX_OPC_STNT,
247 TILEGX_OPC_STNT1,
248 TILEGX_OPC_STNT1_ADD,
249 TILEGX_OPC_STNT2,
250 TILEGX_OPC_STNT2_ADD,
251 TILEGX_OPC_STNT4,
252 TILEGX_OPC_STNT4_ADD,
253 TILEGX_OPC_STNT_ADD,
254 TILEGX_OPC_SUB,
255 TILEGX_OPC_SUBX,
256 TILEGX_OPC_SUBXSC,
257 TILEGX_OPC_SWINT0,
258 TILEGX_OPC_SWINT1,
259 TILEGX_OPC_SWINT2,
260 TILEGX_OPC_SWINT3,
261 TILEGX_OPC_TBLIDXB0,
262 TILEGX_OPC_TBLIDXB1,
263 TILEGX_OPC_TBLIDXB2,
264 TILEGX_OPC_TBLIDXB3,
265 TILEGX_OPC_V1ADD,
266 TILEGX_OPC_V1ADDI,
267 TILEGX_OPC_V1ADDUC,
268 TILEGX_OPC_V1ADIFFU,
269 TILEGX_OPC_V1AVGU,
270 TILEGX_OPC_V1CMPEQ,
271 TILEGX_OPC_V1CMPEQI,
272 TILEGX_OPC_V1CMPLES,
273 TILEGX_OPC_V1CMPLEU,
274 TILEGX_OPC_V1CMPLTS,
275 TILEGX_OPC_V1CMPLTSI,
276 TILEGX_OPC_V1CMPLTU,
277 TILEGX_OPC_V1CMPLTUI,
278 TILEGX_OPC_V1CMPNE,
279 TILEGX_OPC_V1DDOTPU,
280 TILEGX_OPC_V1DDOTPUA,
281 TILEGX_OPC_V1DDOTPUS,
282 TILEGX_OPC_V1DDOTPUSA,
283 TILEGX_OPC_V1DOTP,
284 TILEGX_OPC_V1DOTPA,
285 TILEGX_OPC_V1DOTPU,
286 TILEGX_OPC_V1DOTPUA,
287 TILEGX_OPC_V1DOTPUS,
288 TILEGX_OPC_V1DOTPUSA,
289 TILEGX_OPC_V1INT_H,
290 TILEGX_OPC_V1INT_L,
291 TILEGX_OPC_V1MAXU,
292 TILEGX_OPC_V1MAXUI,
293 TILEGX_OPC_V1MINU,
294 TILEGX_OPC_V1MINUI,
295 TILEGX_OPC_V1MNZ,
296 TILEGX_OPC_V1MULTU,
297 TILEGX_OPC_V1MULU,
298 TILEGX_OPC_V1MULUS,
299 TILEGX_OPC_V1MZ,
300 TILEGX_OPC_V1SADAU,
301 TILEGX_OPC_V1SADU,
302 TILEGX_OPC_V1SHL,
303 TILEGX_OPC_V1SHLI,
304 TILEGX_OPC_V1SHRS,
305 TILEGX_OPC_V1SHRSI,
306 TILEGX_OPC_V1SHRU,
307 TILEGX_OPC_V1SHRUI,
308 TILEGX_OPC_V1SUB,
309 TILEGX_OPC_V1SUBUC,
310 TILEGX_OPC_V2ADD,
311 TILEGX_OPC_V2ADDI,
312 TILEGX_OPC_V2ADDSC,
313 TILEGX_OPC_V2ADIFFS,
314 TILEGX_OPC_V2AVGS,
315 TILEGX_OPC_V2CMPEQ,
316 TILEGX_OPC_V2CMPEQI,
317 TILEGX_OPC_V2CMPLES,
318 TILEGX_OPC_V2CMPLEU,
319 TILEGX_OPC_V2CMPLTS,
320 TILEGX_OPC_V2CMPLTSI,
321 TILEGX_OPC_V2CMPLTU,
322 TILEGX_OPC_V2CMPLTUI,
323 TILEGX_OPC_V2CMPNE,
324 TILEGX_OPC_V2DOTP,
325 TILEGX_OPC_V2DOTPA,
326 TILEGX_OPC_V2INT_H,
327 TILEGX_OPC_V2INT_L,
328 TILEGX_OPC_V2MAXS,
329 TILEGX_OPC_V2MAXSI,
330 TILEGX_OPC_V2MINS,
331 TILEGX_OPC_V2MINSI,
332 TILEGX_OPC_V2MNZ,
333 TILEGX_OPC_V2MULFSC,
334 TILEGX_OPC_V2MULS,
335 TILEGX_OPC_V2MULTS,
336 TILEGX_OPC_V2MZ,
337 TILEGX_OPC_V2PACKH,
338 TILEGX_OPC_V2PACKL,
339 TILEGX_OPC_V2PACKUC,
340 TILEGX_OPC_V2SADAS,
341 TILEGX_OPC_V2SADAU,
342 TILEGX_OPC_V2SADS,
343 TILEGX_OPC_V2SADU,
344 TILEGX_OPC_V2SHL,
345 TILEGX_OPC_V2SHLI,
346 TILEGX_OPC_V2SHLSC,
347 TILEGX_OPC_V2SHRS,
348 TILEGX_OPC_V2SHRSI,
349 TILEGX_OPC_V2SHRU,
350 TILEGX_OPC_V2SHRUI,
351 TILEGX_OPC_V2SUB,
352 TILEGX_OPC_V2SUBSC,
353 TILEGX_OPC_V4ADD,
354 TILEGX_OPC_V4ADDSC,
355 TILEGX_OPC_V4INT_H,
356 TILEGX_OPC_V4INT_L,
357 TILEGX_OPC_V4PACKSC,
358 TILEGX_OPC_V4SHL,
359 TILEGX_OPC_V4SHLSC,
360 TILEGX_OPC_V4SHRS,
361 TILEGX_OPC_V4SHRU,
362 TILEGX_OPC_V4SUB,
363 TILEGX_OPC_V4SUBSC,
364 TILEGX_OPC_WH64,
365 TILEGX_OPC_XOR,
366 TILEGX_OPC_XORI,
367 TILEGX_OPC_NONE
368} tilegx_mnemonic;
369
370
371
372typedef enum
373{
374 TILEGX_PIPELINE_X0,
375 TILEGX_PIPELINE_X1,
376 TILEGX_PIPELINE_Y0,
377 TILEGX_PIPELINE_Y1,
378 TILEGX_PIPELINE_Y2,
379} tilegx_pipeline;
380
381#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
382
383typedef enum
384{
385 TILEGX_OP_TYPE_REGISTER,
386 TILEGX_OP_TYPE_IMMEDIATE,
387 TILEGX_OP_TYPE_ADDRESS,
388 TILEGX_OP_TYPE_SPR
389} tilegx_operand_type;
390
391struct tilegx_operand
392{
393 /* Is this operand a register, immediate or address? */
394 tilegx_operand_type type;
395
396 /* The default relocation type for this operand. */
397 signed int default_reloc : 16;
398
399 /* How many bits is this value? (used for range checking) */
400 unsigned int num_bits : 5;
401
402 /* Is the value signed? (used for range checking) */
403 unsigned int is_signed : 1;
404
405 /* Is this operand a source register? */
406 unsigned int is_src_reg : 1;
407
408 /* Is this operand written? (i.e. is it a destination register) */
409 unsigned int is_dest_reg : 1;
410
411 /* Is this operand PC-relative? */
412 unsigned int is_pc_relative : 1;
413
414 /* By how many bits do we right shift the value before inserting? */
415 unsigned int rightshift : 2;
416
417 /* Return the bits for this operand to be ORed into an existing bundle. */
418 tilegx_bundle_bits (*insert) (int op);
419
420 /* Extract this operand and return it. */
421 unsigned int (*extract) (tilegx_bundle_bits bundle);
422};
423
424
425extern const struct tilegx_operand tilegx_operands[];
426
427/* One finite-state machine per pipe for rapid instruction decoding. */
428extern const unsigned short * const
429tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS];
430
431
432struct tilegx_opcode
433{
434 /* The opcode mnemonic, e.g. "add" */
435 const char *name;
436
437 /* The enum value for this mnemonic. */
438 tilegx_mnemonic mnemonic;
439
440 /* A bit mask of which of the five pipes this instruction
441 is compatible with:
442 X0 0x01
443 X1 0x02
444 Y0 0x04
445 Y1 0x08
446 Y2 0x10 */
447 unsigned char pipes;
448
449 /* How many operands are there? */
450 unsigned char num_operands;
451
452 /* Which register does this write implicitly, or TREG_ZERO if none? */
453 unsigned char implicitly_written_register;
454
455 /* Can this be bundled with other instructions (almost always true). */
456 unsigned char can_bundle;
457
458 /* The description of the operands. Each of these is an
459 * index into the tilegx_operands[] table. */
460 unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
461
462};
463
464extern const struct tilegx_opcode tilegx_opcodes[];
465
466/* Used for non-textual disassembly into structs. */
467struct tilegx_decoded_instruction
468{
469 const struct tilegx_opcode *opcode;
470 const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
471 long long operand_values[TILEGX_MAX_OPERANDS];
472};
473
474
475/* Disassemble a bundle into a struct for machine processing. */
476extern int parse_insn_tilegx(tilegx_bundle_bits bits,
477 unsigned long long pc,
478 struct tilegx_decoded_instruction
479 decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]);
480
481
482
483#endif /* opcode_tilegx_h */
diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c
index 1dc71eabfc5a..9092ce8aa6b4 100644
--- a/arch/tile/kernel/backtrace.c
+++ b/arch/tile/kernel/backtrace.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -15,13 +15,11 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <asm/backtrace.h> 17#include <asm/backtrace.h>
18#include <asm/opcode-tile.h> 18#include <asm/tile-desc.h>
19#include <arch/abi.h> 19#include <arch/abi.h>
20 20
21#ifdef __tilegx__ 21#ifdef __tilegx__
22#define tile_bundle_bits tilegx_bundle_bits
23#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE 22#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
24#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
25#define tile_decoded_instruction tilegx_decoded_instruction 23#define tile_decoded_instruction tilegx_decoded_instruction
26#define tile_mnemonic tilegx_mnemonic 24#define tile_mnemonic tilegx_mnemonic
27#define parse_insn_tile parse_insn_tilegx 25#define parse_insn_tile parse_insn_tilegx
@@ -35,7 +33,18 @@
35#define OPCODE_STORE TILEGX_OPC_ST 33#define OPCODE_STORE TILEGX_OPC_ST
36typedef long long bt_int_reg_t; 34typedef long long bt_int_reg_t;
37#else 35#else
38#define OPCODE_STORE TILE_OPC_SW 36#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE
37#define tile_decoded_instruction tilepro_decoded_instruction
38#define tile_mnemonic tilepro_mnemonic
39#define parse_insn_tile parse_insn_tilepro
40#define TILE_OPC_IRET TILEPRO_OPC_IRET
41#define TILE_OPC_ADDI TILEPRO_OPC_ADDI
42#define TILE_OPC_ADDLI TILEPRO_OPC_ADDLI
43#define TILE_OPC_INFO TILEPRO_OPC_INFO
44#define TILE_OPC_INFOL TILEPRO_OPC_INFOL
45#define TILE_OPC_JRP TILEPRO_OPC_JRP
46#define TILE_OPC_MOVE TILEPRO_OPC_MOVE
47#define OPCODE_STORE TILEPRO_OPC_SW
39typedef int bt_int_reg_t; 48typedef int bt_int_reg_t;
40#endif 49#endif
41 50
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
index 28fa6ece9d3a..b90ab9925674 100644
--- a/arch/tile/kernel/module.c
+++ b/arch/tile/kernel/module.c
@@ -20,9 +20,9 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <asm/opcode-tile.h>
24#include <asm/pgtable.h> 23#include <asm/pgtable.h>
25#include <asm/homecache.h> 24#include <asm/homecache.h>
25#include <arch/opcode.h>
26 26
27#ifdef __tilegx__ 27#ifdef __tilegx__
28# define Elf_Rela Elf64_Rela 28# define Elf_Rela Elf64_Rela
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 4032ca8e51b6..b7a879504086 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -25,9 +25,8 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
28#include <asm/opcode-tile.h>
29#include <asm/opcode_constants.h>
30#include <arch/abi.h> 28#include <arch/abi.h>
29#include <arch/opcode.h>
31 30
32#define signExtend17(val) sign_extend((val), 17) 31#define signExtend17(val) sign_extend((val), 17)
33#define TILE_X1_MASK (0xffffffffULL << 31) 32#define TILE_X1_MASK (0xffffffffULL << 31)
@@ -118,7 +117,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
118 int val_reg, addr_reg, err, val; 117 int val_reg, addr_reg, err, val;
119 118
120 /* Get address and value registers */ 119 /* Get address and value registers */
121 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) { 120 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) {
122 addr_reg = get_SrcA_Y2(bundle); 121 addr_reg = get_SrcA_Y2(bundle);
123 val_reg = get_SrcBDest_Y2(bundle); 122 val_reg = get_SrcBDest_Y2(bundle);
124 } else if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) { 123 } else if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
@@ -229,7 +228,7 @@ P("\n");
229 } 228 }
230 ++unaligned_fixup_count; 229 ++unaligned_fixup_count;
231 230
232 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) { 231 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) {
233 /* Convert the Y2 instruction to a prefetch. */ 232 /* Convert the Y2 instruction to a prefetch. */
234 bundle &= ~(create_SrcBDest_Y2(-1) | 233 bundle &= ~(create_SrcBDest_Y2(-1) |
235 create_Opcode_Y2(-1)); 234 create_Opcode_Y2(-1));
@@ -389,7 +388,7 @@ void single_step_once(struct pt_regs *regs)
389 state->branch_next_pc = 0; 388 state->branch_next_pc = 0;
390 state->update = 0; 389 state->update = 0;
391 390
392 if (!(bundle & TILE_BUNDLE_Y_ENCODING_MASK)) { 391 if (!(bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK)) {
393 /* two wide, check for control flow */ 392 /* two wide, check for control flow */
394 int opcode = get_Opcode_X1(bundle); 393 int opcode = get_Opcode_X1(bundle);
395 394
diff --git a/arch/tile/kernel/tile-desc_32.c b/arch/tile/kernel/tile-desc_32.c
index 7e31a1285788..dd7bd1d8563c 100644
--- a/arch/tile/kernel/tile-desc_32.c
+++ b/arch/tile/kernel/tile-desc_32.c
@@ -1,3 +1,23 @@
1/* TILEPro opcode information.
2 *
3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 *
16 *
17 *
18 *
19 */
20
1/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */ 21/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
2#define BFD_RELOC(x) -1 22#define BFD_RELOC(x) -1
3 23
@@ -6,1217 +26,1217 @@
6#define TREG_SN 56 26#define TREG_SN 56
7#define TREG_ZERO 63 27#define TREG_ZERO 63
8 28
9/* FIXME: Rename this. */
10#include <asm/opcode-tile.h>
11
12#include <linux/stddef.h> 29#include <linux/stddef.h>
30#include <asm/tile-desc.h>
13 31
14const struct tile_opcode tile_opcodes[395] = 32const struct tilepro_opcode tilepro_opcodes[395] =
15{ 33{
16 { "bpt", TILE_OPC_BPT, 0x2, 0, TREG_ZERO, 0, 34 { "bpt", TILEPRO_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
17 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 35 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
18 }, 36 },
19 { "info", TILE_OPC_INFO, 0xf, 1, TREG_ZERO, 1, 37 { "info", TILEPRO_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
20 { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } }, 38 { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
21 }, 39 },
22 { "infol", TILE_OPC_INFOL, 0x3, 1, TREG_ZERO, 1, 40 { "infol", TILEPRO_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
23 { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } }, 41 { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
24 }, 42 },
25 { "j", TILE_OPC_J, 0x2, 1, TREG_ZERO, 1, 43 { "j", TILEPRO_OPC_J, 0x2, 1, TREG_ZERO, 1,
26 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } }, 44 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
27 }, 45 },
28 { "jal", TILE_OPC_JAL, 0x2, 1, TREG_LR, 1, 46 { "jal", TILEPRO_OPC_JAL, 0x2, 1, TREG_LR, 1,
29 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } }, 47 { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
30 }, 48 },
31 { "move", TILE_OPC_MOVE, 0xf, 2, TREG_ZERO, 1, 49 { "move", TILEPRO_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
32 { { 7, 8 }, { 9, 10 }, { 11, 12 }, { 13, 14 }, { 0, } }, 50 { { 7, 8 }, { 9, 10 }, { 11, 12 }, { 13, 14 }, { 0, } },
33 }, 51 },
34 { "move.sn", TILE_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1, 52 { "move.sn", TILEPRO_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1,
35 { { 7, 8 }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 53 { { 7, 8 }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
36 }, 54 },
37 { "movei", TILE_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1, 55 { "movei", TILEPRO_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
38 { { 7, 0 }, { 9, 1 }, { 11, 2 }, { 13, 3 }, { 0, } }, 56 { { 7, 0 }, { 9, 1 }, { 11, 2 }, { 13, 3 }, { 0, } },
39 }, 57 },
40 { "movei.sn", TILE_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1, 58 { "movei.sn", TILEPRO_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1,
41 { { 7, 0 }, { 9, 1 }, { 0, }, { 0, }, { 0, } }, 59 { { 7, 0 }, { 9, 1 }, { 0, }, { 0, }, { 0, } },
42 }, 60 },
43 { "moveli", TILE_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1, 61 { "moveli", TILEPRO_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
44 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } }, 62 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
45 }, 63 },
46 { "moveli.sn", TILE_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1, 64 { "moveli.sn", TILEPRO_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1,
47 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } }, 65 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
48 }, 66 },
49 { "movelis", TILE_OPC_MOVELIS, 0x3, 2, TREG_SN, 1, 67 { "movelis", TILEPRO_OPC_MOVELIS, 0x3, 2, TREG_SN, 1,
50 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } }, 68 { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
51 }, 69 },
52 { "prefetch", TILE_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1, 70 { "prefetch", TILEPRO_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
53 { { 0, }, { 10 }, { 0, }, { 0, }, { 15 } }, 71 { { 0, }, { 10 }, { 0, }, { 0, }, { 15 } },
54 }, 72 },
55 { "raise", TILE_OPC_RAISE, 0x2, 0, TREG_ZERO, 1, 73 { "raise", TILEPRO_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
56 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 74 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
57 }, 75 },
58 { "add", TILE_OPC_ADD, 0xf, 3, TREG_ZERO, 1, 76 { "add", TILEPRO_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
59 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 77 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
60 }, 78 },
61 { "add.sn", TILE_OPC_ADD_SN, 0x3, 3, TREG_SN, 1, 79 { "add.sn", TILEPRO_OPC_ADD_SN, 0x3, 3, TREG_SN, 1,
62 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 80 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
63 }, 81 },
64 { "addb", TILE_OPC_ADDB, 0x3, 3, TREG_ZERO, 1, 82 { "addb", TILEPRO_OPC_ADDB, 0x3, 3, TREG_ZERO, 1,
65 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 83 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
66 }, 84 },
67 { "addb.sn", TILE_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1, 85 { "addb.sn", TILEPRO_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1,
68 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 86 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
69 }, 87 },
70 { "addbs_u", TILE_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1, 88 { "addbs_u", TILEPRO_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1,
71 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 89 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
72 }, 90 },
73 { "addbs_u.sn", TILE_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1, 91 { "addbs_u.sn", TILEPRO_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1,
74 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 92 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
75 }, 93 },
76 { "addh", TILE_OPC_ADDH, 0x3, 3, TREG_ZERO, 1, 94 { "addh", TILEPRO_OPC_ADDH, 0x3, 3, TREG_ZERO, 1,
77 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 95 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
78 }, 96 },
79 { "addh.sn", TILE_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1, 97 { "addh.sn", TILEPRO_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1,
80 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 98 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
81 }, 99 },
82 { "addhs", TILE_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1, 100 { "addhs", TILEPRO_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1,
83 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 101 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
84 }, 102 },
85 { "addhs.sn", TILE_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1, 103 { "addhs.sn", TILEPRO_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1,
86 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 104 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
87 }, 105 },
88 { "addi", TILE_OPC_ADDI, 0xf, 3, TREG_ZERO, 1, 106 { "addi", TILEPRO_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
89 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 107 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
90 }, 108 },
91 { "addi.sn", TILE_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1, 109 { "addi.sn", TILEPRO_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1,
92 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 110 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
93 }, 111 },
94 { "addib", TILE_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1, 112 { "addib", TILEPRO_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1,
95 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 113 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
96 }, 114 },
97 { "addib.sn", TILE_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1, 115 { "addib.sn", TILEPRO_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1,
98 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 116 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
99 }, 117 },
100 { "addih", TILE_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1, 118 { "addih", TILEPRO_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1,
101 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 119 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
102 }, 120 },
103 { "addih.sn", TILE_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1, 121 { "addih.sn", TILEPRO_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1,
104 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 122 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
105 }, 123 },
106 { "addli", TILE_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1, 124 { "addli", TILEPRO_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
107 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } }, 125 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
108 }, 126 },
109 { "addli.sn", TILE_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1, 127 { "addli.sn", TILEPRO_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1,
110 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } }, 128 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
111 }, 129 },
112 { "addlis", TILE_OPC_ADDLIS, 0x3, 3, TREG_SN, 1, 130 { "addlis", TILEPRO_OPC_ADDLIS, 0x3, 3, TREG_SN, 1,
113 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } }, 131 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
114 }, 132 },
115 { "adds", TILE_OPC_ADDS, 0x3, 3, TREG_ZERO, 1, 133 { "adds", TILEPRO_OPC_ADDS, 0x3, 3, TREG_ZERO, 1,
116 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 134 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
117 }, 135 },
118 { "adds.sn", TILE_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1, 136 { "adds.sn", TILEPRO_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1,
119 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 137 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
120 }, 138 },
121 { "adiffb_u", TILE_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1, 139 { "adiffb_u", TILEPRO_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1,
122 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 140 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
123 }, 141 },
124 { "adiffb_u.sn", TILE_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1, 142 { "adiffb_u.sn", TILEPRO_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1,
125 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 143 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
126 }, 144 },
127 { "adiffh", TILE_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1, 145 { "adiffh", TILEPRO_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1,
128 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 146 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
129 }, 147 },
130 { "adiffh.sn", TILE_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1, 148 { "adiffh.sn", TILEPRO_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1,
131 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 149 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
132 }, 150 },
133 { "and", TILE_OPC_AND, 0xf, 3, TREG_ZERO, 1, 151 { "and", TILEPRO_OPC_AND, 0xf, 3, TREG_ZERO, 1,
134 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 152 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
135 }, 153 },
136 { "and.sn", TILE_OPC_AND_SN, 0x3, 3, TREG_SN, 1, 154 { "and.sn", TILEPRO_OPC_AND_SN, 0x3, 3, TREG_SN, 1,
137 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 155 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
138 }, 156 },
139 { "andi", TILE_OPC_ANDI, 0xf, 3, TREG_ZERO, 1, 157 { "andi", TILEPRO_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
140 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 158 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
141 }, 159 },
142 { "andi.sn", TILE_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1, 160 { "andi.sn", TILEPRO_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1,
143 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 161 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
144 }, 162 },
145 { "auli", TILE_OPC_AULI, 0x3, 3, TREG_ZERO, 1, 163 { "auli", TILEPRO_OPC_AULI, 0x3, 3, TREG_ZERO, 1,
146 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } }, 164 { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
147 }, 165 },
148 { "avgb_u", TILE_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1, 166 { "avgb_u", TILEPRO_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1,
149 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 167 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
150 }, 168 },
151 { "avgb_u.sn", TILE_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1, 169 { "avgb_u.sn", TILEPRO_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1,
152 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 170 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
153 }, 171 },
154 { "avgh", TILE_OPC_AVGH, 0x1, 3, TREG_ZERO, 1, 172 { "avgh", TILEPRO_OPC_AVGH, 0x1, 3, TREG_ZERO, 1,
155 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 173 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
156 }, 174 },
157 { "avgh.sn", TILE_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1, 175 { "avgh.sn", TILEPRO_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1,
158 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 176 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
159 }, 177 },
160 { "bbns", TILE_OPC_BBNS, 0x2, 2, TREG_ZERO, 1, 178 { "bbns", TILEPRO_OPC_BBNS, 0x2, 2, TREG_ZERO, 1,
161 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 179 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
162 }, 180 },
163 { "bbns.sn", TILE_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1, 181 { "bbns.sn", TILEPRO_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1,
164 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 182 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
165 }, 183 },
166 { "bbnst", TILE_OPC_BBNST, 0x2, 2, TREG_ZERO, 1, 184 { "bbnst", TILEPRO_OPC_BBNST, 0x2, 2, TREG_ZERO, 1,
167 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 185 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
168 }, 186 },
169 { "bbnst.sn", TILE_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1, 187 { "bbnst.sn", TILEPRO_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1,
170 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 188 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
171 }, 189 },
172 { "bbs", TILE_OPC_BBS, 0x2, 2, TREG_ZERO, 1, 190 { "bbs", TILEPRO_OPC_BBS, 0x2, 2, TREG_ZERO, 1,
173 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 191 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
174 }, 192 },
175 { "bbs.sn", TILE_OPC_BBS_SN, 0x2, 2, TREG_SN, 1, 193 { "bbs.sn", TILEPRO_OPC_BBS_SN, 0x2, 2, TREG_SN, 1,
176 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 194 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
177 }, 195 },
178 { "bbst", TILE_OPC_BBST, 0x2, 2, TREG_ZERO, 1, 196 { "bbst", TILEPRO_OPC_BBST, 0x2, 2, TREG_ZERO, 1,
179 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 197 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
180 }, 198 },
181 { "bbst.sn", TILE_OPC_BBST_SN, 0x2, 2, TREG_SN, 1, 199 { "bbst.sn", TILEPRO_OPC_BBST_SN, 0x2, 2, TREG_SN, 1,
182 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 200 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
183 }, 201 },
184 { "bgez", TILE_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1, 202 { "bgez", TILEPRO_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
185 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 203 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
186 }, 204 },
187 { "bgez.sn", TILE_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1, 205 { "bgez.sn", TILEPRO_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1,
188 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 206 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
189 }, 207 },
190 { "bgezt", TILE_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1, 208 { "bgezt", TILEPRO_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
191 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 209 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
192 }, 210 },
193 { "bgezt.sn", TILE_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1, 211 { "bgezt.sn", TILEPRO_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1,
194 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 212 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
195 }, 213 },
196 { "bgz", TILE_OPC_BGZ, 0x2, 2, TREG_ZERO, 1, 214 { "bgz", TILEPRO_OPC_BGZ, 0x2, 2, TREG_ZERO, 1,
197 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 215 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
198 }, 216 },
199 { "bgz.sn", TILE_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1, 217 { "bgz.sn", TILEPRO_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1,
200 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 218 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
201 }, 219 },
202 { "bgzt", TILE_OPC_BGZT, 0x2, 2, TREG_ZERO, 1, 220 { "bgzt", TILEPRO_OPC_BGZT, 0x2, 2, TREG_ZERO, 1,
203 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 221 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
204 }, 222 },
205 { "bgzt.sn", TILE_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1, 223 { "bgzt.sn", TILEPRO_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1,
206 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 224 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
207 }, 225 },
208 { "bitx", TILE_OPC_BITX, 0x5, 2, TREG_ZERO, 1, 226 { "bitx", TILEPRO_OPC_BITX, 0x5, 2, TREG_ZERO, 1,
209 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } }, 227 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
210 }, 228 },
211 { "bitx.sn", TILE_OPC_BITX_SN, 0x1, 2, TREG_SN, 1, 229 { "bitx.sn", TILEPRO_OPC_BITX_SN, 0x1, 2, TREG_SN, 1,
212 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 230 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
213 }, 231 },
214 { "blez", TILE_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1, 232 { "blez", TILEPRO_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
215 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 233 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
216 }, 234 },
217 { "blez.sn", TILE_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1, 235 { "blez.sn", TILEPRO_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1,
218 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 236 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
219 }, 237 },
220 { "blezt", TILE_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1, 238 { "blezt", TILEPRO_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
221 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 239 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
222 }, 240 },
223 { "blezt.sn", TILE_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1, 241 { "blezt.sn", TILEPRO_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1,
224 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 242 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
225 }, 243 },
226 { "blz", TILE_OPC_BLZ, 0x2, 2, TREG_ZERO, 1, 244 { "blz", TILEPRO_OPC_BLZ, 0x2, 2, TREG_ZERO, 1,
227 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 245 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
228 }, 246 },
229 { "blz.sn", TILE_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1, 247 { "blz.sn", TILEPRO_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1,
230 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 248 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
231 }, 249 },
232 { "blzt", TILE_OPC_BLZT, 0x2, 2, TREG_ZERO, 1, 250 { "blzt", TILEPRO_OPC_BLZT, 0x2, 2, TREG_ZERO, 1,
233 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 251 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
234 }, 252 },
235 { "blzt.sn", TILE_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1, 253 { "blzt.sn", TILEPRO_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1,
236 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 254 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
237 }, 255 },
238 { "bnz", TILE_OPC_BNZ, 0x2, 2, TREG_ZERO, 1, 256 { "bnz", TILEPRO_OPC_BNZ, 0x2, 2, TREG_ZERO, 1,
239 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 257 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
240 }, 258 },
241 { "bnz.sn", TILE_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1, 259 { "bnz.sn", TILEPRO_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1,
242 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 260 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
243 }, 261 },
244 { "bnzt", TILE_OPC_BNZT, 0x2, 2, TREG_ZERO, 1, 262 { "bnzt", TILEPRO_OPC_BNZT, 0x2, 2, TREG_ZERO, 1,
245 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 263 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
246 }, 264 },
247 { "bnzt.sn", TILE_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1, 265 { "bnzt.sn", TILEPRO_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1,
248 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 266 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
249 }, 267 },
250 { "bytex", TILE_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1, 268 { "bytex", TILEPRO_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1,
251 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } }, 269 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
252 }, 270 },
253 { "bytex.sn", TILE_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1, 271 { "bytex.sn", TILEPRO_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1,
254 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 272 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
255 }, 273 },
256 { "bz", TILE_OPC_BZ, 0x2, 2, TREG_ZERO, 1, 274 { "bz", TILEPRO_OPC_BZ, 0x2, 2, TREG_ZERO, 1,
257 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 275 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
258 }, 276 },
259 { "bz.sn", TILE_OPC_BZ_SN, 0x2, 2, TREG_SN, 1, 277 { "bz.sn", TILEPRO_OPC_BZ_SN, 0x2, 2, TREG_SN, 1,
260 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 278 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
261 }, 279 },
262 { "bzt", TILE_OPC_BZT, 0x2, 2, TREG_ZERO, 1, 280 { "bzt", TILEPRO_OPC_BZT, 0x2, 2, TREG_ZERO, 1,
263 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 281 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
264 }, 282 },
265 { "bzt.sn", TILE_OPC_BZT_SN, 0x2, 2, TREG_SN, 1, 283 { "bzt.sn", TILEPRO_OPC_BZT_SN, 0x2, 2, TREG_SN, 1,
266 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } }, 284 { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
267 }, 285 },
268 { "clz", TILE_OPC_CLZ, 0x5, 2, TREG_ZERO, 1, 286 { "clz", TILEPRO_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
269 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } }, 287 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
270 }, 288 },
271 { "clz.sn", TILE_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1, 289 { "clz.sn", TILEPRO_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1,
272 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 290 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
273 }, 291 },
274 { "crc32_32", TILE_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1, 292 { "crc32_32", TILEPRO_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
275 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 293 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
276 }, 294 },
277 { "crc32_32.sn", TILE_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1, 295 { "crc32_32.sn", TILEPRO_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1,
278 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 296 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
279 }, 297 },
280 { "crc32_8", TILE_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1, 298 { "crc32_8", TILEPRO_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
281 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 299 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
282 }, 300 },
283 { "crc32_8.sn", TILE_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1, 301 { "crc32_8.sn", TILEPRO_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1,
284 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 302 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
285 }, 303 },
286 { "ctz", TILE_OPC_CTZ, 0x5, 2, TREG_ZERO, 1, 304 { "ctz", TILEPRO_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
287 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } }, 305 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
288 }, 306 },
289 { "ctz.sn", TILE_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1, 307 { "ctz.sn", TILEPRO_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1,
290 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 308 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
291 }, 309 },
292 { "drain", TILE_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0, 310 { "drain", TILEPRO_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
293 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 311 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
294 }, 312 },
295 { "dtlbpr", TILE_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1, 313 { "dtlbpr", TILEPRO_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
296 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 314 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
297 }, 315 },
298 { "dword_align", TILE_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1, 316 { "dword_align", TILEPRO_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1,
299 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 317 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
300 }, 318 },
301 { "dword_align.sn", TILE_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1, 319 { "dword_align.sn", TILEPRO_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1,
302 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 320 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
303 }, 321 },
304 { "finv", TILE_OPC_FINV, 0x2, 1, TREG_ZERO, 1, 322 { "finv", TILEPRO_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
305 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 323 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
306 }, 324 },
307 { "flush", TILE_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1, 325 { "flush", TILEPRO_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
308 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 326 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
309 }, 327 },
310 { "fnop", TILE_OPC_FNOP, 0xf, 0, TREG_ZERO, 1, 328 { "fnop", TILEPRO_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
311 { { }, { }, { }, { }, { 0, } }, 329 { { }, { }, { }, { }, { 0, } },
312 }, 330 },
313 { "icoh", TILE_OPC_ICOH, 0x2, 1, TREG_ZERO, 1, 331 { "icoh", TILEPRO_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
314 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 332 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
315 }, 333 },
316 { "ill", TILE_OPC_ILL, 0xa, 0, TREG_ZERO, 1, 334 { "ill", TILEPRO_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
317 { { 0, }, { }, { 0, }, { }, { 0, } }, 335 { { 0, }, { }, { 0, }, { }, { 0, } },
318 }, 336 },
319 { "inthb", TILE_OPC_INTHB, 0x3, 3, TREG_ZERO, 1, 337 { "inthb", TILEPRO_OPC_INTHB, 0x3, 3, TREG_ZERO, 1,
320 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 338 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
321 }, 339 },
322 { "inthb.sn", TILE_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1, 340 { "inthb.sn", TILEPRO_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1,
323 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 341 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
324 }, 342 },
325 { "inthh", TILE_OPC_INTHH, 0x3, 3, TREG_ZERO, 1, 343 { "inthh", TILEPRO_OPC_INTHH, 0x3, 3, TREG_ZERO, 1,
326 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 344 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
327 }, 345 },
328 { "inthh.sn", TILE_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1, 346 { "inthh.sn", TILEPRO_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1,
329 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 347 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
330 }, 348 },
331 { "intlb", TILE_OPC_INTLB, 0x3, 3, TREG_ZERO, 1, 349 { "intlb", TILEPRO_OPC_INTLB, 0x3, 3, TREG_ZERO, 1,
332 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 350 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
333 }, 351 },
334 { "intlb.sn", TILE_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1, 352 { "intlb.sn", TILEPRO_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1,
335 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 353 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
336 }, 354 },
337 { "intlh", TILE_OPC_INTLH, 0x3, 3, TREG_ZERO, 1, 355 { "intlh", TILEPRO_OPC_INTLH, 0x3, 3, TREG_ZERO, 1,
338 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 356 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
339 }, 357 },
340 { "intlh.sn", TILE_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1, 358 { "intlh.sn", TILEPRO_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1,
341 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 359 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
342 }, 360 },
343 { "inv", TILE_OPC_INV, 0x2, 1, TREG_ZERO, 1, 361 { "inv", TILEPRO_OPC_INV, 0x2, 1, TREG_ZERO, 1,
344 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 362 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
345 }, 363 },
346 { "iret", TILE_OPC_IRET, 0x2, 0, TREG_ZERO, 1, 364 { "iret", TILEPRO_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
347 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 365 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
348 }, 366 },
349 { "jalb", TILE_OPC_JALB, 0x2, 1, TREG_LR, 1, 367 { "jalb", TILEPRO_OPC_JALB, 0x2, 1, TREG_LR, 1,
350 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } }, 368 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
351 }, 369 },
352 { "jalf", TILE_OPC_JALF, 0x2, 1, TREG_LR, 1, 370 { "jalf", TILEPRO_OPC_JALF, 0x2, 1, TREG_LR, 1,
353 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } }, 371 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
354 }, 372 },
355 { "jalr", TILE_OPC_JALR, 0x2, 1, TREG_LR, 1, 373 { "jalr", TILEPRO_OPC_JALR, 0x2, 1, TREG_LR, 1,
356 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 374 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
357 }, 375 },
358 { "jalrp", TILE_OPC_JALRP, 0x2, 1, TREG_LR, 1, 376 { "jalrp", TILEPRO_OPC_JALRP, 0x2, 1, TREG_LR, 1,
359 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 377 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
360 }, 378 },
361 { "jb", TILE_OPC_JB, 0x2, 1, TREG_ZERO, 1, 379 { "jb", TILEPRO_OPC_JB, 0x2, 1, TREG_ZERO, 1,
362 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } }, 380 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
363 }, 381 },
364 { "jf", TILE_OPC_JF, 0x2, 1, TREG_ZERO, 1, 382 { "jf", TILEPRO_OPC_JF, 0x2, 1, TREG_ZERO, 1,
365 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } }, 383 { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
366 }, 384 },
367 { "jr", TILE_OPC_JR, 0x2, 1, TREG_ZERO, 1, 385 { "jr", TILEPRO_OPC_JR, 0x2, 1, TREG_ZERO, 1,
368 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 386 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
369 }, 387 },
370 { "jrp", TILE_OPC_JRP, 0x2, 1, TREG_ZERO, 1, 388 { "jrp", TILEPRO_OPC_JRP, 0x2, 1, TREG_ZERO, 1,
371 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 389 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
372 }, 390 },
373 { "lb", TILE_OPC_LB, 0x12, 2, TREG_ZERO, 1, 391 { "lb", TILEPRO_OPC_LB, 0x12, 2, TREG_ZERO, 1,
374 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } }, 392 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
375 }, 393 },
376 { "lb.sn", TILE_OPC_LB_SN, 0x2, 2, TREG_SN, 1, 394 { "lb.sn", TILEPRO_OPC_LB_SN, 0x2, 2, TREG_SN, 1,
377 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 395 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
378 }, 396 },
379 { "lb_u", TILE_OPC_LB_U, 0x12, 2, TREG_ZERO, 1, 397 { "lb_u", TILEPRO_OPC_LB_U, 0x12, 2, TREG_ZERO, 1,
380 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } }, 398 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
381 }, 399 },
382 { "lb_u.sn", TILE_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1, 400 { "lb_u.sn", TILEPRO_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1,
383 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 401 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
384 }, 402 },
385 { "lbadd", TILE_OPC_LBADD, 0x2, 3, TREG_ZERO, 1, 403 { "lbadd", TILEPRO_OPC_LBADD, 0x2, 3, TREG_ZERO, 1,
386 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 404 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
387 }, 405 },
388 { "lbadd.sn", TILE_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1, 406 { "lbadd.sn", TILEPRO_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1,
389 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 407 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
390 }, 408 },
391 { "lbadd_u", TILE_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1, 409 { "lbadd_u", TILEPRO_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1,
392 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 410 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
393 }, 411 },
394 { "lbadd_u.sn", TILE_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1, 412 { "lbadd_u.sn", TILEPRO_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1,
395 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 413 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
396 }, 414 },
397 { "lh", TILE_OPC_LH, 0x12, 2, TREG_ZERO, 1, 415 { "lh", TILEPRO_OPC_LH, 0x12, 2, TREG_ZERO, 1,
398 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } }, 416 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
399 }, 417 },
400 { "lh.sn", TILE_OPC_LH_SN, 0x2, 2, TREG_SN, 1, 418 { "lh.sn", TILEPRO_OPC_LH_SN, 0x2, 2, TREG_SN, 1,
401 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 419 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
402 }, 420 },
403 { "lh_u", TILE_OPC_LH_U, 0x12, 2, TREG_ZERO, 1, 421 { "lh_u", TILEPRO_OPC_LH_U, 0x12, 2, TREG_ZERO, 1,
404 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } }, 422 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
405 }, 423 },
406 { "lh_u.sn", TILE_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1, 424 { "lh_u.sn", TILEPRO_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1,
407 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 425 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
408 }, 426 },
409 { "lhadd", TILE_OPC_LHADD, 0x2, 3, TREG_ZERO, 1, 427 { "lhadd", TILEPRO_OPC_LHADD, 0x2, 3, TREG_ZERO, 1,
410 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 428 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
411 }, 429 },
412 { "lhadd.sn", TILE_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1, 430 { "lhadd.sn", TILEPRO_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1,
413 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 431 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
414 }, 432 },
415 { "lhadd_u", TILE_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1, 433 { "lhadd_u", TILEPRO_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1,
416 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 434 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
417 }, 435 },
418 { "lhadd_u.sn", TILE_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1, 436 { "lhadd_u.sn", TILEPRO_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1,
419 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 437 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
420 }, 438 },
421 { "lnk", TILE_OPC_LNK, 0x2, 1, TREG_ZERO, 1, 439 { "lnk", TILEPRO_OPC_LNK, 0x2, 1, TREG_ZERO, 1,
422 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } }, 440 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
423 }, 441 },
424 { "lnk.sn", TILE_OPC_LNK_SN, 0x2, 1, TREG_SN, 1, 442 { "lnk.sn", TILEPRO_OPC_LNK_SN, 0x2, 1, TREG_SN, 1,
425 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } }, 443 { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
426 }, 444 },
427 { "lw", TILE_OPC_LW, 0x12, 2, TREG_ZERO, 1, 445 { "lw", TILEPRO_OPC_LW, 0x12, 2, TREG_ZERO, 1,
428 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } }, 446 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
429 }, 447 },
430 { "lw.sn", TILE_OPC_LW_SN, 0x2, 2, TREG_SN, 1, 448 { "lw.sn", TILEPRO_OPC_LW_SN, 0x2, 2, TREG_SN, 1,
431 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 449 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
432 }, 450 },
433 { "lw_na", TILE_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1, 451 { "lw_na", TILEPRO_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1,
434 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 452 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
435 }, 453 },
436 { "lw_na.sn", TILE_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1, 454 { "lw_na.sn", TILEPRO_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1,
437 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 455 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
438 }, 456 },
439 { "lwadd", TILE_OPC_LWADD, 0x2, 3, TREG_ZERO, 1, 457 { "lwadd", TILEPRO_OPC_LWADD, 0x2, 3, TREG_ZERO, 1,
440 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 458 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
441 }, 459 },
442 { "lwadd.sn", TILE_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1, 460 { "lwadd.sn", TILEPRO_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1,
443 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 461 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
444 }, 462 },
445 { "lwadd_na", TILE_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1, 463 { "lwadd_na", TILEPRO_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1,
446 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 464 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
447 }, 465 },
448 { "lwadd_na.sn", TILE_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1, 466 { "lwadd_na.sn", TILEPRO_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1,
449 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } }, 467 { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
450 }, 468 },
451 { "maxb_u", TILE_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1, 469 { "maxb_u", TILEPRO_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1,
452 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 470 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
453 }, 471 },
454 { "maxb_u.sn", TILE_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1, 472 { "maxb_u.sn", TILEPRO_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1,
455 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 473 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
456 }, 474 },
457 { "maxh", TILE_OPC_MAXH, 0x3, 3, TREG_ZERO, 1, 475 { "maxh", TILEPRO_OPC_MAXH, 0x3, 3, TREG_ZERO, 1,
458 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 476 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
459 }, 477 },
460 { "maxh.sn", TILE_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1, 478 { "maxh.sn", TILEPRO_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1,
461 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 479 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
462 }, 480 },
463 { "maxib_u", TILE_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1, 481 { "maxib_u", TILEPRO_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1,
464 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 482 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
465 }, 483 },
466 { "maxib_u.sn", TILE_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1, 484 { "maxib_u.sn", TILEPRO_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1,
467 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 485 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
468 }, 486 },
469 { "maxih", TILE_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1, 487 { "maxih", TILEPRO_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1,
470 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 488 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
471 }, 489 },
472 { "maxih.sn", TILE_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1, 490 { "maxih.sn", TILEPRO_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1,
473 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 491 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
474 }, 492 },
475 { "mf", TILE_OPC_MF, 0x2, 0, TREG_ZERO, 1, 493 { "mf", TILEPRO_OPC_MF, 0x2, 0, TREG_ZERO, 1,
476 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 494 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
477 }, 495 },
478 { "mfspr", TILE_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1, 496 { "mfspr", TILEPRO_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
479 { { 0, }, { 9, 25 }, { 0, }, { 0, }, { 0, } }, 497 { { 0, }, { 9, 25 }, { 0, }, { 0, }, { 0, } },
480 }, 498 },
481 { "minb_u", TILE_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1, 499 { "minb_u", TILEPRO_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1,
482 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 500 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
483 }, 501 },
484 { "minb_u.sn", TILE_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1, 502 { "minb_u.sn", TILEPRO_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1,
485 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 503 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
486 }, 504 },
487 { "minh", TILE_OPC_MINH, 0x3, 3, TREG_ZERO, 1, 505 { "minh", TILEPRO_OPC_MINH, 0x3, 3, TREG_ZERO, 1,
488 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 506 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
489 }, 507 },
490 { "minh.sn", TILE_OPC_MINH_SN, 0x3, 3, TREG_SN, 1, 508 { "minh.sn", TILEPRO_OPC_MINH_SN, 0x3, 3, TREG_SN, 1,
491 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 509 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
492 }, 510 },
493 { "minib_u", TILE_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1, 511 { "minib_u", TILEPRO_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1,
494 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 512 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
495 }, 513 },
496 { "minib_u.sn", TILE_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1, 514 { "minib_u.sn", TILEPRO_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1,
497 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 515 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
498 }, 516 },
499 { "minih", TILE_OPC_MINIH, 0x3, 3, TREG_ZERO, 1, 517 { "minih", TILEPRO_OPC_MINIH, 0x3, 3, TREG_ZERO, 1,
500 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 518 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
501 }, 519 },
502 { "minih.sn", TILE_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1, 520 { "minih.sn", TILEPRO_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1,
503 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 521 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
504 }, 522 },
505 { "mm", TILE_OPC_MM, 0x3, 5, TREG_ZERO, 1, 523 { "mm", TILEPRO_OPC_MM, 0x3, 5, TREG_ZERO, 1,
506 { { 7, 8, 16, 26, 27 }, { 9, 10, 17, 28, 29 }, { 0, }, { 0, }, { 0, } }, 524 { { 7, 8, 16, 26, 27 }, { 9, 10, 17, 28, 29 }, { 0, }, { 0, }, { 0, } },
507 }, 525 },
508 { "mnz", TILE_OPC_MNZ, 0xf, 3, TREG_ZERO, 1, 526 { "mnz", TILEPRO_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
509 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 527 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
510 }, 528 },
511 { "mnz.sn", TILE_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1, 529 { "mnz.sn", TILEPRO_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1,
512 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 530 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
513 }, 531 },
514 { "mnzb", TILE_OPC_MNZB, 0x3, 3, TREG_ZERO, 1, 532 { "mnzb", TILEPRO_OPC_MNZB, 0x3, 3, TREG_ZERO, 1,
515 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 533 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
516 }, 534 },
517 { "mnzb.sn", TILE_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1, 535 { "mnzb.sn", TILEPRO_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1,
518 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 536 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
519 }, 537 },
520 { "mnzh", TILE_OPC_MNZH, 0x3, 3, TREG_ZERO, 1, 538 { "mnzh", TILEPRO_OPC_MNZH, 0x3, 3, TREG_ZERO, 1,
521 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 539 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
522 }, 540 },
523 { "mnzh.sn", TILE_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1, 541 { "mnzh.sn", TILEPRO_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1,
524 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 542 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
525 }, 543 },
526 { "mtspr", TILE_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1, 544 { "mtspr", TILEPRO_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
527 { { 0, }, { 30, 10 }, { 0, }, { 0, }, { 0, } }, 545 { { 0, }, { 30, 10 }, { 0, }, { 0, }, { 0, } },
528 }, 546 },
529 { "mulhh_ss", TILE_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1, 547 { "mulhh_ss", TILEPRO_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1,
530 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } }, 548 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
531 }, 549 },
532 { "mulhh_ss.sn", TILE_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1, 550 { "mulhh_ss.sn", TILEPRO_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1,
533 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 551 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
534 }, 552 },
535 { "mulhh_su", TILE_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1, 553 { "mulhh_su", TILEPRO_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1,
536 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 554 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
537 }, 555 },
538 { "mulhh_su.sn", TILE_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1, 556 { "mulhh_su.sn", TILEPRO_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1,
539 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 557 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
540 }, 558 },
541 { "mulhh_uu", TILE_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1, 559 { "mulhh_uu", TILEPRO_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1,
542 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } }, 560 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
543 }, 561 },
544 { "mulhh_uu.sn", TILE_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1, 562 { "mulhh_uu.sn", TILEPRO_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1,
545 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 563 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
546 }, 564 },
547 { "mulhha_ss", TILE_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1, 565 { "mulhha_ss", TILEPRO_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1,
548 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 566 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
549 }, 567 },
550 { "mulhha_ss.sn", TILE_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1, 568 { "mulhha_ss.sn", TILEPRO_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1,
551 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 569 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
552 }, 570 },
553 { "mulhha_su", TILE_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1, 571 { "mulhha_su", TILEPRO_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1,
554 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 572 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
555 }, 573 },
556 { "mulhha_su.sn", TILE_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1, 574 { "mulhha_su.sn", TILEPRO_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1,
557 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 575 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
558 }, 576 },
559 { "mulhha_uu", TILE_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1, 577 { "mulhha_uu", TILEPRO_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1,
560 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 578 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
561 }, 579 },
562 { "mulhha_uu.sn", TILE_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1, 580 { "mulhha_uu.sn", TILEPRO_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1,
563 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 581 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
564 }, 582 },
565 { "mulhhsa_uu", TILE_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1, 583 { "mulhhsa_uu", TILEPRO_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1,
566 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 584 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
567 }, 585 },
568 { "mulhhsa_uu.sn", TILE_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1, 586 { "mulhhsa_uu.sn", TILEPRO_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1,
569 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 587 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
570 }, 588 },
571 { "mulhl_ss", TILE_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1, 589 { "mulhl_ss", TILEPRO_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1,
572 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 590 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
573 }, 591 },
574 { "mulhl_ss.sn", TILE_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1, 592 { "mulhl_ss.sn", TILEPRO_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1,
575 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 593 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
576 }, 594 },
577 { "mulhl_su", TILE_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1, 595 { "mulhl_su", TILEPRO_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1,
578 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 596 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
579 }, 597 },
580 { "mulhl_su.sn", TILE_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1, 598 { "mulhl_su.sn", TILEPRO_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1,
581 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 599 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
582 }, 600 },
583 { "mulhl_us", TILE_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1, 601 { "mulhl_us", TILEPRO_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1,
584 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 602 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
585 }, 603 },
586 { "mulhl_us.sn", TILE_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1, 604 { "mulhl_us.sn", TILEPRO_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1,
587 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 605 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
588 }, 606 },
589 { "mulhl_uu", TILE_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1, 607 { "mulhl_uu", TILEPRO_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1,
590 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 608 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
591 }, 609 },
592 { "mulhl_uu.sn", TILE_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1, 610 { "mulhl_uu.sn", TILEPRO_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1,
593 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 611 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
594 }, 612 },
595 { "mulhla_ss", TILE_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1, 613 { "mulhla_ss", TILEPRO_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1,
596 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 614 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
597 }, 615 },
598 { "mulhla_ss.sn", TILE_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1, 616 { "mulhla_ss.sn", TILEPRO_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1,
599 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 617 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
600 }, 618 },
601 { "mulhla_su", TILE_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1, 619 { "mulhla_su", TILEPRO_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1,
602 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 620 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
603 }, 621 },
604 { "mulhla_su.sn", TILE_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1, 622 { "mulhla_su.sn", TILEPRO_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1,
605 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 623 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
606 }, 624 },
607 { "mulhla_us", TILE_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1, 625 { "mulhla_us", TILEPRO_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1,
608 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 626 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
609 }, 627 },
610 { "mulhla_us.sn", TILE_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1, 628 { "mulhla_us.sn", TILEPRO_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1,
611 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 629 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
612 }, 630 },
613 { "mulhla_uu", TILE_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1, 631 { "mulhla_uu", TILEPRO_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1,
614 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 632 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
615 }, 633 },
616 { "mulhla_uu.sn", TILE_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1, 634 { "mulhla_uu.sn", TILEPRO_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1,
617 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 635 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
618 }, 636 },
619 { "mulhlsa_uu", TILE_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1, 637 { "mulhlsa_uu", TILEPRO_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1,
620 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 638 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
621 }, 639 },
622 { "mulhlsa_uu.sn", TILE_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1, 640 { "mulhlsa_uu.sn", TILEPRO_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1,
623 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 641 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
624 }, 642 },
625 { "mulll_ss", TILE_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1, 643 { "mulll_ss", TILEPRO_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1,
626 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } }, 644 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
627 }, 645 },
628 { "mulll_ss.sn", TILE_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1, 646 { "mulll_ss.sn", TILEPRO_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1,
629 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 647 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
630 }, 648 },
631 { "mulll_su", TILE_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1, 649 { "mulll_su", TILEPRO_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1,
632 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 650 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
633 }, 651 },
634 { "mulll_su.sn", TILE_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1, 652 { "mulll_su.sn", TILEPRO_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1,
635 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 653 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
636 }, 654 },
637 { "mulll_uu", TILE_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1, 655 { "mulll_uu", TILEPRO_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1,
638 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } }, 656 { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
639 }, 657 },
640 { "mulll_uu.sn", TILE_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1, 658 { "mulll_uu.sn", TILEPRO_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1,
641 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 659 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
642 }, 660 },
643 { "mullla_ss", TILE_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1, 661 { "mullla_ss", TILEPRO_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1,
644 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 662 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
645 }, 663 },
646 { "mullla_ss.sn", TILE_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1, 664 { "mullla_ss.sn", TILEPRO_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1,
647 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 665 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
648 }, 666 },
649 { "mullla_su", TILE_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1, 667 { "mullla_su", TILEPRO_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1,
650 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 668 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
651 }, 669 },
652 { "mullla_su.sn", TILE_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1, 670 { "mullla_su.sn", TILEPRO_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1,
653 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 671 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
654 }, 672 },
655 { "mullla_uu", TILE_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1, 673 { "mullla_uu", TILEPRO_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1,
656 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 674 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
657 }, 675 },
658 { "mullla_uu.sn", TILE_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1, 676 { "mullla_uu.sn", TILEPRO_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1,
659 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 677 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
660 }, 678 },
661 { "mulllsa_uu", TILE_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1, 679 { "mulllsa_uu", TILEPRO_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1,
662 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 680 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
663 }, 681 },
664 { "mulllsa_uu.sn", TILE_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1, 682 { "mulllsa_uu.sn", TILEPRO_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1,
665 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 683 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
666 }, 684 },
667 { "mvnz", TILE_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1, 685 { "mvnz", TILEPRO_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1,
668 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 686 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
669 }, 687 },
670 { "mvnz.sn", TILE_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1, 688 { "mvnz.sn", TILEPRO_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1,
671 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 689 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
672 }, 690 },
673 { "mvz", TILE_OPC_MVZ, 0x5, 3, TREG_ZERO, 1, 691 { "mvz", TILEPRO_OPC_MVZ, 0x5, 3, TREG_ZERO, 1,
674 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } }, 692 { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
675 }, 693 },
676 { "mvz.sn", TILE_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1, 694 { "mvz.sn", TILEPRO_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1,
677 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 695 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
678 }, 696 },
679 { "mz", TILE_OPC_MZ, 0xf, 3, TREG_ZERO, 1, 697 { "mz", TILEPRO_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
680 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 698 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
681 }, 699 },
682 { "mz.sn", TILE_OPC_MZ_SN, 0x3, 3, TREG_SN, 1, 700 { "mz.sn", TILEPRO_OPC_MZ_SN, 0x3, 3, TREG_SN, 1,
683 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 701 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
684 }, 702 },
685 { "mzb", TILE_OPC_MZB, 0x3, 3, TREG_ZERO, 1, 703 { "mzb", TILEPRO_OPC_MZB, 0x3, 3, TREG_ZERO, 1,
686 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 704 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
687 }, 705 },
688 { "mzb.sn", TILE_OPC_MZB_SN, 0x3, 3, TREG_SN, 1, 706 { "mzb.sn", TILEPRO_OPC_MZB_SN, 0x3, 3, TREG_SN, 1,
689 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 707 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
690 }, 708 },
691 { "mzh", TILE_OPC_MZH, 0x3, 3, TREG_ZERO, 1, 709 { "mzh", TILEPRO_OPC_MZH, 0x3, 3, TREG_ZERO, 1,
692 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 710 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
693 }, 711 },
694 { "mzh.sn", TILE_OPC_MZH_SN, 0x3, 3, TREG_SN, 1, 712 { "mzh.sn", TILEPRO_OPC_MZH_SN, 0x3, 3, TREG_SN, 1,
695 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 713 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
696 }, 714 },
697 { "nap", TILE_OPC_NAP, 0x2, 0, TREG_ZERO, 0, 715 { "nap", TILEPRO_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
698 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 716 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
699 }, 717 },
700 { "nop", TILE_OPC_NOP, 0xf, 0, TREG_ZERO, 1, 718 { "nop", TILEPRO_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
701 { { }, { }, { }, { }, { 0, } }, 719 { { }, { }, { }, { }, { 0, } },
702 }, 720 },
703 { "nor", TILE_OPC_NOR, 0xf, 3, TREG_ZERO, 1, 721 { "nor", TILEPRO_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
704 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 722 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
705 }, 723 },
706 { "nor.sn", TILE_OPC_NOR_SN, 0x3, 3, TREG_SN, 1, 724 { "nor.sn", TILEPRO_OPC_NOR_SN, 0x3, 3, TREG_SN, 1,
707 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 725 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
708 }, 726 },
709 { "or", TILE_OPC_OR, 0xf, 3, TREG_ZERO, 1, 727 { "or", TILEPRO_OPC_OR, 0xf, 3, TREG_ZERO, 1,
710 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 728 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
711 }, 729 },
712 { "or.sn", TILE_OPC_OR_SN, 0x3, 3, TREG_SN, 1, 730 { "or.sn", TILEPRO_OPC_OR_SN, 0x3, 3, TREG_SN, 1,
713 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 731 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
714 }, 732 },
715 { "ori", TILE_OPC_ORI, 0xf, 3, TREG_ZERO, 1, 733 { "ori", TILEPRO_OPC_ORI, 0xf, 3, TREG_ZERO, 1,
716 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 734 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
717 }, 735 },
718 { "ori.sn", TILE_OPC_ORI_SN, 0x3, 3, TREG_SN, 1, 736 { "ori.sn", TILEPRO_OPC_ORI_SN, 0x3, 3, TREG_SN, 1,
719 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 737 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
720 }, 738 },
721 { "packbs_u", TILE_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1, 739 { "packbs_u", TILEPRO_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1,
722 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 740 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
723 }, 741 },
724 { "packbs_u.sn", TILE_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1, 742 { "packbs_u.sn", TILEPRO_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1,
725 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 743 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
726 }, 744 },
727 { "packhb", TILE_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1, 745 { "packhb", TILEPRO_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1,
728 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 746 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
729 }, 747 },
730 { "packhb.sn", TILE_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1, 748 { "packhb.sn", TILEPRO_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1,
731 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 749 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
732 }, 750 },
733 { "packhs", TILE_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1, 751 { "packhs", TILEPRO_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1,
734 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 752 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
735 }, 753 },
736 { "packhs.sn", TILE_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1, 754 { "packhs.sn", TILEPRO_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1,
737 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 755 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
738 }, 756 },
739 { "packlb", TILE_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1, 757 { "packlb", TILEPRO_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1,
740 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 758 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
741 }, 759 },
742 { "packlb.sn", TILE_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1, 760 { "packlb.sn", TILEPRO_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1,
743 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 761 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
744 }, 762 },
745 { "pcnt", TILE_OPC_PCNT, 0x5, 2, TREG_ZERO, 1, 763 { "pcnt", TILEPRO_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
746 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } }, 764 { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
747 }, 765 },
748 { "pcnt.sn", TILE_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1, 766 { "pcnt.sn", TILEPRO_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1,
749 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 767 { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
750 }, 768 },
751 { "rl", TILE_OPC_RL, 0xf, 3, TREG_ZERO, 1, 769 { "rl", TILEPRO_OPC_RL, 0xf, 3, TREG_ZERO, 1,
752 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 770 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
753 }, 771 },
754 { "rl.sn", TILE_OPC_RL_SN, 0x3, 3, TREG_SN, 1, 772 { "rl.sn", TILEPRO_OPC_RL_SN, 0x3, 3, TREG_SN, 1,
755 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 773 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
756 }, 774 },
757 { "rli", TILE_OPC_RLI, 0xf, 3, TREG_ZERO, 1, 775 { "rli", TILEPRO_OPC_RLI, 0xf, 3, TREG_ZERO, 1,
758 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } }, 776 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
759 }, 777 },
760 { "rli.sn", TILE_OPC_RLI_SN, 0x3, 3, TREG_SN, 1, 778 { "rli.sn", TILEPRO_OPC_RLI_SN, 0x3, 3, TREG_SN, 1,
761 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 779 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
762 }, 780 },
763 { "s1a", TILE_OPC_S1A, 0xf, 3, TREG_ZERO, 1, 781 { "s1a", TILEPRO_OPC_S1A, 0xf, 3, TREG_ZERO, 1,
764 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 782 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
765 }, 783 },
766 { "s1a.sn", TILE_OPC_S1A_SN, 0x3, 3, TREG_SN, 1, 784 { "s1a.sn", TILEPRO_OPC_S1A_SN, 0x3, 3, TREG_SN, 1,
767 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 785 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
768 }, 786 },
769 { "s2a", TILE_OPC_S2A, 0xf, 3, TREG_ZERO, 1, 787 { "s2a", TILEPRO_OPC_S2A, 0xf, 3, TREG_ZERO, 1,
770 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 788 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
771 }, 789 },
772 { "s2a.sn", TILE_OPC_S2A_SN, 0x3, 3, TREG_SN, 1, 790 { "s2a.sn", TILEPRO_OPC_S2A_SN, 0x3, 3, TREG_SN, 1,
773 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 791 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
774 }, 792 },
775 { "s3a", TILE_OPC_S3A, 0xf, 3, TREG_ZERO, 1, 793 { "s3a", TILEPRO_OPC_S3A, 0xf, 3, TREG_ZERO, 1,
776 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 794 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
777 }, 795 },
778 { "s3a.sn", TILE_OPC_S3A_SN, 0x3, 3, TREG_SN, 1, 796 { "s3a.sn", TILEPRO_OPC_S3A_SN, 0x3, 3, TREG_SN, 1,
779 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 797 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
780 }, 798 },
781 { "sadab_u", TILE_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1, 799 { "sadab_u", TILEPRO_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1,
782 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 800 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
783 }, 801 },
784 { "sadab_u.sn", TILE_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1, 802 { "sadab_u.sn", TILEPRO_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1,
785 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 803 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
786 }, 804 },
787 { "sadah", TILE_OPC_SADAH, 0x1, 3, TREG_ZERO, 1, 805 { "sadah", TILEPRO_OPC_SADAH, 0x1, 3, TREG_ZERO, 1,
788 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 806 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
789 }, 807 },
790 { "sadah.sn", TILE_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1, 808 { "sadah.sn", TILEPRO_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1,
791 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 809 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
792 }, 810 },
793 { "sadah_u", TILE_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1, 811 { "sadah_u", TILEPRO_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1,
794 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 812 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
795 }, 813 },
796 { "sadah_u.sn", TILE_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1, 814 { "sadah_u.sn", TILEPRO_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1,
797 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 815 { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
798 }, 816 },
799 { "sadb_u", TILE_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1, 817 { "sadb_u", TILEPRO_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1,
800 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 818 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
801 }, 819 },
802 { "sadb_u.sn", TILE_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1, 820 { "sadb_u.sn", TILEPRO_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1,
803 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 821 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
804 }, 822 },
805 { "sadh", TILE_OPC_SADH, 0x1, 3, TREG_ZERO, 1, 823 { "sadh", TILEPRO_OPC_SADH, 0x1, 3, TREG_ZERO, 1,
806 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 824 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
807 }, 825 },
808 { "sadh.sn", TILE_OPC_SADH_SN, 0x1, 3, TREG_SN, 1, 826 { "sadh.sn", TILEPRO_OPC_SADH_SN, 0x1, 3, TREG_SN, 1,
809 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 827 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
810 }, 828 },
811 { "sadh_u", TILE_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1, 829 { "sadh_u", TILEPRO_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1,
812 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 830 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
813 }, 831 },
814 { "sadh_u.sn", TILE_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1, 832 { "sadh_u.sn", TILEPRO_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1,
815 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } }, 833 { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
816 }, 834 },
817 { "sb", TILE_OPC_SB, 0x12, 2, TREG_ZERO, 1, 835 { "sb", TILEPRO_OPC_SB, 0x12, 2, TREG_ZERO, 1,
818 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } }, 836 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
819 }, 837 },
820 { "sbadd", TILE_OPC_SBADD, 0x2, 3, TREG_ZERO, 1, 838 { "sbadd", TILEPRO_OPC_SBADD, 0x2, 3, TREG_ZERO, 1,
821 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } }, 839 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
822 }, 840 },
823 { "seq", TILE_OPC_SEQ, 0xf, 3, TREG_ZERO, 1, 841 { "seq", TILEPRO_OPC_SEQ, 0xf, 3, TREG_ZERO, 1,
824 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 842 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
825 }, 843 },
826 { "seq.sn", TILE_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1, 844 { "seq.sn", TILEPRO_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1,
827 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 845 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
828 }, 846 },
829 { "seqb", TILE_OPC_SEQB, 0x3, 3, TREG_ZERO, 1, 847 { "seqb", TILEPRO_OPC_SEQB, 0x3, 3, TREG_ZERO, 1,
830 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 848 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
831 }, 849 },
832 { "seqb.sn", TILE_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1, 850 { "seqb.sn", TILEPRO_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1,
833 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 851 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
834 }, 852 },
835 { "seqh", TILE_OPC_SEQH, 0x3, 3, TREG_ZERO, 1, 853 { "seqh", TILEPRO_OPC_SEQH, 0x3, 3, TREG_ZERO, 1,
836 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 854 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
837 }, 855 },
838 { "seqh.sn", TILE_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1, 856 { "seqh.sn", TILEPRO_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1,
839 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 857 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
840 }, 858 },
841 { "seqi", TILE_OPC_SEQI, 0xf, 3, TREG_ZERO, 1, 859 { "seqi", TILEPRO_OPC_SEQI, 0xf, 3, TREG_ZERO, 1,
842 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 860 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
843 }, 861 },
844 { "seqi.sn", TILE_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1, 862 { "seqi.sn", TILEPRO_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1,
845 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 863 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
846 }, 864 },
847 { "seqib", TILE_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1, 865 { "seqib", TILEPRO_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1,
848 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 866 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
849 }, 867 },
850 { "seqib.sn", TILE_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1, 868 { "seqib.sn", TILEPRO_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1,
851 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 869 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
852 }, 870 },
853 { "seqih", TILE_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1, 871 { "seqih", TILEPRO_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1,
854 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 872 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
855 }, 873 },
856 { "seqih.sn", TILE_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1, 874 { "seqih.sn", TILEPRO_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1,
857 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 875 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
858 }, 876 },
859 { "sh", TILE_OPC_SH, 0x12, 2, TREG_ZERO, 1, 877 { "sh", TILEPRO_OPC_SH, 0x12, 2, TREG_ZERO, 1,
860 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } }, 878 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
861 }, 879 },
862 { "shadd", TILE_OPC_SHADD, 0x2, 3, TREG_ZERO, 1, 880 { "shadd", TILEPRO_OPC_SHADD, 0x2, 3, TREG_ZERO, 1,
863 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } }, 881 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
864 }, 882 },
865 { "shl", TILE_OPC_SHL, 0xf, 3, TREG_ZERO, 1, 883 { "shl", TILEPRO_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
866 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 884 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
867 }, 885 },
868 { "shl.sn", TILE_OPC_SHL_SN, 0x3, 3, TREG_SN, 1, 886 { "shl.sn", TILEPRO_OPC_SHL_SN, 0x3, 3, TREG_SN, 1,
869 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 887 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
870 }, 888 },
871 { "shlb", TILE_OPC_SHLB, 0x3, 3, TREG_ZERO, 1, 889 { "shlb", TILEPRO_OPC_SHLB, 0x3, 3, TREG_ZERO, 1,
872 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 890 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
873 }, 891 },
874 { "shlb.sn", TILE_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1, 892 { "shlb.sn", TILEPRO_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1,
875 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 893 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
876 }, 894 },
877 { "shlh", TILE_OPC_SHLH, 0x3, 3, TREG_ZERO, 1, 895 { "shlh", TILEPRO_OPC_SHLH, 0x3, 3, TREG_ZERO, 1,
878 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 896 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
879 }, 897 },
880 { "shlh.sn", TILE_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1, 898 { "shlh.sn", TILEPRO_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1,
881 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 899 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
882 }, 900 },
883 { "shli", TILE_OPC_SHLI, 0xf, 3, TREG_ZERO, 1, 901 { "shli", TILEPRO_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
884 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } }, 902 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
885 }, 903 },
886 { "shli.sn", TILE_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1, 904 { "shli.sn", TILEPRO_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1,
887 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 905 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
888 }, 906 },
889 { "shlib", TILE_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1, 907 { "shlib", TILEPRO_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1,
890 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 908 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
891 }, 909 },
892 { "shlib.sn", TILE_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1, 910 { "shlib.sn", TILEPRO_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1,
893 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 911 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
894 }, 912 },
895 { "shlih", TILE_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1, 913 { "shlih", TILEPRO_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1,
896 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 914 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
897 }, 915 },
898 { "shlih.sn", TILE_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1, 916 { "shlih.sn", TILEPRO_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1,
899 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 917 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
900 }, 918 },
901 { "shr", TILE_OPC_SHR, 0xf, 3, TREG_ZERO, 1, 919 { "shr", TILEPRO_OPC_SHR, 0xf, 3, TREG_ZERO, 1,
902 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 920 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
903 }, 921 },
904 { "shr.sn", TILE_OPC_SHR_SN, 0x3, 3, TREG_SN, 1, 922 { "shr.sn", TILEPRO_OPC_SHR_SN, 0x3, 3, TREG_SN, 1,
905 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 923 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
906 }, 924 },
907 { "shrb", TILE_OPC_SHRB, 0x3, 3, TREG_ZERO, 1, 925 { "shrb", TILEPRO_OPC_SHRB, 0x3, 3, TREG_ZERO, 1,
908 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 926 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
909 }, 927 },
910 { "shrb.sn", TILE_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1, 928 { "shrb.sn", TILEPRO_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1,
911 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 929 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
912 }, 930 },
913 { "shrh", TILE_OPC_SHRH, 0x3, 3, TREG_ZERO, 1, 931 { "shrh", TILEPRO_OPC_SHRH, 0x3, 3, TREG_ZERO, 1,
914 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 932 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
915 }, 933 },
916 { "shrh.sn", TILE_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1, 934 { "shrh.sn", TILEPRO_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1,
917 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 935 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
918 }, 936 },
919 { "shri", TILE_OPC_SHRI, 0xf, 3, TREG_ZERO, 1, 937 { "shri", TILEPRO_OPC_SHRI, 0xf, 3, TREG_ZERO, 1,
920 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } }, 938 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
921 }, 939 },
922 { "shri.sn", TILE_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1, 940 { "shri.sn", TILEPRO_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1,
923 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 941 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
924 }, 942 },
925 { "shrib", TILE_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1, 943 { "shrib", TILEPRO_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1,
926 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 944 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
927 }, 945 },
928 { "shrib.sn", TILE_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1, 946 { "shrib.sn", TILEPRO_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1,
929 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 947 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
930 }, 948 },
931 { "shrih", TILE_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1, 949 { "shrih", TILEPRO_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1,
932 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 950 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
933 }, 951 },
934 { "shrih.sn", TILE_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1, 952 { "shrih.sn", TILEPRO_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1,
935 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 953 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
936 }, 954 },
937 { "slt", TILE_OPC_SLT, 0xf, 3, TREG_ZERO, 1, 955 { "slt", TILEPRO_OPC_SLT, 0xf, 3, TREG_ZERO, 1,
938 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 956 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
939 }, 957 },
940 { "slt.sn", TILE_OPC_SLT_SN, 0x3, 3, TREG_SN, 1, 958 { "slt.sn", TILEPRO_OPC_SLT_SN, 0x3, 3, TREG_SN, 1,
941 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 959 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
942 }, 960 },
943 { "slt_u", TILE_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1, 961 { "slt_u", TILEPRO_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1,
944 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 962 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
945 }, 963 },
946 { "slt_u.sn", TILE_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1, 964 { "slt_u.sn", TILEPRO_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1,
947 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 965 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
948 }, 966 },
949 { "sltb", TILE_OPC_SLTB, 0x3, 3, TREG_ZERO, 1, 967 { "sltb", TILEPRO_OPC_SLTB, 0x3, 3, TREG_ZERO, 1,
950 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 968 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
951 }, 969 },
952 { "sltb.sn", TILE_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1, 970 { "sltb.sn", TILEPRO_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1,
953 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 971 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
954 }, 972 },
955 { "sltb_u", TILE_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1, 973 { "sltb_u", TILEPRO_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1,
956 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 974 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
957 }, 975 },
958 { "sltb_u.sn", TILE_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1, 976 { "sltb_u.sn", TILEPRO_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1,
959 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 977 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
960 }, 978 },
961 { "slte", TILE_OPC_SLTE, 0xf, 3, TREG_ZERO, 1, 979 { "slte", TILEPRO_OPC_SLTE, 0xf, 3, TREG_ZERO, 1,
962 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 980 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
963 }, 981 },
964 { "slte.sn", TILE_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1, 982 { "slte.sn", TILEPRO_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1,
965 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 983 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
966 }, 984 },
967 { "slte_u", TILE_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1, 985 { "slte_u", TILEPRO_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1,
968 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 986 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
969 }, 987 },
970 { "slte_u.sn", TILE_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1, 988 { "slte_u.sn", TILEPRO_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1,
971 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 989 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
972 }, 990 },
973 { "slteb", TILE_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1, 991 { "slteb", TILEPRO_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1,
974 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 992 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
975 }, 993 },
976 { "slteb.sn", TILE_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1, 994 { "slteb.sn", TILEPRO_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1,
977 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 995 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
978 }, 996 },
979 { "slteb_u", TILE_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1, 997 { "slteb_u", TILEPRO_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1,
980 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 998 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
981 }, 999 },
982 { "slteb_u.sn", TILE_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1, 1000 { "slteb_u.sn", TILEPRO_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1,
983 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1001 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
984 }, 1002 },
985 { "slteh", TILE_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1, 1003 { "slteh", TILEPRO_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1,
986 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1004 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
987 }, 1005 },
988 { "slteh.sn", TILE_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1, 1006 { "slteh.sn", TILEPRO_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1,
989 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1007 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
990 }, 1008 },
991 { "slteh_u", TILE_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1, 1009 { "slteh_u", TILEPRO_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1,
992 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1010 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
993 }, 1011 },
994 { "slteh_u.sn", TILE_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1, 1012 { "slteh_u.sn", TILEPRO_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1,
995 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1013 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
996 }, 1014 },
997 { "slth", TILE_OPC_SLTH, 0x3, 3, TREG_ZERO, 1, 1015 { "slth", TILEPRO_OPC_SLTH, 0x3, 3, TREG_ZERO, 1,
998 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1016 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
999 }, 1017 },
1000 { "slth.sn", TILE_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1, 1018 { "slth.sn", TILEPRO_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1,
1001 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1019 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1002 }, 1020 },
1003 { "slth_u", TILE_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1, 1021 { "slth_u", TILEPRO_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1,
1004 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1022 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1005 }, 1023 },
1006 { "slth_u.sn", TILE_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1, 1024 { "slth_u.sn", TILEPRO_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1,
1007 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1025 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1008 }, 1026 },
1009 { "slti", TILE_OPC_SLTI, 0xf, 3, TREG_ZERO, 1, 1027 { "slti", TILEPRO_OPC_SLTI, 0xf, 3, TREG_ZERO, 1,
1010 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 1028 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
1011 }, 1029 },
1012 { "slti.sn", TILE_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1, 1030 { "slti.sn", TILEPRO_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1,
1013 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1031 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1014 }, 1032 },
1015 { "slti_u", TILE_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1, 1033 { "slti_u", TILEPRO_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1,
1016 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } }, 1034 { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
1017 }, 1035 },
1018 { "slti_u.sn", TILE_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1, 1036 { "slti_u.sn", TILEPRO_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1,
1019 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1037 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1020 }, 1038 },
1021 { "sltib", TILE_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1, 1039 { "sltib", TILEPRO_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1,
1022 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1040 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1023 }, 1041 },
1024 { "sltib.sn", TILE_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1, 1042 { "sltib.sn", TILEPRO_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1,
1025 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1043 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1026 }, 1044 },
1027 { "sltib_u", TILE_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1, 1045 { "sltib_u", TILEPRO_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1,
1028 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1046 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1029 }, 1047 },
1030 { "sltib_u.sn", TILE_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1, 1048 { "sltib_u.sn", TILEPRO_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1,
1031 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1049 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1032 }, 1050 },
1033 { "sltih", TILE_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1, 1051 { "sltih", TILEPRO_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1,
1034 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1052 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1035 }, 1053 },
1036 { "sltih.sn", TILE_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1, 1054 { "sltih.sn", TILEPRO_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1,
1037 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1055 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1038 }, 1056 },
1039 { "sltih_u", TILE_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1, 1057 { "sltih_u", TILEPRO_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1,
1040 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1058 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1041 }, 1059 },
1042 { "sltih_u.sn", TILE_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1, 1060 { "sltih_u.sn", TILEPRO_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1,
1043 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1061 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1044 }, 1062 },
1045 { "sne", TILE_OPC_SNE, 0xf, 3, TREG_ZERO, 1, 1063 { "sne", TILEPRO_OPC_SNE, 0xf, 3, TREG_ZERO, 1,
1046 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 1064 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1047 }, 1065 },
1048 { "sne.sn", TILE_OPC_SNE_SN, 0x3, 3, TREG_SN, 1, 1066 { "sne.sn", TILEPRO_OPC_SNE_SN, 0x3, 3, TREG_SN, 1,
1049 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1067 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1050 }, 1068 },
1051 { "sneb", TILE_OPC_SNEB, 0x3, 3, TREG_ZERO, 1, 1069 { "sneb", TILEPRO_OPC_SNEB, 0x3, 3, TREG_ZERO, 1,
1052 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1070 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1053 }, 1071 },
1054 { "sneb.sn", TILE_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1, 1072 { "sneb.sn", TILEPRO_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1,
1055 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1073 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1056 }, 1074 },
1057 { "sneh", TILE_OPC_SNEH, 0x3, 3, TREG_ZERO, 1, 1075 { "sneh", TILEPRO_OPC_SNEH, 0x3, 3, TREG_ZERO, 1,
1058 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1076 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1059 }, 1077 },
1060 { "sneh.sn", TILE_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1, 1078 { "sneh.sn", TILEPRO_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1,
1061 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1079 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1062 }, 1080 },
1063 { "sra", TILE_OPC_SRA, 0xf, 3, TREG_ZERO, 1, 1081 { "sra", TILEPRO_OPC_SRA, 0xf, 3, TREG_ZERO, 1,
1064 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 1082 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1065 }, 1083 },
1066 { "sra.sn", TILE_OPC_SRA_SN, 0x3, 3, TREG_SN, 1, 1084 { "sra.sn", TILEPRO_OPC_SRA_SN, 0x3, 3, TREG_SN, 1,
1067 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1085 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1068 }, 1086 },
1069 { "srab", TILE_OPC_SRAB, 0x3, 3, TREG_ZERO, 1, 1087 { "srab", TILEPRO_OPC_SRAB, 0x3, 3, TREG_ZERO, 1,
1070 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1088 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1071 }, 1089 },
1072 { "srab.sn", TILE_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1, 1090 { "srab.sn", TILEPRO_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1,
1073 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1091 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1074 }, 1092 },
1075 { "srah", TILE_OPC_SRAH, 0x3, 3, TREG_ZERO, 1, 1093 { "srah", TILEPRO_OPC_SRAH, 0x3, 3, TREG_ZERO, 1,
1076 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1094 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1077 }, 1095 },
1078 { "srah.sn", TILE_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1, 1096 { "srah.sn", TILEPRO_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1,
1079 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1097 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1080 }, 1098 },
1081 { "srai", TILE_OPC_SRAI, 0xf, 3, TREG_ZERO, 1, 1099 { "srai", TILEPRO_OPC_SRAI, 0xf, 3, TREG_ZERO, 1,
1082 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } }, 1100 { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
1083 }, 1101 },
1084 { "srai.sn", TILE_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1, 1102 { "srai.sn", TILEPRO_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1,
1085 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 1103 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1086 }, 1104 },
1087 { "sraib", TILE_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1, 1105 { "sraib", TILEPRO_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1,
1088 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 1106 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1089 }, 1107 },
1090 { "sraib.sn", TILE_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1, 1108 { "sraib.sn", TILEPRO_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1,
1091 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 1109 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1092 }, 1110 },
1093 { "sraih", TILE_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1, 1111 { "sraih", TILEPRO_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1,
1094 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 1112 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1095 }, 1113 },
1096 { "sraih.sn", TILE_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1, 1114 { "sraih.sn", TILEPRO_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1,
1097 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } }, 1115 { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
1098 }, 1116 },
1099 { "sub", TILE_OPC_SUB, 0xf, 3, TREG_ZERO, 1, 1117 { "sub", TILEPRO_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
1100 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 1118 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1101 }, 1119 },
1102 { "sub.sn", TILE_OPC_SUB_SN, 0x3, 3, TREG_SN, 1, 1120 { "sub.sn", TILEPRO_OPC_SUB_SN, 0x3, 3, TREG_SN, 1,
1103 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1121 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1104 }, 1122 },
1105 { "subb", TILE_OPC_SUBB, 0x3, 3, TREG_ZERO, 1, 1123 { "subb", TILEPRO_OPC_SUBB, 0x3, 3, TREG_ZERO, 1,
1106 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1124 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1107 }, 1125 },
1108 { "subb.sn", TILE_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1, 1126 { "subb.sn", TILEPRO_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1,
1109 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1127 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1110 }, 1128 },
1111 { "subbs_u", TILE_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1, 1129 { "subbs_u", TILEPRO_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1,
1112 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1130 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1113 }, 1131 },
1114 { "subbs_u.sn", TILE_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1, 1132 { "subbs_u.sn", TILEPRO_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1,
1115 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1133 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1116 }, 1134 },
1117 { "subh", TILE_OPC_SUBH, 0x3, 3, TREG_ZERO, 1, 1135 { "subh", TILEPRO_OPC_SUBH, 0x3, 3, TREG_ZERO, 1,
1118 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1136 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1119 }, 1137 },
1120 { "subh.sn", TILE_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1, 1138 { "subh.sn", TILEPRO_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1,
1121 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1139 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1122 }, 1140 },
1123 { "subhs", TILE_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1, 1141 { "subhs", TILEPRO_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1,
1124 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1142 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1125 }, 1143 },
1126 { "subhs.sn", TILE_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1, 1144 { "subhs.sn", TILEPRO_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1,
1127 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1145 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1128 }, 1146 },
1129 { "subs", TILE_OPC_SUBS, 0x3, 3, TREG_ZERO, 1, 1147 { "subs", TILEPRO_OPC_SUBS, 0x3, 3, TREG_ZERO, 1,
1130 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1148 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1131 }, 1149 },
1132 { "subs.sn", TILE_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1, 1150 { "subs.sn", TILEPRO_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1,
1133 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1151 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1134 }, 1152 },
1135 { "sw", TILE_OPC_SW, 0x12, 2, TREG_ZERO, 1, 1153 { "sw", TILEPRO_OPC_SW, 0x12, 2, TREG_ZERO, 1,
1136 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } }, 1154 { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
1137 }, 1155 },
1138 { "swadd", TILE_OPC_SWADD, 0x2, 3, TREG_ZERO, 1, 1156 { "swadd", TILEPRO_OPC_SWADD, 0x2, 3, TREG_ZERO, 1,
1139 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } }, 1157 { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
1140 }, 1158 },
1141 { "swint0", TILE_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0, 1159 { "swint0", TILEPRO_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
1142 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 1160 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1143 }, 1161 },
1144 { "swint1", TILE_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0, 1162 { "swint1", TILEPRO_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
1145 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 1163 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1146 }, 1164 },
1147 { "swint2", TILE_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0, 1165 { "swint2", TILEPRO_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
1148 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 1166 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1149 }, 1167 },
1150 { "swint3", TILE_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0, 1168 { "swint3", TILEPRO_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
1151 { { 0, }, { }, { 0, }, { 0, }, { 0, } }, 1169 { { 0, }, { }, { 0, }, { 0, }, { 0, } },
1152 }, 1170 },
1153 { "tblidxb0", TILE_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1, 1171 { "tblidxb0", TILEPRO_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
1154 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } }, 1172 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1155 }, 1173 },
1156 { "tblidxb0.sn", TILE_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1, 1174 { "tblidxb0.sn", TILEPRO_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1,
1157 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 1175 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1158 }, 1176 },
1159 { "tblidxb1", TILE_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1, 1177 { "tblidxb1", TILEPRO_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
1160 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } }, 1178 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1161 }, 1179 },
1162 { "tblidxb1.sn", TILE_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1, 1180 { "tblidxb1.sn", TILEPRO_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1,
1163 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 1181 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1164 }, 1182 },
1165 { "tblidxb2", TILE_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1, 1183 { "tblidxb2", TILEPRO_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
1166 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } }, 1184 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1167 }, 1185 },
1168 { "tblidxb2.sn", TILE_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1, 1186 { "tblidxb2.sn", TILEPRO_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1,
1169 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 1187 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1170 }, 1188 },
1171 { "tblidxb3", TILE_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1, 1189 { "tblidxb3", TILEPRO_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
1172 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } }, 1190 { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
1173 }, 1191 },
1174 { "tblidxb3.sn", TILE_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1, 1192 { "tblidxb3.sn", TILEPRO_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1,
1175 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } }, 1193 { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
1176 }, 1194 },
1177 { "tns", TILE_OPC_TNS, 0x2, 2, TREG_ZERO, 1, 1195 { "tns", TILEPRO_OPC_TNS, 0x2, 2, TREG_ZERO, 1,
1178 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 1196 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
1179 }, 1197 },
1180 { "tns.sn", TILE_OPC_TNS_SN, 0x2, 2, TREG_SN, 1, 1198 { "tns.sn", TILEPRO_OPC_TNS_SN, 0x2, 2, TREG_SN, 1,
1181 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } }, 1199 { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
1182 }, 1200 },
1183 { "wh64", TILE_OPC_WH64, 0x2, 1, TREG_ZERO, 1, 1201 { "wh64", TILEPRO_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
1184 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } }, 1202 { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
1185 }, 1203 },
1186 { "xor", TILE_OPC_XOR, 0xf, 3, TREG_ZERO, 1, 1204 { "xor", TILEPRO_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
1187 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } }, 1205 { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
1188 }, 1206 },
1189 { "xor.sn", TILE_OPC_XOR_SN, 0x3, 3, TREG_SN, 1, 1207 { "xor.sn", TILEPRO_OPC_XOR_SN, 0x3, 3, TREG_SN, 1,
1190 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } }, 1208 { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
1191 }, 1209 },
1192 { "xori", TILE_OPC_XORI, 0x3, 3, TREG_ZERO, 1, 1210 { "xori", TILEPRO_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
1193 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1211 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1194 }, 1212 },
1195 { "xori.sn", TILE_OPC_XORI_SN, 0x3, 3, TREG_SN, 1, 1213 { "xori.sn", TILEPRO_OPC_XORI_SN, 0x3, 3, TREG_SN, 1,
1196 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } }, 1214 { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
1197 }, 1215 },
1198 { NULL, TILE_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } }, 1216 { NULL, TILEPRO_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
1199 } 1217 }
1200}; 1218};
1201#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6)) 1219#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
1202#define CHILD(array_index) (TILE_OPC_NONE + (array_index)) 1220#define CHILD(array_index) (TILEPRO_OPC_NONE + (array_index))
1203 1221
1204static const unsigned short decode_X0_fsm[1153] = 1222static const unsigned short decode_X0_fsm[1153] =
1205{ 1223{
1206 BITFIELD(22, 9) /* index 0 */, 1224 BITFIELD(22, 9) /* index 0 */,
1207 CHILD(513), CHILD(530), CHILD(547), CHILD(564), CHILD(596), CHILD(613), 1225 CHILD(513), CHILD(530), CHILD(547), CHILD(564), CHILD(596), CHILD(613),
1208 CHILD(630), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1226 CHILD(630), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1209 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1227 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1210 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1228 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1211 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1229 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1212 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1230 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1213 TILE_OPC_NONE, CHILD(663), CHILD(680), CHILD(697), CHILD(714), CHILD(746), 1231 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1214 CHILD(763), CHILD(780), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1232 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(663), CHILD(680), CHILD(697),
1215 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1233 CHILD(714), CHILD(746), CHILD(763), CHILD(780), TILEPRO_OPC_NONE,
1216 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1234 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1217 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1235 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1218 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1236 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1219 TILE_OPC_NONE, TILE_OPC_NONE, CHILD(813), CHILD(813), CHILD(813), 1237 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1238 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1239 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1220 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1240 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1221 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1241 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1222 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1242 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
@@ -1227,7 +1247,8 @@ static const unsigned short decode_X0_fsm[1153] =
1227 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1247 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1228 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1248 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1229 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), 1249 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
1230 CHILD(813), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1250 CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(828), CHILD(828),
1251 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1231 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1252 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1232 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1253 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1233 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1254 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
@@ -1237,7 +1258,7 @@ static const unsigned short decode_X0_fsm[1153] =
1237 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1258 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1238 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1259 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1239 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), 1260 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
1240 CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(843), 1261 CHILD(828), CHILD(828), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1241 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1262 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1242 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1263 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1243 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1264 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
@@ -1248,333 +1269,371 @@ static const unsigned short decode_X0_fsm[1153] =
1248 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1269 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1249 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1270 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1250 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1271 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1251 CHILD(843), CHILD(843), CHILD(843), CHILD(873), CHILD(878), CHILD(883), 1272 CHILD(873), CHILD(878), CHILD(883), CHILD(903), CHILD(908),
1252 CHILD(903), CHILD(908), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1273 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1253 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1274 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1254 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1275 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1255 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1276 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1256 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1277 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1257 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(913), 1278 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1258 CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILE_OPC_NONE, 1279 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(913),
1259 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1280 CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILEPRO_OPC_NONE,
1260 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1281 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1261 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1282 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1262 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1283 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1263 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1284 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1264 TILE_OPC_NONE, CHILD(953), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1285 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1265 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1286 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1266 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1287 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(953), TILEPRO_OPC_NONE,
1267 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1288 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1268 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1289 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1269 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1290 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1270 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(988), TILE_OPC_NONE, 1291 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1271 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1292 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1272 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1293 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1273 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1294 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1274 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1295 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(988), TILEPRO_OPC_NONE,
1275 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1296 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1276 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1297 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1277 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1298 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1278 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1299 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1279 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1300 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1280 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1301 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1281 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1302 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1282 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1303 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1283 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1304 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1284 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1305 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1285 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1306 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1286 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1307 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1287 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1308 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1288 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1309 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1289 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(993), 1310 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1290 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1311 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1291 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1312 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1292 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1313 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1293 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1314 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1294 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1315 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1295 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1316 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1296 TILE_OPC_NONE, CHILD(1076), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1317 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1297 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1318 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1298 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1319 TILEPRO_OPC_MM, TILEPRO_OPC_MM, CHILD(993), TILEPRO_OPC_NONE,
1299 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1320 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1300 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1321 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1301 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1322 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1302 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1323 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1324 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1325 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1326 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1327 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(1076), TILEPRO_OPC_NONE,
1328 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1329 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1330 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1331 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1332 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1333 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1334 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1335 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1303 BITFIELD(18, 4) /* index 513 */, 1336 BITFIELD(18, 4) /* index 513 */,
1304 TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD, 1337 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB, TILEPRO_OPC_ADDH, TILEPRO_OPC_ADD,
1305 TILE_OPC_ADIFFB_U, TILE_OPC_ADIFFH, TILE_OPC_AND, TILE_OPC_AVGB_U, 1338 TILEPRO_OPC_ADIFFB_U, TILEPRO_OPC_ADIFFH, TILEPRO_OPC_AND,
1306 TILE_OPC_AVGH, TILE_OPC_CRC32_32, TILE_OPC_CRC32_8, TILE_OPC_INTHB, 1339 TILEPRO_OPC_AVGB_U, TILEPRO_OPC_AVGH, TILEPRO_OPC_CRC32_32,
1307 TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH, TILE_OPC_MAXB_U, 1340 TILEPRO_OPC_CRC32_8, TILEPRO_OPC_INTHB, TILEPRO_OPC_INTHH,
1341 TILEPRO_OPC_INTLB, TILEPRO_OPC_INTLH, TILEPRO_OPC_MAXB_U,
1308 BITFIELD(18, 4) /* index 530 */, 1342 BITFIELD(18, 4) /* index 530 */,
1309 TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH, TILE_OPC_MNZB, TILE_OPC_MNZH, 1343 TILEPRO_OPC_MAXH, TILEPRO_OPC_MINB_U, TILEPRO_OPC_MINH, TILEPRO_OPC_MNZB,
1310 TILE_OPC_MNZ, TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_SU, TILE_OPC_MULHHA_UU, 1344 TILEPRO_OPC_MNZH, TILEPRO_OPC_MNZ, TILEPRO_OPC_MULHHA_SS,
1311 TILE_OPC_MULHHSA_UU, TILE_OPC_MULHH_SS, TILE_OPC_MULHH_SU, 1345 TILEPRO_OPC_MULHHA_SU, TILEPRO_OPC_MULHHA_UU, TILEPRO_OPC_MULHHSA_UU,
1312 TILE_OPC_MULHH_UU, TILE_OPC_MULHLA_SS, TILE_OPC_MULHLA_SU, 1346 TILEPRO_OPC_MULHH_SS, TILEPRO_OPC_MULHH_SU, TILEPRO_OPC_MULHH_UU,
1313 TILE_OPC_MULHLA_US, 1347 TILEPRO_OPC_MULHLA_SS, TILEPRO_OPC_MULHLA_SU, TILEPRO_OPC_MULHLA_US,
1314 BITFIELD(18, 4) /* index 547 */, 1348 BITFIELD(18, 4) /* index 547 */,
1315 TILE_OPC_MULHLA_UU, TILE_OPC_MULHLSA_UU, TILE_OPC_MULHL_SS, 1349 TILEPRO_OPC_MULHLA_UU, TILEPRO_OPC_MULHLSA_UU, TILEPRO_OPC_MULHL_SS,
1316 TILE_OPC_MULHL_SU, TILE_OPC_MULHL_US, TILE_OPC_MULHL_UU, TILE_OPC_MULLLA_SS, 1350 TILEPRO_OPC_MULHL_SU, TILEPRO_OPC_MULHL_US, TILEPRO_OPC_MULHL_UU,
1317 TILE_OPC_MULLLA_SU, TILE_OPC_MULLLA_UU, TILE_OPC_MULLLSA_UU, 1351 TILEPRO_OPC_MULLLA_SS, TILEPRO_OPC_MULLLA_SU, TILEPRO_OPC_MULLLA_UU,
1318 TILE_OPC_MULLL_SS, TILE_OPC_MULLL_SU, TILE_OPC_MULLL_UU, TILE_OPC_MVNZ, 1352 TILEPRO_OPC_MULLLSA_UU, TILEPRO_OPC_MULLL_SS, TILEPRO_OPC_MULLL_SU,
1319 TILE_OPC_MVZ, TILE_OPC_MZB, 1353 TILEPRO_OPC_MULLL_UU, TILEPRO_OPC_MVNZ, TILEPRO_OPC_MVZ, TILEPRO_OPC_MZB,
1320 BITFIELD(18, 4) /* index 564 */, 1354 BITFIELD(18, 4) /* index 564 */,
1321 TILE_OPC_MZH, TILE_OPC_MZ, TILE_OPC_NOR, CHILD(581), TILE_OPC_PACKHB, 1355 TILEPRO_OPC_MZH, TILEPRO_OPC_MZ, TILEPRO_OPC_NOR, CHILD(581),
1322 TILE_OPC_PACKLB, TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A, 1356 TILEPRO_OPC_PACKHB, TILEPRO_OPC_PACKLB, TILEPRO_OPC_RL, TILEPRO_OPC_S1A,
1323 TILE_OPC_SADAB_U, TILE_OPC_SADAH, TILE_OPC_SADAH_U, TILE_OPC_SADB_U, 1357 TILEPRO_OPC_S2A, TILEPRO_OPC_S3A, TILEPRO_OPC_SADAB_U, TILEPRO_OPC_SADAH,
1324 TILE_OPC_SADH, TILE_OPC_SADH_U, 1358 TILEPRO_OPC_SADAH_U, TILEPRO_OPC_SADB_U, TILEPRO_OPC_SADH,
1359 TILEPRO_OPC_SADH_U,
1325 BITFIELD(12, 2) /* index 581 */, 1360 BITFIELD(12, 2) /* index 581 */,
1326 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(586), 1361 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(586),
1327 BITFIELD(14, 2) /* index 586 */, 1362 BITFIELD(14, 2) /* index 586 */,
1328 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(591), 1363 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(591),
1329 BITFIELD(16, 2) /* index 591 */, 1364 BITFIELD(16, 2) /* index 591 */,
1330 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE, 1365 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
1331 BITFIELD(18, 4) /* index 596 */, 1366 BITFIELD(18, 4) /* index 596 */,
1332 TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB, TILE_OPC_SHLH, 1367 TILEPRO_OPC_SEQB, TILEPRO_OPC_SEQH, TILEPRO_OPC_SEQ, TILEPRO_OPC_SHLB,
1333 TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR, TILE_OPC_SLTB, 1368 TILEPRO_OPC_SHLH, TILEPRO_OPC_SHL, TILEPRO_OPC_SHRB, TILEPRO_OPC_SHRH,
1334 TILE_OPC_SLTB_U, TILE_OPC_SLTEB, TILE_OPC_SLTEB_U, TILE_OPC_SLTEH, 1369 TILEPRO_OPC_SHR, TILEPRO_OPC_SLTB, TILEPRO_OPC_SLTB_U, TILEPRO_OPC_SLTEB,
1335 TILE_OPC_SLTEH_U, TILE_OPC_SLTE, 1370 TILEPRO_OPC_SLTEB_U, TILEPRO_OPC_SLTEH, TILEPRO_OPC_SLTEH_U,
1371 TILEPRO_OPC_SLTE,
1336 BITFIELD(18, 4) /* index 613 */, 1372 BITFIELD(18, 4) /* index 613 */,
1337 TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT, 1373 TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLTH, TILEPRO_OPC_SLTH_U, TILEPRO_OPC_SLT,
1338 TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB, 1374 TILEPRO_OPC_SLT_U, TILEPRO_OPC_SNEB, TILEPRO_OPC_SNEH, TILEPRO_OPC_SNE,
1339 TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB, 1375 TILEPRO_OPC_SRAB, TILEPRO_OPC_SRAH, TILEPRO_OPC_SRA, TILEPRO_OPC_SUBB,
1340 TILE_OPC_XOR, TILE_OPC_DWORD_ALIGN, 1376 TILEPRO_OPC_SUBH, TILEPRO_OPC_SUB, TILEPRO_OPC_XOR, TILEPRO_OPC_DWORD_ALIGN,
1341 BITFIELD(18, 3) /* index 630 */, 1377 BITFIELD(18, 3) /* index 630 */,
1342 CHILD(639), CHILD(642), CHILD(645), CHILD(648), CHILD(651), CHILD(654), 1378 CHILD(639), CHILD(642), CHILD(645), CHILD(648), CHILD(651), CHILD(654),
1343 CHILD(657), CHILD(660), 1379 CHILD(657), CHILD(660),
1344 BITFIELD(21, 1) /* index 639 */, 1380 BITFIELD(21, 1) /* index 639 */,
1345 TILE_OPC_ADDS, TILE_OPC_NONE, 1381 TILEPRO_OPC_ADDS, TILEPRO_OPC_NONE,
1346 BITFIELD(21, 1) /* index 642 */, 1382 BITFIELD(21, 1) /* index 642 */,
1347 TILE_OPC_SUBS, TILE_OPC_NONE, 1383 TILEPRO_OPC_SUBS, TILEPRO_OPC_NONE,
1348 BITFIELD(21, 1) /* index 645 */, 1384 BITFIELD(21, 1) /* index 645 */,
1349 TILE_OPC_ADDBS_U, TILE_OPC_NONE, 1385 TILEPRO_OPC_ADDBS_U, TILEPRO_OPC_NONE,
1350 BITFIELD(21, 1) /* index 648 */, 1386 BITFIELD(21, 1) /* index 648 */,
1351 TILE_OPC_ADDHS, TILE_OPC_NONE, 1387 TILEPRO_OPC_ADDHS, TILEPRO_OPC_NONE,
1352 BITFIELD(21, 1) /* index 651 */, 1388 BITFIELD(21, 1) /* index 651 */,
1353 TILE_OPC_SUBBS_U, TILE_OPC_NONE, 1389 TILEPRO_OPC_SUBBS_U, TILEPRO_OPC_NONE,
1354 BITFIELD(21, 1) /* index 654 */, 1390 BITFIELD(21, 1) /* index 654 */,
1355 TILE_OPC_SUBHS, TILE_OPC_NONE, 1391 TILEPRO_OPC_SUBHS, TILEPRO_OPC_NONE,
1356 BITFIELD(21, 1) /* index 657 */, 1392 BITFIELD(21, 1) /* index 657 */,
1357 TILE_OPC_PACKHS, TILE_OPC_NONE, 1393 TILEPRO_OPC_PACKHS, TILEPRO_OPC_NONE,
1358 BITFIELD(21, 1) /* index 660 */, 1394 BITFIELD(21, 1) /* index 660 */,
1359 TILE_OPC_PACKBS_U, TILE_OPC_NONE, 1395 TILEPRO_OPC_PACKBS_U, TILEPRO_OPC_NONE,
1360 BITFIELD(18, 4) /* index 663 */, 1396 BITFIELD(18, 4) /* index 663 */,
1361 TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN, 1397 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB_SN, TILEPRO_OPC_ADDH_SN,
1362 TILE_OPC_ADIFFB_U_SN, TILE_OPC_ADIFFH_SN, TILE_OPC_AND_SN, 1398 TILEPRO_OPC_ADD_SN, TILEPRO_OPC_ADIFFB_U_SN, TILEPRO_OPC_ADIFFH_SN,
1363 TILE_OPC_AVGB_U_SN, TILE_OPC_AVGH_SN, TILE_OPC_CRC32_32_SN, 1399 TILEPRO_OPC_AND_SN, TILEPRO_OPC_AVGB_U_SN, TILEPRO_OPC_AVGH_SN,
1364 TILE_OPC_CRC32_8_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN, 1400 TILEPRO_OPC_CRC32_32_SN, TILEPRO_OPC_CRC32_8_SN, TILEPRO_OPC_INTHB_SN,
1365 TILE_OPC_INTLB_SN, TILE_OPC_INTLH_SN, TILE_OPC_MAXB_U_SN, 1401 TILEPRO_OPC_INTHH_SN, TILEPRO_OPC_INTLB_SN, TILEPRO_OPC_INTLH_SN,
1402 TILEPRO_OPC_MAXB_U_SN,
1366 BITFIELD(18, 4) /* index 680 */, 1403 BITFIELD(18, 4) /* index 680 */,
1367 TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN, TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN, 1404 TILEPRO_OPC_MAXH_SN, TILEPRO_OPC_MINB_U_SN, TILEPRO_OPC_MINH_SN,
1368 TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN, TILE_OPC_MULHHA_SS_SN, 1405 TILEPRO_OPC_MNZB_SN, TILEPRO_OPC_MNZH_SN, TILEPRO_OPC_MNZ_SN,
1369 TILE_OPC_MULHHA_SU_SN, TILE_OPC_MULHHA_UU_SN, TILE_OPC_MULHHSA_UU_SN, 1406 TILEPRO_OPC_MULHHA_SS_SN, TILEPRO_OPC_MULHHA_SU_SN,
1370 TILE_OPC_MULHH_SS_SN, TILE_OPC_MULHH_SU_SN, TILE_OPC_MULHH_UU_SN, 1407 TILEPRO_OPC_MULHHA_UU_SN, TILEPRO_OPC_MULHHSA_UU_SN,
1371 TILE_OPC_MULHLA_SS_SN, TILE_OPC_MULHLA_SU_SN, TILE_OPC_MULHLA_US_SN, 1408 TILEPRO_OPC_MULHH_SS_SN, TILEPRO_OPC_MULHH_SU_SN, TILEPRO_OPC_MULHH_UU_SN,
1409 TILEPRO_OPC_MULHLA_SS_SN, TILEPRO_OPC_MULHLA_SU_SN,
1410 TILEPRO_OPC_MULHLA_US_SN,
1372 BITFIELD(18, 4) /* index 697 */, 1411 BITFIELD(18, 4) /* index 697 */,
1373 TILE_OPC_MULHLA_UU_SN, TILE_OPC_MULHLSA_UU_SN, TILE_OPC_MULHL_SS_SN, 1412 TILEPRO_OPC_MULHLA_UU_SN, TILEPRO_OPC_MULHLSA_UU_SN,
1374 TILE_OPC_MULHL_SU_SN, TILE_OPC_MULHL_US_SN, TILE_OPC_MULHL_UU_SN, 1413 TILEPRO_OPC_MULHL_SS_SN, TILEPRO_OPC_MULHL_SU_SN, TILEPRO_OPC_MULHL_US_SN,
1375 TILE_OPC_MULLLA_SS_SN, TILE_OPC_MULLLA_SU_SN, TILE_OPC_MULLLA_UU_SN, 1414 TILEPRO_OPC_MULHL_UU_SN, TILEPRO_OPC_MULLLA_SS_SN, TILEPRO_OPC_MULLLA_SU_SN,
1376 TILE_OPC_MULLLSA_UU_SN, TILE_OPC_MULLL_SS_SN, TILE_OPC_MULLL_SU_SN, 1415 TILEPRO_OPC_MULLLA_UU_SN, TILEPRO_OPC_MULLLSA_UU_SN,
1377 TILE_OPC_MULLL_UU_SN, TILE_OPC_MVNZ_SN, TILE_OPC_MVZ_SN, TILE_OPC_MZB_SN, 1416 TILEPRO_OPC_MULLL_SS_SN, TILEPRO_OPC_MULLL_SU_SN, TILEPRO_OPC_MULLL_UU_SN,
1417 TILEPRO_OPC_MVNZ_SN, TILEPRO_OPC_MVZ_SN, TILEPRO_OPC_MZB_SN,
1378 BITFIELD(18, 4) /* index 714 */, 1418 BITFIELD(18, 4) /* index 714 */,
1379 TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN, CHILD(731), 1419 TILEPRO_OPC_MZH_SN, TILEPRO_OPC_MZ_SN, TILEPRO_OPC_NOR_SN, CHILD(731),
1380 TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN, TILE_OPC_S1A_SN, 1420 TILEPRO_OPC_PACKHB_SN, TILEPRO_OPC_PACKLB_SN, TILEPRO_OPC_RL_SN,
1381 TILE_OPC_S2A_SN, TILE_OPC_S3A_SN, TILE_OPC_SADAB_U_SN, TILE_OPC_SADAH_SN, 1421 TILEPRO_OPC_S1A_SN, TILEPRO_OPC_S2A_SN, TILEPRO_OPC_S3A_SN,
1382 TILE_OPC_SADAH_U_SN, TILE_OPC_SADB_U_SN, TILE_OPC_SADH_SN, 1422 TILEPRO_OPC_SADAB_U_SN, TILEPRO_OPC_SADAH_SN, TILEPRO_OPC_SADAH_U_SN,
1383 TILE_OPC_SADH_U_SN, 1423 TILEPRO_OPC_SADB_U_SN, TILEPRO_OPC_SADH_SN, TILEPRO_OPC_SADH_U_SN,
1384 BITFIELD(12, 2) /* index 731 */, 1424 BITFIELD(12, 2) /* index 731 */,
1385 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(736), 1425 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(736),
1386 BITFIELD(14, 2) /* index 736 */, 1426 BITFIELD(14, 2) /* index 736 */,
1387 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(741), 1427 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(741),
1388 BITFIELD(16, 2) /* index 741 */, 1428 BITFIELD(16, 2) /* index 741 */,
1389 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN, 1429 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN,
1430 TILEPRO_OPC_MOVE_SN,
1390 BITFIELD(18, 4) /* index 746 */, 1431 BITFIELD(18, 4) /* index 746 */,
1391 TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN, TILE_OPC_SHLB_SN, 1432 TILEPRO_OPC_SEQB_SN, TILEPRO_OPC_SEQH_SN, TILEPRO_OPC_SEQ_SN,
1392 TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN, TILE_OPC_SHRH_SN, 1433 TILEPRO_OPC_SHLB_SN, TILEPRO_OPC_SHLH_SN, TILEPRO_OPC_SHL_SN,
1393 TILE_OPC_SHR_SN, TILE_OPC_SLTB_SN, TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN, 1434 TILEPRO_OPC_SHRB_SN, TILEPRO_OPC_SHRH_SN, TILEPRO_OPC_SHR_SN,
1394 TILE_OPC_SLTEB_U_SN, TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN, 1435 TILEPRO_OPC_SLTB_SN, TILEPRO_OPC_SLTB_U_SN, TILEPRO_OPC_SLTEB_SN,
1395 TILE_OPC_SLTE_SN, 1436 TILEPRO_OPC_SLTEB_U_SN, TILEPRO_OPC_SLTEH_SN, TILEPRO_OPC_SLTEH_U_SN,
1437 TILEPRO_OPC_SLTE_SN,
1396 BITFIELD(18, 4) /* index 763 */, 1438 BITFIELD(18, 4) /* index 763 */,
1397 TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN, 1439 TILEPRO_OPC_SLTE_U_SN, TILEPRO_OPC_SLTH_SN, TILEPRO_OPC_SLTH_U_SN,
1398 TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN, 1440 TILEPRO_OPC_SLT_SN, TILEPRO_OPC_SLT_U_SN, TILEPRO_OPC_SNEB_SN,
1399 TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN, 1441 TILEPRO_OPC_SNEH_SN, TILEPRO_OPC_SNE_SN, TILEPRO_OPC_SRAB_SN,
1400 TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN, TILE_OPC_XOR_SN, TILE_OPC_DWORD_ALIGN_SN, 1442 TILEPRO_OPC_SRAH_SN, TILEPRO_OPC_SRA_SN, TILEPRO_OPC_SUBB_SN,
1443 TILEPRO_OPC_SUBH_SN, TILEPRO_OPC_SUB_SN, TILEPRO_OPC_XOR_SN,
1444 TILEPRO_OPC_DWORD_ALIGN_SN,
1401 BITFIELD(18, 3) /* index 780 */, 1445 BITFIELD(18, 3) /* index 780 */,
1402 CHILD(789), CHILD(792), CHILD(795), CHILD(798), CHILD(801), CHILD(804), 1446 CHILD(789), CHILD(792), CHILD(795), CHILD(798), CHILD(801), CHILD(804),
1403 CHILD(807), CHILD(810), 1447 CHILD(807), CHILD(810),
1404 BITFIELD(21, 1) /* index 789 */, 1448 BITFIELD(21, 1) /* index 789 */,
1405 TILE_OPC_ADDS_SN, TILE_OPC_NONE, 1449 TILEPRO_OPC_ADDS_SN, TILEPRO_OPC_NONE,
1406 BITFIELD(21, 1) /* index 792 */, 1450 BITFIELD(21, 1) /* index 792 */,
1407 TILE_OPC_SUBS_SN, TILE_OPC_NONE, 1451 TILEPRO_OPC_SUBS_SN, TILEPRO_OPC_NONE,
1408 BITFIELD(21, 1) /* index 795 */, 1452 BITFIELD(21, 1) /* index 795 */,
1409 TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE, 1453 TILEPRO_OPC_ADDBS_U_SN, TILEPRO_OPC_NONE,
1410 BITFIELD(21, 1) /* index 798 */, 1454 BITFIELD(21, 1) /* index 798 */,
1411 TILE_OPC_ADDHS_SN, TILE_OPC_NONE, 1455 TILEPRO_OPC_ADDHS_SN, TILEPRO_OPC_NONE,
1412 BITFIELD(21, 1) /* index 801 */, 1456 BITFIELD(21, 1) /* index 801 */,
1413 TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE, 1457 TILEPRO_OPC_SUBBS_U_SN, TILEPRO_OPC_NONE,
1414 BITFIELD(21, 1) /* index 804 */, 1458 BITFIELD(21, 1) /* index 804 */,
1415 TILE_OPC_SUBHS_SN, TILE_OPC_NONE, 1459 TILEPRO_OPC_SUBHS_SN, TILEPRO_OPC_NONE,
1416 BITFIELD(21, 1) /* index 807 */, 1460 BITFIELD(21, 1) /* index 807 */,
1417 TILE_OPC_PACKHS_SN, TILE_OPC_NONE, 1461 TILEPRO_OPC_PACKHS_SN, TILEPRO_OPC_NONE,
1418 BITFIELD(21, 1) /* index 810 */, 1462 BITFIELD(21, 1) /* index 810 */,
1419 TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE, 1463 TILEPRO_OPC_PACKBS_U_SN, TILEPRO_OPC_NONE,
1420 BITFIELD(6, 2) /* index 813 */, 1464 BITFIELD(6, 2) /* index 813 */,
1421 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(818), 1465 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1466 CHILD(818),
1422 BITFIELD(8, 2) /* index 818 */, 1467 BITFIELD(8, 2) /* index 818 */,
1423 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(823), 1468 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1469 CHILD(823),
1424 BITFIELD(10, 2) /* index 823 */, 1470 BITFIELD(10, 2) /* index 823 */,
1425 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN, 1471 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1472 TILEPRO_OPC_MOVELI_SN,
1426 BITFIELD(6, 2) /* index 828 */, 1473 BITFIELD(6, 2) /* index 828 */,
1427 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(833), 1474 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(833),
1428 BITFIELD(8, 2) /* index 833 */, 1475 BITFIELD(8, 2) /* index 833 */,
1429 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(838), 1476 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(838),
1430 BITFIELD(10, 2) /* index 838 */, 1477 BITFIELD(10, 2) /* index 838 */,
1431 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI, 1478 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_MOVELI,
1432 BITFIELD(0, 2) /* index 843 */, 1479 BITFIELD(0, 2) /* index 843 */,
1433 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(848), 1480 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(848),
1434 BITFIELD(2, 2) /* index 848 */, 1481 BITFIELD(2, 2) /* index 848 */,
1435 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(853), 1482 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(853),
1436 BITFIELD(4, 2) /* index 853 */, 1483 BITFIELD(4, 2) /* index 853 */,
1437 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(858), 1484 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(858),
1438 BITFIELD(6, 2) /* index 858 */, 1485 BITFIELD(6, 2) /* index 858 */,
1439 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(863), 1486 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(863),
1440 BITFIELD(8, 2) /* index 863 */, 1487 BITFIELD(8, 2) /* index 863 */,
1441 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(868), 1488 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(868),
1442 BITFIELD(10, 2) /* index 868 */, 1489 BITFIELD(10, 2) /* index 868 */,
1443 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL, 1490 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_INFOL,
1444 BITFIELD(20, 2) /* index 873 */, 1491 BITFIELD(20, 2) /* index 873 */,
1445 TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI, 1492 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB, TILEPRO_OPC_ADDIH, TILEPRO_OPC_ADDI,
1446 BITFIELD(20, 2) /* index 878 */, 1493 BITFIELD(20, 2) /* index 878 */,
1447 TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MINIB_U, TILE_OPC_MINIH, 1494 TILEPRO_OPC_MAXIB_U, TILEPRO_OPC_MAXIH, TILEPRO_OPC_MINIB_U,
1495 TILEPRO_OPC_MINIH,
1448 BITFIELD(20, 2) /* index 883 */, 1496 BITFIELD(20, 2) /* index 883 */,
1449 CHILD(888), TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI, 1497 CHILD(888), TILEPRO_OPC_SEQIB, TILEPRO_OPC_SEQIH, TILEPRO_OPC_SEQI,
1450 BITFIELD(6, 2) /* index 888 */, 1498 BITFIELD(6, 2) /* index 888 */,
1451 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(893), 1499 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(893),
1452 BITFIELD(8, 2) /* index 893 */, 1500 BITFIELD(8, 2) /* index 893 */,
1453 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(898), 1501 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(898),
1454 BITFIELD(10, 2) /* index 898 */, 1502 BITFIELD(10, 2) /* index 898 */,
1455 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI, 1503 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
1456 BITFIELD(20, 2) /* index 903 */, 1504 BITFIELD(20, 2) /* index 903 */,
1457 TILE_OPC_SLTIB, TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U, 1505 TILEPRO_OPC_SLTIB, TILEPRO_OPC_SLTIB_U, TILEPRO_OPC_SLTIH,
1506 TILEPRO_OPC_SLTIH_U,
1458 BITFIELD(20, 2) /* index 908 */, 1507 BITFIELD(20, 2) /* index 908 */,
1459 TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE, 1508 TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1460 BITFIELD(20, 2) /* index 913 */, 1509 BITFIELD(20, 2) /* index 913 */,
1461 TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN, 1510 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB_SN, TILEPRO_OPC_ADDIH_SN,
1511 TILEPRO_OPC_ADDI_SN,
1462 BITFIELD(20, 2) /* index 918 */, 1512 BITFIELD(20, 2) /* index 918 */,
1463 TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MINIB_U_SN, 1513 TILEPRO_OPC_MAXIB_U_SN, TILEPRO_OPC_MAXIH_SN, TILEPRO_OPC_MINIB_U_SN,
1464 TILE_OPC_MINIH_SN, 1514 TILEPRO_OPC_MINIH_SN,
1465 BITFIELD(20, 2) /* index 923 */, 1515 BITFIELD(20, 2) /* index 923 */,
1466 CHILD(928), TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN, 1516 CHILD(928), TILEPRO_OPC_SEQIB_SN, TILEPRO_OPC_SEQIH_SN, TILEPRO_OPC_SEQI_SN,
1467 BITFIELD(6, 2) /* index 928 */, 1517 BITFIELD(6, 2) /* index 928 */,
1468 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(933), 1518 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(933),
1469 BITFIELD(8, 2) /* index 933 */, 1519 BITFIELD(8, 2) /* index 933 */,
1470 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(938), 1520 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(938),
1471 BITFIELD(10, 2) /* index 938 */, 1521 BITFIELD(10, 2) /* index 938 */,
1472 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN, 1522 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN,
1523 TILEPRO_OPC_MOVEI_SN,
1473 BITFIELD(20, 2) /* index 943 */, 1524 BITFIELD(20, 2) /* index 943 */,
1474 TILE_OPC_SLTIB_SN, TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN, 1525 TILEPRO_OPC_SLTIB_SN, TILEPRO_OPC_SLTIB_U_SN, TILEPRO_OPC_SLTIH_SN,
1475 TILE_OPC_SLTIH_U_SN, 1526 TILEPRO_OPC_SLTIH_U_SN,
1476 BITFIELD(20, 2) /* index 948 */, 1527 BITFIELD(20, 2) /* index 948 */,
1477 TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_NONE, TILE_OPC_NONE, 1528 TILEPRO_OPC_SLTI_SN, TILEPRO_OPC_SLTI_U_SN, TILEPRO_OPC_NONE,
1529 TILEPRO_OPC_NONE,
1478 BITFIELD(20, 2) /* index 953 */, 1530 BITFIELD(20, 2) /* index 953 */,
1479 TILE_OPC_NONE, CHILD(958), TILE_OPC_XORI, TILE_OPC_NONE, 1531 TILEPRO_OPC_NONE, CHILD(958), TILEPRO_OPC_XORI, TILEPRO_OPC_NONE,
1480 BITFIELD(0, 2) /* index 958 */, 1532 BITFIELD(0, 2) /* index 958 */,
1481 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(963), 1533 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(963),
1482 BITFIELD(2, 2) /* index 963 */, 1534 BITFIELD(2, 2) /* index 963 */,
1483 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(968), 1535 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(968),
1484 BITFIELD(4, 2) /* index 968 */, 1536 BITFIELD(4, 2) /* index 968 */,
1485 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(973), 1537 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(973),
1486 BITFIELD(6, 2) /* index 973 */, 1538 BITFIELD(6, 2) /* index 973 */,
1487 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(978), 1539 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(978),
1488 BITFIELD(8, 2) /* index 978 */, 1540 BITFIELD(8, 2) /* index 978 */,
1489 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(983), 1541 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(983),
1490 BITFIELD(10, 2) /* index 983 */, 1542 BITFIELD(10, 2) /* index 983 */,
1491 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO, 1543 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
1492 BITFIELD(20, 2) /* index 988 */, 1544 BITFIELD(20, 2) /* index 988 */,
1493 TILE_OPC_NONE, TILE_OPC_ANDI_SN, TILE_OPC_XORI_SN, TILE_OPC_NONE, 1545 TILEPRO_OPC_NONE, TILEPRO_OPC_ANDI_SN, TILEPRO_OPC_XORI_SN,
1546 TILEPRO_OPC_NONE,
1494 BITFIELD(17, 5) /* index 993 */, 1547 BITFIELD(17, 5) /* index 993 */,
1495 TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLIB, TILE_OPC_SHLIH, TILE_OPC_SHLI, 1548 TILEPRO_OPC_NONE, TILEPRO_OPC_RLI, TILEPRO_OPC_SHLIB, TILEPRO_OPC_SHLIH,
1496 TILE_OPC_SHRIB, TILE_OPC_SHRIH, TILE_OPC_SHRI, TILE_OPC_SRAIB, 1549 TILEPRO_OPC_SHLI, TILEPRO_OPC_SHRIB, TILEPRO_OPC_SHRIH, TILEPRO_OPC_SHRI,
1497 TILE_OPC_SRAIH, TILE_OPC_SRAI, CHILD(1026), TILE_OPC_NONE, TILE_OPC_NONE, 1550 TILEPRO_OPC_SRAIB, TILEPRO_OPC_SRAIH, TILEPRO_OPC_SRAI, CHILD(1026),
1498 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1551 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1499 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1552 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1500 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1553 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1501 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1554 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1555 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1502 BITFIELD(12, 4) /* index 1026 */, 1556 BITFIELD(12, 4) /* index 1026 */,
1503 TILE_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052), 1557 TILEPRO_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052),
1504 CHILD(1055), CHILD(1058), CHILD(1061), CHILD(1064), CHILD(1067), 1558 CHILD(1055), CHILD(1058), CHILD(1061), CHILD(1064), CHILD(1067),
1505 CHILD(1070), CHILD(1073), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1559 CHILD(1070), CHILD(1073), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1506 TILE_OPC_NONE, 1560 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1507 BITFIELD(16, 1) /* index 1043 */, 1561 BITFIELD(16, 1) /* index 1043 */,
1508 TILE_OPC_BITX, TILE_OPC_NONE, 1562 TILEPRO_OPC_BITX, TILEPRO_OPC_NONE,
1509 BITFIELD(16, 1) /* index 1046 */, 1563 BITFIELD(16, 1) /* index 1046 */,
1510 TILE_OPC_BYTEX, TILE_OPC_NONE, 1564 TILEPRO_OPC_BYTEX, TILEPRO_OPC_NONE,
1511 BITFIELD(16, 1) /* index 1049 */, 1565 BITFIELD(16, 1) /* index 1049 */,
1512 TILE_OPC_CLZ, TILE_OPC_NONE, 1566 TILEPRO_OPC_CLZ, TILEPRO_OPC_NONE,
1513 BITFIELD(16, 1) /* index 1052 */, 1567 BITFIELD(16, 1) /* index 1052 */,
1514 TILE_OPC_CTZ, TILE_OPC_NONE, 1568 TILEPRO_OPC_CTZ, TILEPRO_OPC_NONE,
1515 BITFIELD(16, 1) /* index 1055 */, 1569 BITFIELD(16, 1) /* index 1055 */,
1516 TILE_OPC_FNOP, TILE_OPC_NONE, 1570 TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE,
1517 BITFIELD(16, 1) /* index 1058 */, 1571 BITFIELD(16, 1) /* index 1058 */,
1518 TILE_OPC_NOP, TILE_OPC_NONE, 1572 TILEPRO_OPC_NOP, TILEPRO_OPC_NONE,
1519 BITFIELD(16, 1) /* index 1061 */, 1573 BITFIELD(16, 1) /* index 1061 */,
1520 TILE_OPC_PCNT, TILE_OPC_NONE, 1574 TILEPRO_OPC_PCNT, TILEPRO_OPC_NONE,
1521 BITFIELD(16, 1) /* index 1064 */, 1575 BITFIELD(16, 1) /* index 1064 */,
1522 TILE_OPC_TBLIDXB0, TILE_OPC_NONE, 1576 TILEPRO_OPC_TBLIDXB0, TILEPRO_OPC_NONE,
1523 BITFIELD(16, 1) /* index 1067 */, 1577 BITFIELD(16, 1) /* index 1067 */,
1524 TILE_OPC_TBLIDXB1, TILE_OPC_NONE, 1578 TILEPRO_OPC_TBLIDXB1, TILEPRO_OPC_NONE,
1525 BITFIELD(16, 1) /* index 1070 */, 1579 BITFIELD(16, 1) /* index 1070 */,
1526 TILE_OPC_TBLIDXB2, TILE_OPC_NONE, 1580 TILEPRO_OPC_TBLIDXB2, TILEPRO_OPC_NONE,
1527 BITFIELD(16, 1) /* index 1073 */, 1581 BITFIELD(16, 1) /* index 1073 */,
1528 TILE_OPC_TBLIDXB3, TILE_OPC_NONE, 1582 TILEPRO_OPC_TBLIDXB3, TILEPRO_OPC_NONE,
1529 BITFIELD(17, 5) /* index 1076 */, 1583 BITFIELD(17, 5) /* index 1076 */,
1530 TILE_OPC_NONE, TILE_OPC_RLI_SN, TILE_OPC_SHLIB_SN, TILE_OPC_SHLIH_SN, 1584 TILEPRO_OPC_NONE, TILEPRO_OPC_RLI_SN, TILEPRO_OPC_SHLIB_SN,
1531 TILE_OPC_SHLI_SN, TILE_OPC_SHRIB_SN, TILE_OPC_SHRIH_SN, TILE_OPC_SHRI_SN, 1585 TILEPRO_OPC_SHLIH_SN, TILEPRO_OPC_SHLI_SN, TILEPRO_OPC_SHRIB_SN,
1532 TILE_OPC_SRAIB_SN, TILE_OPC_SRAIH_SN, TILE_OPC_SRAI_SN, CHILD(1109), 1586 TILEPRO_OPC_SHRIH_SN, TILEPRO_OPC_SHRI_SN, TILEPRO_OPC_SRAIB_SN,
1533 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1587 TILEPRO_OPC_SRAIH_SN, TILEPRO_OPC_SRAI_SN, CHILD(1109), TILEPRO_OPC_NONE,
1534 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1588 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1535 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1589 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1536 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1590 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1591 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1592 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1537 BITFIELD(12, 4) /* index 1109 */, 1593 BITFIELD(12, 4) /* index 1109 */,
1538 TILE_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135), 1594 TILEPRO_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135),
1539 CHILD(1055), CHILD(1058), CHILD(1138), CHILD(1141), CHILD(1144), 1595 CHILD(1055), CHILD(1058), CHILD(1138), CHILD(1141), CHILD(1144),
1540 CHILD(1147), CHILD(1150), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1596 CHILD(1147), CHILD(1150), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1541 TILE_OPC_NONE, 1597 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1542 BITFIELD(16, 1) /* index 1126 */, 1598 BITFIELD(16, 1) /* index 1126 */,
1543 TILE_OPC_BITX_SN, TILE_OPC_NONE, 1599 TILEPRO_OPC_BITX_SN, TILEPRO_OPC_NONE,
1544 BITFIELD(16, 1) /* index 1129 */, 1600 BITFIELD(16, 1) /* index 1129 */,
1545 TILE_OPC_BYTEX_SN, TILE_OPC_NONE, 1601 TILEPRO_OPC_BYTEX_SN, TILEPRO_OPC_NONE,
1546 BITFIELD(16, 1) /* index 1132 */, 1602 BITFIELD(16, 1) /* index 1132 */,
1547 TILE_OPC_CLZ_SN, TILE_OPC_NONE, 1603 TILEPRO_OPC_CLZ_SN, TILEPRO_OPC_NONE,
1548 BITFIELD(16, 1) /* index 1135 */, 1604 BITFIELD(16, 1) /* index 1135 */,
1549 TILE_OPC_CTZ_SN, TILE_OPC_NONE, 1605 TILEPRO_OPC_CTZ_SN, TILEPRO_OPC_NONE,
1550 BITFIELD(16, 1) /* index 1138 */, 1606 BITFIELD(16, 1) /* index 1138 */,
1551 TILE_OPC_PCNT_SN, TILE_OPC_NONE, 1607 TILEPRO_OPC_PCNT_SN, TILEPRO_OPC_NONE,
1552 BITFIELD(16, 1) /* index 1141 */, 1608 BITFIELD(16, 1) /* index 1141 */,
1553 TILE_OPC_TBLIDXB0_SN, TILE_OPC_NONE, 1609 TILEPRO_OPC_TBLIDXB0_SN, TILEPRO_OPC_NONE,
1554 BITFIELD(16, 1) /* index 1144 */, 1610 BITFIELD(16, 1) /* index 1144 */,
1555 TILE_OPC_TBLIDXB1_SN, TILE_OPC_NONE, 1611 TILEPRO_OPC_TBLIDXB1_SN, TILEPRO_OPC_NONE,
1556 BITFIELD(16, 1) /* index 1147 */, 1612 BITFIELD(16, 1) /* index 1147 */,
1557 TILE_OPC_TBLIDXB2_SN, TILE_OPC_NONE, 1613 TILEPRO_OPC_TBLIDXB2_SN, TILEPRO_OPC_NONE,
1558 BITFIELD(16, 1) /* index 1150 */, 1614 BITFIELD(16, 1) /* index 1150 */,
1559 TILE_OPC_TBLIDXB3_SN, TILE_OPC_NONE, 1615 TILEPRO_OPC_TBLIDXB3_SN, TILEPRO_OPC_NONE,
1560}; 1616};
1561 1617
1562static const unsigned short decode_X1_fsm[1540] = 1618static const unsigned short decode_X1_fsm[1540] =
1563{ 1619{
1564 BITFIELD(54, 9) /* index 0 */, 1620 BITFIELD(54, 9) /* index 0 */,
1565 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1621 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1566 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1622 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1567 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1623 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1568 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1624 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1569 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1625 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1570 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1626 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1571 TILE_OPC_NONE, TILE_OPC_NONE, CHILD(513), CHILD(561), CHILD(594), 1627 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1572 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1628 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1573 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1629 CHILD(513), CHILD(561), CHILD(594), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1574 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(641), CHILD(689), 1630 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1575 CHILD(722), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1631 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1576 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1632 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(641),
1577 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(766), 1633 CHILD(689), CHILD(722), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1634 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1635 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1636 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(766),
1578 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), 1637 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1579 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), 1638 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
1580 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), 1639 CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
@@ -1596,594 +1655,641 @@ static const unsigned short decode_X1_fsm[1540] =
1596 CHILD(826), CHILD(826), CHILD(826), CHILD(843), CHILD(843), CHILD(843), 1655 CHILD(826), CHILD(826), CHILD(826), CHILD(843), CHILD(843), CHILD(843),
1597 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1656 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1598 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), 1657 CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
1599 CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932), TILE_OPC_NONE, 1658 CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932),
1600 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1659 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1601 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1660 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1602 TILE_OPC_NONE, CHILD(941), CHILD(950), CHILD(974), CHILD(983), 1661 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1603 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1662 CHILD(941), CHILD(950), CHILD(974), CHILD(983), TILEPRO_OPC_NONE,
1604 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1663 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1605 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1664 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1606 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1665 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_MM,
1607 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1666 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1608 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1667 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1609 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1668 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1610 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, 1669 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1611 TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(992), 1670 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1612 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1671 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1613 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1672 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
1614 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1673 TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, CHILD(992),
1615 CHILD(1334), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1674 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1616 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1675 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1617 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1676 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1618 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1677 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(1334),
1619 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1678 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1620 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1679 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1621 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1680 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1622 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1681 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1623 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1682 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1624 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_J, TILE_OPC_J, 1683 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1625 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1684 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1626 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1685 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1627 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1686 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1628 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1687 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1629 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1688 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1630 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1689 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_J,
1631 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1690 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1632 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1691 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1633 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1692 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1634 TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, 1693 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1635 TILE_OPC_J, TILE_OPC_J, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1694 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1636 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1695 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1637 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1696 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1638 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1697 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1639 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1698 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1640 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1699 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1641 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1700 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1642 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1701 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
1643 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1702 TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_JAL,
1644 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1703 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1645 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1704 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1646 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1705 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1647 TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, 1706 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1648 TILE_OPC_JAL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1707 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1649 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1708 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1650 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1709 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1651 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1710 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1652 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1711 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1653 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1712 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1654 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1713 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1655 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1714 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1656 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1715 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1657 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1716 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1658 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1717 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
1659 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1718 TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_NONE,
1660 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1719 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1720 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1721 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1722 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1723 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1724 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1725 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1726 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1727 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1728 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1729 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1730 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1731 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1732 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1733 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1734 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1661 BITFIELD(49, 5) /* index 513 */, 1735 BITFIELD(49, 5) /* index 513 */,
1662 TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD, TILE_OPC_AND, 1736 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB, TILEPRO_OPC_ADDH, TILEPRO_OPC_ADD,
1663 TILE_OPC_INTHB, TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH, 1737 TILEPRO_OPC_AND, TILEPRO_OPC_INTHB, TILEPRO_OPC_INTHH, TILEPRO_OPC_INTLB,
1664 TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR, TILE_OPC_LNK, 1738 TILEPRO_OPC_INTLH, TILEPRO_OPC_JALRP, TILEPRO_OPC_JALR, TILEPRO_OPC_JRP,
1665 TILE_OPC_MAXB_U, TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH, 1739 TILEPRO_OPC_JR, TILEPRO_OPC_LNK, TILEPRO_OPC_MAXB_U, TILEPRO_OPC_MAXH,
1666 TILE_OPC_MNZB, TILE_OPC_MNZH, TILE_OPC_MNZ, TILE_OPC_MZB, TILE_OPC_MZH, 1740 TILEPRO_OPC_MINB_U, TILEPRO_OPC_MINH, TILEPRO_OPC_MNZB, TILEPRO_OPC_MNZH,
1667 TILE_OPC_MZ, TILE_OPC_NOR, CHILD(546), TILE_OPC_PACKHB, TILE_OPC_PACKLB, 1741 TILEPRO_OPC_MNZ, TILEPRO_OPC_MZB, TILEPRO_OPC_MZH, TILEPRO_OPC_MZ,
1668 TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A, 1742 TILEPRO_OPC_NOR, CHILD(546), TILEPRO_OPC_PACKHB, TILEPRO_OPC_PACKLB,
1743 TILEPRO_OPC_RL, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_S3A,
1669 BITFIELD(43, 2) /* index 546 */, 1744 BITFIELD(43, 2) /* index 546 */,
1670 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(551), 1745 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(551),
1671 BITFIELD(45, 2) /* index 551 */, 1746 BITFIELD(45, 2) /* index 551 */,
1672 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(556), 1747 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(556),
1673 BITFIELD(47, 2) /* index 556 */, 1748 BITFIELD(47, 2) /* index 556 */,
1674 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE, 1749 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
1675 BITFIELD(49, 5) /* index 561 */, 1750 BITFIELD(49, 5) /* index 561 */,
1676 TILE_OPC_SB, TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB, 1751 TILEPRO_OPC_SB, TILEPRO_OPC_SEQB, TILEPRO_OPC_SEQH, TILEPRO_OPC_SEQ,
1677 TILE_OPC_SHLH, TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR, 1752 TILEPRO_OPC_SHLB, TILEPRO_OPC_SHLH, TILEPRO_OPC_SHL, TILEPRO_OPC_SHRB,
1678 TILE_OPC_SH, TILE_OPC_SLTB, TILE_OPC_SLTB_U, TILE_OPC_SLTEB, 1753 TILEPRO_OPC_SHRH, TILEPRO_OPC_SHR, TILEPRO_OPC_SH, TILEPRO_OPC_SLTB,
1679 TILE_OPC_SLTEB_U, TILE_OPC_SLTEH, TILE_OPC_SLTEH_U, TILE_OPC_SLTE, 1754 TILEPRO_OPC_SLTB_U, TILEPRO_OPC_SLTEB, TILEPRO_OPC_SLTEB_U,
1680 TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT, 1755 TILEPRO_OPC_SLTEH, TILEPRO_OPC_SLTEH_U, TILEPRO_OPC_SLTE,
1681 TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB, 1756 TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLTH, TILEPRO_OPC_SLTH_U, TILEPRO_OPC_SLT,
1682 TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB, 1757 TILEPRO_OPC_SLT_U, TILEPRO_OPC_SNEB, TILEPRO_OPC_SNEH, TILEPRO_OPC_SNE,
1758 TILEPRO_OPC_SRAB, TILEPRO_OPC_SRAH, TILEPRO_OPC_SRA, TILEPRO_OPC_SUBB,
1759 TILEPRO_OPC_SUBH, TILEPRO_OPC_SUB,
1683 BITFIELD(49, 4) /* index 594 */, 1760 BITFIELD(49, 4) /* index 594 */,
1684 CHILD(611), CHILD(614), CHILD(617), CHILD(620), CHILD(623), CHILD(626), 1761 CHILD(611), CHILD(614), CHILD(617), CHILD(620), CHILD(623), CHILD(626),
1685 CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILE_OPC_NONE, 1762 CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILEPRO_OPC_NONE,
1686 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1763 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1764 TILEPRO_OPC_NONE,
1687 BITFIELD(53, 1) /* index 611 */, 1765 BITFIELD(53, 1) /* index 611 */,
1688 TILE_OPC_SW, TILE_OPC_NONE, 1766 TILEPRO_OPC_SW, TILEPRO_OPC_NONE,
1689 BITFIELD(53, 1) /* index 614 */, 1767 BITFIELD(53, 1) /* index 614 */,
1690 TILE_OPC_XOR, TILE_OPC_NONE, 1768 TILEPRO_OPC_XOR, TILEPRO_OPC_NONE,
1691 BITFIELD(53, 1) /* index 617 */, 1769 BITFIELD(53, 1) /* index 617 */,
1692 TILE_OPC_ADDS, TILE_OPC_NONE, 1770 TILEPRO_OPC_ADDS, TILEPRO_OPC_NONE,
1693 BITFIELD(53, 1) /* index 620 */, 1771 BITFIELD(53, 1) /* index 620 */,
1694 TILE_OPC_SUBS, TILE_OPC_NONE, 1772 TILEPRO_OPC_SUBS, TILEPRO_OPC_NONE,
1695 BITFIELD(53, 1) /* index 623 */, 1773 BITFIELD(53, 1) /* index 623 */,
1696 TILE_OPC_ADDBS_U, TILE_OPC_NONE, 1774 TILEPRO_OPC_ADDBS_U, TILEPRO_OPC_NONE,
1697 BITFIELD(53, 1) /* index 626 */, 1775 BITFIELD(53, 1) /* index 626 */,
1698 TILE_OPC_ADDHS, TILE_OPC_NONE, 1776 TILEPRO_OPC_ADDHS, TILEPRO_OPC_NONE,
1699 BITFIELD(53, 1) /* index 629 */, 1777 BITFIELD(53, 1) /* index 629 */,
1700 TILE_OPC_SUBBS_U, TILE_OPC_NONE, 1778 TILEPRO_OPC_SUBBS_U, TILEPRO_OPC_NONE,
1701 BITFIELD(53, 1) /* index 632 */, 1779 BITFIELD(53, 1) /* index 632 */,
1702 TILE_OPC_SUBHS, TILE_OPC_NONE, 1780 TILEPRO_OPC_SUBHS, TILEPRO_OPC_NONE,
1703 BITFIELD(53, 1) /* index 635 */, 1781 BITFIELD(53, 1) /* index 635 */,
1704 TILE_OPC_PACKHS, TILE_OPC_NONE, 1782 TILEPRO_OPC_PACKHS, TILEPRO_OPC_NONE,
1705 BITFIELD(53, 1) /* index 638 */, 1783 BITFIELD(53, 1) /* index 638 */,
1706 TILE_OPC_PACKBS_U, TILE_OPC_NONE, 1784 TILEPRO_OPC_PACKBS_U, TILEPRO_OPC_NONE,
1707 BITFIELD(49, 5) /* index 641 */, 1785 BITFIELD(49, 5) /* index 641 */,
1708 TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN, 1786 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB_SN, TILEPRO_OPC_ADDH_SN,
1709 TILE_OPC_AND_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN, TILE_OPC_INTLB_SN, 1787 TILEPRO_OPC_ADD_SN, TILEPRO_OPC_AND_SN, TILEPRO_OPC_INTHB_SN,
1710 TILE_OPC_INTLH_SN, TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR, 1788 TILEPRO_OPC_INTHH_SN, TILEPRO_OPC_INTLB_SN, TILEPRO_OPC_INTLH_SN,
1711 TILE_OPC_LNK_SN, TILE_OPC_MAXB_U_SN, TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN, 1789 TILEPRO_OPC_JALRP, TILEPRO_OPC_JALR, TILEPRO_OPC_JRP, TILEPRO_OPC_JR,
1712 TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN, TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN, 1790 TILEPRO_OPC_LNK_SN, TILEPRO_OPC_MAXB_U_SN, TILEPRO_OPC_MAXH_SN,
1713 TILE_OPC_MZB_SN, TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN, 1791 TILEPRO_OPC_MINB_U_SN, TILEPRO_OPC_MINH_SN, TILEPRO_OPC_MNZB_SN,
1714 CHILD(674), TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN, 1792 TILEPRO_OPC_MNZH_SN, TILEPRO_OPC_MNZ_SN, TILEPRO_OPC_MZB_SN,
1715 TILE_OPC_S1A_SN, TILE_OPC_S2A_SN, TILE_OPC_S3A_SN, 1793 TILEPRO_OPC_MZH_SN, TILEPRO_OPC_MZ_SN, TILEPRO_OPC_NOR_SN, CHILD(674),
1794 TILEPRO_OPC_PACKHB_SN, TILEPRO_OPC_PACKLB_SN, TILEPRO_OPC_RL_SN,
1795 TILEPRO_OPC_S1A_SN, TILEPRO_OPC_S2A_SN, TILEPRO_OPC_S3A_SN,
1716 BITFIELD(43, 2) /* index 674 */, 1796 BITFIELD(43, 2) /* index 674 */,
1717 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(679), 1797 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(679),
1718 BITFIELD(45, 2) /* index 679 */, 1798 BITFIELD(45, 2) /* index 679 */,
1719 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(684), 1799 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(684),
1720 BITFIELD(47, 2) /* index 684 */, 1800 BITFIELD(47, 2) /* index 684 */,
1721 TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN, 1801 TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN,
1802 TILEPRO_OPC_MOVE_SN,
1722 BITFIELD(49, 5) /* index 689 */, 1803 BITFIELD(49, 5) /* index 689 */,
1723 TILE_OPC_SB, TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN, 1804 TILEPRO_OPC_SB, TILEPRO_OPC_SEQB_SN, TILEPRO_OPC_SEQH_SN,
1724 TILE_OPC_SHLB_SN, TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN, 1805 TILEPRO_OPC_SEQ_SN, TILEPRO_OPC_SHLB_SN, TILEPRO_OPC_SHLH_SN,
1725 TILE_OPC_SHRH_SN, TILE_OPC_SHR_SN, TILE_OPC_SH, TILE_OPC_SLTB_SN, 1806 TILEPRO_OPC_SHL_SN, TILEPRO_OPC_SHRB_SN, TILEPRO_OPC_SHRH_SN,
1726 TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN, TILE_OPC_SLTEB_U_SN, 1807 TILEPRO_OPC_SHR_SN, TILEPRO_OPC_SH, TILEPRO_OPC_SLTB_SN,
1727 TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN, TILE_OPC_SLTE_SN, 1808 TILEPRO_OPC_SLTB_U_SN, TILEPRO_OPC_SLTEB_SN, TILEPRO_OPC_SLTEB_U_SN,
1728 TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN, 1809 TILEPRO_OPC_SLTEH_SN, TILEPRO_OPC_SLTEH_U_SN, TILEPRO_OPC_SLTE_SN,
1729 TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN, 1810 TILEPRO_OPC_SLTE_U_SN, TILEPRO_OPC_SLTH_SN, TILEPRO_OPC_SLTH_U_SN,
1730 TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN, 1811 TILEPRO_OPC_SLT_SN, TILEPRO_OPC_SLT_U_SN, TILEPRO_OPC_SNEB_SN,
1731 TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN, 1812 TILEPRO_OPC_SNEH_SN, TILEPRO_OPC_SNE_SN, TILEPRO_OPC_SRAB_SN,
1813 TILEPRO_OPC_SRAH_SN, TILEPRO_OPC_SRA_SN, TILEPRO_OPC_SUBB_SN,
1814 TILEPRO_OPC_SUBH_SN, TILEPRO_OPC_SUB_SN,
1732 BITFIELD(49, 4) /* index 722 */, 1815 BITFIELD(49, 4) /* index 722 */,
1733 CHILD(611), CHILD(739), CHILD(742), CHILD(745), CHILD(748), CHILD(751), 1816 CHILD(611), CHILD(739), CHILD(742), CHILD(745), CHILD(748), CHILD(751),
1734 CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILE_OPC_NONE, 1817 CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILEPRO_OPC_NONE,
1735 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1818 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1819 TILEPRO_OPC_NONE,
1736 BITFIELD(53, 1) /* index 739 */, 1820 BITFIELD(53, 1) /* index 739 */,
1737 TILE_OPC_XOR_SN, TILE_OPC_NONE, 1821 TILEPRO_OPC_XOR_SN, TILEPRO_OPC_NONE,
1738 BITFIELD(53, 1) /* index 742 */, 1822 BITFIELD(53, 1) /* index 742 */,
1739 TILE_OPC_ADDS_SN, TILE_OPC_NONE, 1823 TILEPRO_OPC_ADDS_SN, TILEPRO_OPC_NONE,
1740 BITFIELD(53, 1) /* index 745 */, 1824 BITFIELD(53, 1) /* index 745 */,
1741 TILE_OPC_SUBS_SN, TILE_OPC_NONE, 1825 TILEPRO_OPC_SUBS_SN, TILEPRO_OPC_NONE,
1742 BITFIELD(53, 1) /* index 748 */, 1826 BITFIELD(53, 1) /* index 748 */,
1743 TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE, 1827 TILEPRO_OPC_ADDBS_U_SN, TILEPRO_OPC_NONE,
1744 BITFIELD(53, 1) /* index 751 */, 1828 BITFIELD(53, 1) /* index 751 */,
1745 TILE_OPC_ADDHS_SN, TILE_OPC_NONE, 1829 TILEPRO_OPC_ADDHS_SN, TILEPRO_OPC_NONE,
1746 BITFIELD(53, 1) /* index 754 */, 1830 BITFIELD(53, 1) /* index 754 */,
1747 TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE, 1831 TILEPRO_OPC_SUBBS_U_SN, TILEPRO_OPC_NONE,
1748 BITFIELD(53, 1) /* index 757 */, 1832 BITFIELD(53, 1) /* index 757 */,
1749 TILE_OPC_SUBHS_SN, TILE_OPC_NONE, 1833 TILEPRO_OPC_SUBHS_SN, TILEPRO_OPC_NONE,
1750 BITFIELD(53, 1) /* index 760 */, 1834 BITFIELD(53, 1) /* index 760 */,
1751 TILE_OPC_PACKHS_SN, TILE_OPC_NONE, 1835 TILEPRO_OPC_PACKHS_SN, TILEPRO_OPC_NONE,
1752 BITFIELD(53, 1) /* index 763 */, 1836 BITFIELD(53, 1) /* index 763 */,
1753 TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE, 1837 TILEPRO_OPC_PACKBS_U_SN, TILEPRO_OPC_NONE,
1754 BITFIELD(37, 2) /* index 766 */, 1838 BITFIELD(37, 2) /* index 766 */,
1755 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(771), 1839 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1840 CHILD(771),
1756 BITFIELD(39, 2) /* index 771 */, 1841 BITFIELD(39, 2) /* index 771 */,
1757 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(776), 1842 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1843 CHILD(776),
1758 BITFIELD(41, 2) /* index 776 */, 1844 BITFIELD(41, 2) /* index 776 */,
1759 TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN, 1845 TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
1846 TILEPRO_OPC_MOVELI_SN,
1760 BITFIELD(37, 2) /* index 781 */, 1847 BITFIELD(37, 2) /* index 781 */,
1761 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(786), 1848 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(786),
1762 BITFIELD(39, 2) /* index 786 */, 1849 BITFIELD(39, 2) /* index 786 */,
1763 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(791), 1850 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(791),
1764 BITFIELD(41, 2) /* index 791 */, 1851 BITFIELD(41, 2) /* index 791 */,
1765 TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI, 1852 TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_MOVELI,
1766 BITFIELD(31, 2) /* index 796 */, 1853 BITFIELD(31, 2) /* index 796 */,
1767 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(801), 1854 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(801),
1768 BITFIELD(33, 2) /* index 801 */, 1855 BITFIELD(33, 2) /* index 801 */,
1769 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(806), 1856 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(806),
1770 BITFIELD(35, 2) /* index 806 */, 1857 BITFIELD(35, 2) /* index 806 */,
1771 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(811), 1858 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(811),
1772 BITFIELD(37, 2) /* index 811 */, 1859 BITFIELD(37, 2) /* index 811 */,
1773 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(816), 1860 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(816),
1774 BITFIELD(39, 2) /* index 816 */, 1861 BITFIELD(39, 2) /* index 816 */,
1775 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(821), 1862 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(821),
1776 BITFIELD(41, 2) /* index 821 */, 1863 BITFIELD(41, 2) /* index 821 */,
1777 TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL, 1864 TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_INFOL,
1778 BITFIELD(31, 4) /* index 826 */, 1865 BITFIELD(31, 4) /* index 826 */,
1779 TILE_OPC_BZ, TILE_OPC_BZT, TILE_OPC_BNZ, TILE_OPC_BNZT, TILE_OPC_BGZ, 1866 TILEPRO_OPC_BZ, TILEPRO_OPC_BZT, TILEPRO_OPC_BNZ, TILEPRO_OPC_BNZT,
1780 TILE_OPC_BGZT, TILE_OPC_BGEZ, TILE_OPC_BGEZT, TILE_OPC_BLZ, TILE_OPC_BLZT, 1867 TILEPRO_OPC_BGZ, TILEPRO_OPC_BGZT, TILEPRO_OPC_BGEZ, TILEPRO_OPC_BGEZT,
1781 TILE_OPC_BLEZ, TILE_OPC_BLEZT, TILE_OPC_BBS, TILE_OPC_BBST, TILE_OPC_BBNS, 1868 TILEPRO_OPC_BLZ, TILEPRO_OPC_BLZT, TILEPRO_OPC_BLEZ, TILEPRO_OPC_BLEZT,
1782 TILE_OPC_BBNST, 1869 TILEPRO_OPC_BBS, TILEPRO_OPC_BBST, TILEPRO_OPC_BBNS, TILEPRO_OPC_BBNST,
1783 BITFIELD(31, 4) /* index 843 */, 1870 BITFIELD(31, 4) /* index 843 */,
1784 TILE_OPC_BZ_SN, TILE_OPC_BZT_SN, TILE_OPC_BNZ_SN, TILE_OPC_BNZT_SN, 1871 TILEPRO_OPC_BZ_SN, TILEPRO_OPC_BZT_SN, TILEPRO_OPC_BNZ_SN,
1785 TILE_OPC_BGZ_SN, TILE_OPC_BGZT_SN, TILE_OPC_BGEZ_SN, TILE_OPC_BGEZT_SN, 1872 TILEPRO_OPC_BNZT_SN, TILEPRO_OPC_BGZ_SN, TILEPRO_OPC_BGZT_SN,
1786 TILE_OPC_BLZ_SN, TILE_OPC_BLZT_SN, TILE_OPC_BLEZ_SN, TILE_OPC_BLEZT_SN, 1873 TILEPRO_OPC_BGEZ_SN, TILEPRO_OPC_BGEZT_SN, TILEPRO_OPC_BLZ_SN,
1787 TILE_OPC_BBS_SN, TILE_OPC_BBST_SN, TILE_OPC_BBNS_SN, TILE_OPC_BBNST_SN, 1874 TILEPRO_OPC_BLZT_SN, TILEPRO_OPC_BLEZ_SN, TILEPRO_OPC_BLEZT_SN,
1875 TILEPRO_OPC_BBS_SN, TILEPRO_OPC_BBST_SN, TILEPRO_OPC_BBNS_SN,
1876 TILEPRO_OPC_BBNST_SN,
1788 BITFIELD(51, 3) /* index 860 */, 1877 BITFIELD(51, 3) /* index 860 */,
1789 TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI, CHILD(869), 1878 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB, TILEPRO_OPC_ADDIH, TILEPRO_OPC_ADDI,
1790 TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MFSPR, 1879 CHILD(869), TILEPRO_OPC_MAXIB_U, TILEPRO_OPC_MAXIH, TILEPRO_OPC_MFSPR,
1791 BITFIELD(31, 2) /* index 869 */, 1880 BITFIELD(31, 2) /* index 869 */,
1792 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(874), 1881 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(874),
1793 BITFIELD(33, 2) /* index 874 */, 1882 BITFIELD(33, 2) /* index 874 */,
1794 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(879), 1883 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(879),
1795 BITFIELD(35, 2) /* index 879 */, 1884 BITFIELD(35, 2) /* index 879 */,
1796 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(884), 1885 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(884),
1797 BITFIELD(37, 2) /* index 884 */, 1886 BITFIELD(37, 2) /* index 884 */,
1798 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(889), 1887 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(889),
1799 BITFIELD(39, 2) /* index 889 */, 1888 BITFIELD(39, 2) /* index 889 */,
1800 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(894), 1889 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(894),
1801 BITFIELD(41, 2) /* index 894 */, 1890 BITFIELD(41, 2) /* index 894 */,
1802 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO, 1891 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
1803 BITFIELD(51, 3) /* index 899 */, 1892 BITFIELD(51, 3) /* index 899 */,
1804 TILE_OPC_MINIB_U, TILE_OPC_MINIH, TILE_OPC_MTSPR, CHILD(908), 1893 TILEPRO_OPC_MINIB_U, TILEPRO_OPC_MINIH, TILEPRO_OPC_MTSPR, CHILD(908),
1805 TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI, TILE_OPC_SLTIB, 1894 TILEPRO_OPC_SEQIB, TILEPRO_OPC_SEQIH, TILEPRO_OPC_SEQI, TILEPRO_OPC_SLTIB,
1806 BITFIELD(37, 2) /* index 908 */, 1895 BITFIELD(37, 2) /* index 908 */,
1807 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(913), 1896 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(913),
1808 BITFIELD(39, 2) /* index 913 */, 1897 BITFIELD(39, 2) /* index 913 */,
1809 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(918), 1898 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(918),
1810 BITFIELD(41, 2) /* index 918 */, 1899 BITFIELD(41, 2) /* index 918 */,
1811 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI, 1900 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
1812 BITFIELD(51, 3) /* index 923 */, 1901 BITFIELD(51, 3) /* index 923 */,
1813 TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U, TILE_OPC_SLTI, 1902 TILEPRO_OPC_SLTIB_U, TILEPRO_OPC_SLTIH, TILEPRO_OPC_SLTIH_U,
1814 TILE_OPC_SLTI_U, TILE_OPC_XORI, TILE_OPC_LBADD, TILE_OPC_LBADD_U, 1903 TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_XORI, TILEPRO_OPC_LBADD,
1904 TILEPRO_OPC_LBADD_U,
1815 BITFIELD(51, 3) /* index 932 */, 1905 BITFIELD(51, 3) /* index 932 */,
1816 TILE_OPC_LHADD, TILE_OPC_LHADD_U, TILE_OPC_LWADD, TILE_OPC_LWADD_NA, 1906 TILEPRO_OPC_LHADD, TILEPRO_OPC_LHADD_U, TILEPRO_OPC_LWADD,
1817 TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD, TILE_OPC_NONE, 1907 TILEPRO_OPC_LWADD_NA, TILEPRO_OPC_SBADD, TILEPRO_OPC_SHADD,
1908 TILEPRO_OPC_SWADD, TILEPRO_OPC_NONE,
1818 BITFIELD(51, 3) /* index 941 */, 1909 BITFIELD(51, 3) /* index 941 */,
1819 TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN, 1910 TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB_SN, TILEPRO_OPC_ADDIH_SN,
1820 TILE_OPC_ANDI_SN, TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MFSPR, 1911 TILEPRO_OPC_ADDI_SN, TILEPRO_OPC_ANDI_SN, TILEPRO_OPC_MAXIB_U_SN,
1912 TILEPRO_OPC_MAXIH_SN, TILEPRO_OPC_MFSPR,
1821 BITFIELD(51, 3) /* index 950 */, 1913 BITFIELD(51, 3) /* index 950 */,
1822 TILE_OPC_MINIB_U_SN, TILE_OPC_MINIH_SN, TILE_OPC_MTSPR, CHILD(959), 1914 TILEPRO_OPC_MINIB_U_SN, TILEPRO_OPC_MINIH_SN, TILEPRO_OPC_MTSPR, CHILD(959),
1823 TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN, TILE_OPC_SLTIB_SN, 1915 TILEPRO_OPC_SEQIB_SN, TILEPRO_OPC_SEQIH_SN, TILEPRO_OPC_SEQI_SN,
1916 TILEPRO_OPC_SLTIB_SN,
1824 BITFIELD(37, 2) /* index 959 */, 1917 BITFIELD(37, 2) /* index 959 */,
1825 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(964), 1918 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(964),
1826 BITFIELD(39, 2) /* index 964 */, 1919 BITFIELD(39, 2) /* index 964 */,
1827 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(969), 1920 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(969),
1828 BITFIELD(41, 2) /* index 969 */, 1921 BITFIELD(41, 2) /* index 969 */,
1829 TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN, 1922 TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN,
1923 TILEPRO_OPC_MOVEI_SN,
1830 BITFIELD(51, 3) /* index 974 */, 1924 BITFIELD(51, 3) /* index 974 */,
1831 TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN, TILE_OPC_SLTIH_U_SN, 1925 TILEPRO_OPC_SLTIB_U_SN, TILEPRO_OPC_SLTIH_SN, TILEPRO_OPC_SLTIH_U_SN,
1832 TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_XORI_SN, TILE_OPC_LBADD_SN, 1926 TILEPRO_OPC_SLTI_SN, TILEPRO_OPC_SLTI_U_SN, TILEPRO_OPC_XORI_SN,
1833 TILE_OPC_LBADD_U_SN, 1927 TILEPRO_OPC_LBADD_SN, TILEPRO_OPC_LBADD_U_SN,
1834 BITFIELD(51, 3) /* index 983 */, 1928 BITFIELD(51, 3) /* index 983 */,
1835 TILE_OPC_LHADD_SN, TILE_OPC_LHADD_U_SN, TILE_OPC_LWADD_SN, 1929 TILEPRO_OPC_LHADD_SN, TILEPRO_OPC_LHADD_U_SN, TILEPRO_OPC_LWADD_SN,
1836 TILE_OPC_LWADD_NA_SN, TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD, 1930 TILEPRO_OPC_LWADD_NA_SN, TILEPRO_OPC_SBADD, TILEPRO_OPC_SHADD,
1837 TILE_OPC_NONE, 1931 TILEPRO_OPC_SWADD, TILEPRO_OPC_NONE,
1838 BITFIELD(46, 7) /* index 992 */, 1932 BITFIELD(46, 7) /* index 992 */,
1839 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1121), 1933 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1840 CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124), CHILD(1124), 1934 CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124),
1841 CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127), CHILD(1127), 1935 CHILD(1124), CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127),
1842 CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130), CHILD(1130), 1936 CHILD(1127), CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130),
1843 CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1136), 1937 CHILD(1130), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133),
1844 CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139), CHILD(1139), 1938 CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139),
1845 CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142), CHILD(1142), 1939 CHILD(1139), CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142),
1846 CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145), CHILD(1145), 1940 CHILD(1142), CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145),
1847 CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1151), 1941 CHILD(1145), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148),
1848 CHILD(1242), CHILD(1290), CHILD(1323), TILE_OPC_NONE, TILE_OPC_NONE, 1942 CHILD(1151), CHILD(1242), CHILD(1290), CHILD(1323), TILEPRO_OPC_NONE,
1849 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1943 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1850 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1944 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1851 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1945 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1852 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1946 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1853 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1947 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1854 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1948 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1855 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1949 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1856 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1950 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1857 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1951 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1858 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1952 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1859 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1953 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1860 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1954 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1861 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1955 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1862 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1956 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1863 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1957 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1864 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 1958 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1959 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1960 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1961 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1962 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1865 BITFIELD(53, 1) /* index 1121 */, 1963 BITFIELD(53, 1) /* index 1121 */,
1866 TILE_OPC_RLI, TILE_OPC_NONE, 1964 TILEPRO_OPC_RLI, TILEPRO_OPC_NONE,
1867 BITFIELD(53, 1) /* index 1124 */, 1965 BITFIELD(53, 1) /* index 1124 */,
1868 TILE_OPC_SHLIB, TILE_OPC_NONE, 1966 TILEPRO_OPC_SHLIB, TILEPRO_OPC_NONE,
1869 BITFIELD(53, 1) /* index 1127 */, 1967 BITFIELD(53, 1) /* index 1127 */,
1870 TILE_OPC_SHLIH, TILE_OPC_NONE, 1968 TILEPRO_OPC_SHLIH, TILEPRO_OPC_NONE,
1871 BITFIELD(53, 1) /* index 1130 */, 1969 BITFIELD(53, 1) /* index 1130 */,
1872 TILE_OPC_SHLI, TILE_OPC_NONE, 1970 TILEPRO_OPC_SHLI, TILEPRO_OPC_NONE,
1873 BITFIELD(53, 1) /* index 1133 */, 1971 BITFIELD(53, 1) /* index 1133 */,
1874 TILE_OPC_SHRIB, TILE_OPC_NONE, 1972 TILEPRO_OPC_SHRIB, TILEPRO_OPC_NONE,
1875 BITFIELD(53, 1) /* index 1136 */, 1973 BITFIELD(53, 1) /* index 1136 */,
1876 TILE_OPC_SHRIH, TILE_OPC_NONE, 1974 TILEPRO_OPC_SHRIH, TILEPRO_OPC_NONE,
1877 BITFIELD(53, 1) /* index 1139 */, 1975 BITFIELD(53, 1) /* index 1139 */,
1878 TILE_OPC_SHRI, TILE_OPC_NONE, 1976 TILEPRO_OPC_SHRI, TILEPRO_OPC_NONE,
1879 BITFIELD(53, 1) /* index 1142 */, 1977 BITFIELD(53, 1) /* index 1142 */,
1880 TILE_OPC_SRAIB, TILE_OPC_NONE, 1978 TILEPRO_OPC_SRAIB, TILEPRO_OPC_NONE,
1881 BITFIELD(53, 1) /* index 1145 */, 1979 BITFIELD(53, 1) /* index 1145 */,
1882 TILE_OPC_SRAIH, TILE_OPC_NONE, 1980 TILEPRO_OPC_SRAIH, TILEPRO_OPC_NONE,
1883 BITFIELD(53, 1) /* index 1148 */, 1981 BITFIELD(53, 1) /* index 1148 */,
1884 TILE_OPC_SRAI, TILE_OPC_NONE, 1982 TILEPRO_OPC_SRAI, TILEPRO_OPC_NONE,
1885 BITFIELD(43, 3) /* index 1151 */, 1983 BITFIELD(43, 3) /* index 1151 */,
1886 TILE_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169), 1984 TILEPRO_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169),
1887 CHILD(1172), CHILD(1175), CHILD(1178), 1985 CHILD(1172), CHILD(1175), CHILD(1178),
1888 BITFIELD(53, 1) /* index 1160 */, 1986 BITFIELD(53, 1) /* index 1160 */,
1889 TILE_OPC_DRAIN, TILE_OPC_NONE, 1987 TILEPRO_OPC_DRAIN, TILEPRO_OPC_NONE,
1890 BITFIELD(53, 1) /* index 1163 */, 1988 BITFIELD(53, 1) /* index 1163 */,
1891 TILE_OPC_DTLBPR, TILE_OPC_NONE, 1989 TILEPRO_OPC_DTLBPR, TILEPRO_OPC_NONE,
1892 BITFIELD(53, 1) /* index 1166 */, 1990 BITFIELD(53, 1) /* index 1166 */,
1893 TILE_OPC_FINV, TILE_OPC_NONE, 1991 TILEPRO_OPC_FINV, TILEPRO_OPC_NONE,
1894 BITFIELD(53, 1) /* index 1169 */, 1992 BITFIELD(53, 1) /* index 1169 */,
1895 TILE_OPC_FLUSH, TILE_OPC_NONE, 1993 TILEPRO_OPC_FLUSH, TILEPRO_OPC_NONE,
1896 BITFIELD(53, 1) /* index 1172 */, 1994 BITFIELD(53, 1) /* index 1172 */,
1897 TILE_OPC_FNOP, TILE_OPC_NONE, 1995 TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE,
1898 BITFIELD(53, 1) /* index 1175 */, 1996 BITFIELD(53, 1) /* index 1175 */,
1899 TILE_OPC_ICOH, TILE_OPC_NONE, 1997 TILEPRO_OPC_ICOH, TILEPRO_OPC_NONE,
1900 BITFIELD(31, 2) /* index 1178 */, 1998 BITFIELD(31, 2) /* index 1178 */,
1901 CHILD(1183), CHILD(1211), CHILD(1239), CHILD(1239), 1999 CHILD(1183), CHILD(1211), CHILD(1239), CHILD(1239),
1902 BITFIELD(53, 1) /* index 1183 */, 2000 BITFIELD(53, 1) /* index 1183 */,
1903 CHILD(1186), TILE_OPC_NONE, 2001 CHILD(1186), TILEPRO_OPC_NONE,
1904 BITFIELD(33, 2) /* index 1186 */, 2002 BITFIELD(33, 2) /* index 1186 */,
1905 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1191), 2003 TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, CHILD(1191),
1906 BITFIELD(35, 2) /* index 1191 */, 2004 BITFIELD(35, 2) /* index 1191 */,
1907 TILE_OPC_ILL, CHILD(1196), TILE_OPC_ILL, TILE_OPC_ILL, 2005 TILEPRO_OPC_ILL, CHILD(1196), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1908 BITFIELD(37, 2) /* index 1196 */, 2006 BITFIELD(37, 2) /* index 1196 */,
1909 TILE_OPC_ILL, CHILD(1201), TILE_OPC_ILL, TILE_OPC_ILL, 2007 TILEPRO_OPC_ILL, CHILD(1201), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1910 BITFIELD(39, 2) /* index 1201 */, 2008 BITFIELD(39, 2) /* index 1201 */,
1911 TILE_OPC_ILL, CHILD(1206), TILE_OPC_ILL, TILE_OPC_ILL, 2009 TILEPRO_OPC_ILL, CHILD(1206), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1912 BITFIELD(41, 2) /* index 1206 */, 2010 BITFIELD(41, 2) /* index 1206 */,
1913 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_BPT, TILE_OPC_ILL, 2011 TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_BPT, TILEPRO_OPC_ILL,
1914 BITFIELD(53, 1) /* index 1211 */, 2012 BITFIELD(53, 1) /* index 1211 */,
1915 CHILD(1214), TILE_OPC_NONE, 2013 CHILD(1214), TILEPRO_OPC_NONE,
1916 BITFIELD(33, 2) /* index 1214 */, 2014 BITFIELD(33, 2) /* index 1214 */,
1917 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1219), 2015 TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, CHILD(1219),
1918 BITFIELD(35, 2) /* index 1219 */, 2016 BITFIELD(35, 2) /* index 1219 */,
1919 TILE_OPC_ILL, CHILD(1224), TILE_OPC_ILL, TILE_OPC_ILL, 2017 TILEPRO_OPC_ILL, CHILD(1224), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1920 BITFIELD(37, 2) /* index 1224 */, 2018 BITFIELD(37, 2) /* index 1224 */,
1921 TILE_OPC_ILL, CHILD(1229), TILE_OPC_ILL, TILE_OPC_ILL, 2019 TILEPRO_OPC_ILL, CHILD(1229), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1922 BITFIELD(39, 2) /* index 1229 */, 2020 BITFIELD(39, 2) /* index 1229 */,
1923 TILE_OPC_ILL, CHILD(1234), TILE_OPC_ILL, TILE_OPC_ILL, 2021 TILEPRO_OPC_ILL, CHILD(1234), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
1924 BITFIELD(41, 2) /* index 1234 */, 2022 BITFIELD(41, 2) /* index 1234 */,
1925 TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_RAISE, TILE_OPC_ILL, 2023 TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_RAISE, TILEPRO_OPC_ILL,
1926 BITFIELD(53, 1) /* index 1239 */, 2024 BITFIELD(53, 1) /* index 1239 */,
1927 TILE_OPC_ILL, TILE_OPC_NONE, 2025 TILEPRO_OPC_ILL, TILEPRO_OPC_NONE,
1928 BITFIELD(43, 3) /* index 1242 */, 2026 BITFIELD(43, 3) /* index 1242 */,
1929 CHILD(1251), CHILD(1254), CHILD(1257), CHILD(1275), CHILD(1278), 2027 CHILD(1251), CHILD(1254), CHILD(1257), CHILD(1275), CHILD(1278),
1930 CHILD(1281), CHILD(1284), CHILD(1287), 2028 CHILD(1281), CHILD(1284), CHILD(1287),
1931 BITFIELD(53, 1) /* index 1251 */, 2029 BITFIELD(53, 1) /* index 1251 */,
1932 TILE_OPC_INV, TILE_OPC_NONE, 2030 TILEPRO_OPC_INV, TILEPRO_OPC_NONE,
1933 BITFIELD(53, 1) /* index 1254 */, 2031 BITFIELD(53, 1) /* index 1254 */,
1934 TILE_OPC_IRET, TILE_OPC_NONE, 2032 TILEPRO_OPC_IRET, TILEPRO_OPC_NONE,
1935 BITFIELD(53, 1) /* index 1257 */, 2033 BITFIELD(53, 1) /* index 1257 */,
1936 CHILD(1260), TILE_OPC_NONE, 2034 CHILD(1260), TILEPRO_OPC_NONE,
1937 BITFIELD(31, 2) /* index 1260 */, 2035 BITFIELD(31, 2) /* index 1260 */,
1938 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1265), 2036 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(1265),
1939 BITFIELD(33, 2) /* index 1265 */, 2037 BITFIELD(33, 2) /* index 1265 */,
1940 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1270), 2038 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(1270),
1941 BITFIELD(35, 2) /* index 1270 */, 2039 BITFIELD(35, 2) /* index 1270 */,
1942 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH, 2040 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_PREFETCH,
1943 BITFIELD(53, 1) /* index 1275 */, 2041 BITFIELD(53, 1) /* index 1275 */,
1944 TILE_OPC_LB_U, TILE_OPC_NONE, 2042 TILEPRO_OPC_LB_U, TILEPRO_OPC_NONE,
1945 BITFIELD(53, 1) /* index 1278 */, 2043 BITFIELD(53, 1) /* index 1278 */,
1946 TILE_OPC_LH, TILE_OPC_NONE, 2044 TILEPRO_OPC_LH, TILEPRO_OPC_NONE,
1947 BITFIELD(53, 1) /* index 1281 */, 2045 BITFIELD(53, 1) /* index 1281 */,
1948 TILE_OPC_LH_U, TILE_OPC_NONE, 2046 TILEPRO_OPC_LH_U, TILEPRO_OPC_NONE,
1949 BITFIELD(53, 1) /* index 1284 */, 2047 BITFIELD(53, 1) /* index 1284 */,
1950 TILE_OPC_LW, TILE_OPC_NONE, 2048 TILEPRO_OPC_LW, TILEPRO_OPC_NONE,
1951 BITFIELD(53, 1) /* index 1287 */, 2049 BITFIELD(53, 1) /* index 1287 */,
1952 TILE_OPC_MF, TILE_OPC_NONE, 2050 TILEPRO_OPC_MF, TILEPRO_OPC_NONE,
1953 BITFIELD(43, 3) /* index 1290 */, 2051 BITFIELD(43, 3) /* index 1290 */,
1954 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311), 2052 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
1955 CHILD(1314), CHILD(1317), CHILD(1320), 2053 CHILD(1314), CHILD(1317), CHILD(1320),
1956 BITFIELD(53, 1) /* index 1299 */, 2054 BITFIELD(53, 1) /* index 1299 */,
1957 TILE_OPC_NAP, TILE_OPC_NONE, 2055 TILEPRO_OPC_NAP, TILEPRO_OPC_NONE,
1958 BITFIELD(53, 1) /* index 1302 */, 2056 BITFIELD(53, 1) /* index 1302 */,
1959 TILE_OPC_NOP, TILE_OPC_NONE, 2057 TILEPRO_OPC_NOP, TILEPRO_OPC_NONE,
1960 BITFIELD(53, 1) /* index 1305 */, 2058 BITFIELD(53, 1) /* index 1305 */,
1961 TILE_OPC_SWINT0, TILE_OPC_NONE, 2059 TILEPRO_OPC_SWINT0, TILEPRO_OPC_NONE,
1962 BITFIELD(53, 1) /* index 1308 */, 2060 BITFIELD(53, 1) /* index 1308 */,
1963 TILE_OPC_SWINT1, TILE_OPC_NONE, 2061 TILEPRO_OPC_SWINT1, TILEPRO_OPC_NONE,
1964 BITFIELD(53, 1) /* index 1311 */, 2062 BITFIELD(53, 1) /* index 1311 */,
1965 TILE_OPC_SWINT2, TILE_OPC_NONE, 2063 TILEPRO_OPC_SWINT2, TILEPRO_OPC_NONE,
1966 BITFIELD(53, 1) /* index 1314 */, 2064 BITFIELD(53, 1) /* index 1314 */,
1967 TILE_OPC_SWINT3, TILE_OPC_NONE, 2065 TILEPRO_OPC_SWINT3, TILEPRO_OPC_NONE,
1968 BITFIELD(53, 1) /* index 1317 */, 2066 BITFIELD(53, 1) /* index 1317 */,
1969 TILE_OPC_TNS, TILE_OPC_NONE, 2067 TILEPRO_OPC_TNS, TILEPRO_OPC_NONE,
1970 BITFIELD(53, 1) /* index 1320 */, 2068 BITFIELD(53, 1) /* index 1320 */,
1971 TILE_OPC_WH64, TILE_OPC_NONE, 2069 TILEPRO_OPC_WH64, TILEPRO_OPC_NONE,
1972 BITFIELD(43, 2) /* index 1323 */, 2070 BITFIELD(43, 2) /* index 1323 */,
1973 CHILD(1328), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2071 CHILD(1328), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1974 BITFIELD(45, 1) /* index 1328 */, 2072 BITFIELD(45, 1) /* index 1328 */,
1975 CHILD(1331), TILE_OPC_NONE, 2073 CHILD(1331), TILEPRO_OPC_NONE,
1976 BITFIELD(53, 1) /* index 1331 */, 2074 BITFIELD(53, 1) /* index 1331 */,
1977 TILE_OPC_LW_NA, TILE_OPC_NONE, 2075 TILEPRO_OPC_LW_NA, TILEPRO_OPC_NONE,
1978 BITFIELD(46, 7) /* index 1334 */, 2076 BITFIELD(46, 7) /* index 1334 */,
1979 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1463), 2077 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1980 CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466), CHILD(1466), 2078 CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466),
1981 CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469), CHILD(1469), 2079 CHILD(1466), CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469),
1982 CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472), CHILD(1472), 2080 CHILD(1469), CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472),
1983 CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1478), 2081 CHILD(1472), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475),
1984 CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481), CHILD(1481), 2082 CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481),
1985 CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484), CHILD(1484), 2083 CHILD(1481), CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484),
1986 CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487), CHILD(1487), 2084 CHILD(1484), CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487),
1987 CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1151), 2085 CHILD(1487), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490),
1988 CHILD(1493), CHILD(1517), CHILD(1529), TILE_OPC_NONE, TILE_OPC_NONE, 2086 CHILD(1151), CHILD(1493), CHILD(1517), CHILD(1529), TILEPRO_OPC_NONE,
1989 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2087 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1990 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2088 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1991 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2089 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1992 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2090 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1993 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2091 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1994 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2092 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1995 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2093 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1996 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2094 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1997 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2095 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1998 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2096 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
1999 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2097 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2000 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2098 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2001 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2099 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2002 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2100 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2003 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2101 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2004 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2102 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2103 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2104 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2105 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2106 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2005 BITFIELD(53, 1) /* index 1463 */, 2107 BITFIELD(53, 1) /* index 1463 */,
2006 TILE_OPC_RLI_SN, TILE_OPC_NONE, 2108 TILEPRO_OPC_RLI_SN, TILEPRO_OPC_NONE,
2007 BITFIELD(53, 1) /* index 1466 */, 2109 BITFIELD(53, 1) /* index 1466 */,
2008 TILE_OPC_SHLIB_SN, TILE_OPC_NONE, 2110 TILEPRO_OPC_SHLIB_SN, TILEPRO_OPC_NONE,
2009 BITFIELD(53, 1) /* index 1469 */, 2111 BITFIELD(53, 1) /* index 1469 */,
2010 TILE_OPC_SHLIH_SN, TILE_OPC_NONE, 2112 TILEPRO_OPC_SHLIH_SN, TILEPRO_OPC_NONE,
2011 BITFIELD(53, 1) /* index 1472 */, 2113 BITFIELD(53, 1) /* index 1472 */,
2012 TILE_OPC_SHLI_SN, TILE_OPC_NONE, 2114 TILEPRO_OPC_SHLI_SN, TILEPRO_OPC_NONE,
2013 BITFIELD(53, 1) /* index 1475 */, 2115 BITFIELD(53, 1) /* index 1475 */,
2014 TILE_OPC_SHRIB_SN, TILE_OPC_NONE, 2116 TILEPRO_OPC_SHRIB_SN, TILEPRO_OPC_NONE,
2015 BITFIELD(53, 1) /* index 1478 */, 2117 BITFIELD(53, 1) /* index 1478 */,
2016 TILE_OPC_SHRIH_SN, TILE_OPC_NONE, 2118 TILEPRO_OPC_SHRIH_SN, TILEPRO_OPC_NONE,
2017 BITFIELD(53, 1) /* index 1481 */, 2119 BITFIELD(53, 1) /* index 1481 */,
2018 TILE_OPC_SHRI_SN, TILE_OPC_NONE, 2120 TILEPRO_OPC_SHRI_SN, TILEPRO_OPC_NONE,
2019 BITFIELD(53, 1) /* index 1484 */, 2121 BITFIELD(53, 1) /* index 1484 */,
2020 TILE_OPC_SRAIB_SN, TILE_OPC_NONE, 2122 TILEPRO_OPC_SRAIB_SN, TILEPRO_OPC_NONE,
2021 BITFIELD(53, 1) /* index 1487 */, 2123 BITFIELD(53, 1) /* index 1487 */,
2022 TILE_OPC_SRAIH_SN, TILE_OPC_NONE, 2124 TILEPRO_OPC_SRAIH_SN, TILEPRO_OPC_NONE,
2023 BITFIELD(53, 1) /* index 1490 */, 2125 BITFIELD(53, 1) /* index 1490 */,
2024 TILE_OPC_SRAI_SN, TILE_OPC_NONE, 2126 TILEPRO_OPC_SRAI_SN, TILEPRO_OPC_NONE,
2025 BITFIELD(43, 3) /* index 1493 */, 2127 BITFIELD(43, 3) /* index 1493 */,
2026 CHILD(1251), CHILD(1254), CHILD(1502), CHILD(1505), CHILD(1508), 2128 CHILD(1251), CHILD(1254), CHILD(1502), CHILD(1505), CHILD(1508),
2027 CHILD(1511), CHILD(1514), CHILD(1287), 2129 CHILD(1511), CHILD(1514), CHILD(1287),
2028 BITFIELD(53, 1) /* index 1502 */, 2130 BITFIELD(53, 1) /* index 1502 */,
2029 TILE_OPC_LB_SN, TILE_OPC_NONE, 2131 TILEPRO_OPC_LB_SN, TILEPRO_OPC_NONE,
2030 BITFIELD(53, 1) /* index 1505 */, 2132 BITFIELD(53, 1) /* index 1505 */,
2031 TILE_OPC_LB_U_SN, TILE_OPC_NONE, 2133 TILEPRO_OPC_LB_U_SN, TILEPRO_OPC_NONE,
2032 BITFIELD(53, 1) /* index 1508 */, 2134 BITFIELD(53, 1) /* index 1508 */,
2033 TILE_OPC_LH_SN, TILE_OPC_NONE, 2135 TILEPRO_OPC_LH_SN, TILEPRO_OPC_NONE,
2034 BITFIELD(53, 1) /* index 1511 */, 2136 BITFIELD(53, 1) /* index 1511 */,
2035 TILE_OPC_LH_U_SN, TILE_OPC_NONE, 2137 TILEPRO_OPC_LH_U_SN, TILEPRO_OPC_NONE,
2036 BITFIELD(53, 1) /* index 1514 */, 2138 BITFIELD(53, 1) /* index 1514 */,
2037 TILE_OPC_LW_SN, TILE_OPC_NONE, 2139 TILEPRO_OPC_LW_SN, TILEPRO_OPC_NONE,
2038 BITFIELD(43, 3) /* index 1517 */, 2140 BITFIELD(43, 3) /* index 1517 */,
2039 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311), 2141 CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
2040 CHILD(1314), CHILD(1526), CHILD(1320), 2142 CHILD(1314), CHILD(1526), CHILD(1320),
2041 BITFIELD(53, 1) /* index 1526 */, 2143 BITFIELD(53, 1) /* index 1526 */,
2042 TILE_OPC_TNS_SN, TILE_OPC_NONE, 2144 TILEPRO_OPC_TNS_SN, TILEPRO_OPC_NONE,
2043 BITFIELD(43, 2) /* index 1529 */, 2145 BITFIELD(43, 2) /* index 1529 */,
2044 CHILD(1534), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2146 CHILD(1534), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2045 BITFIELD(45, 1) /* index 1534 */, 2147 BITFIELD(45, 1) /* index 1534 */,
2046 CHILD(1537), TILE_OPC_NONE, 2148 CHILD(1537), TILEPRO_OPC_NONE,
2047 BITFIELD(53, 1) /* index 1537 */, 2149 BITFIELD(53, 1) /* index 1537 */,
2048 TILE_OPC_LW_NA_SN, TILE_OPC_NONE, 2150 TILEPRO_OPC_LW_NA_SN, TILEPRO_OPC_NONE,
2049}; 2151};
2050 2152
2051static const unsigned short decode_Y0_fsm[168] = 2153static const unsigned short decode_Y0_fsm[168] =
2052{ 2154{
2053 BITFIELD(27, 4) /* index 0 */, 2155 BITFIELD(27, 4) /* index 0 */,
2054 TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52), 2156 TILEPRO_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
2055 CHILD(57), CHILD(62), CHILD(67), TILE_OPC_ADDI, CHILD(72), CHILD(102), 2157 CHILD(57), CHILD(62), CHILD(67), TILEPRO_OPC_ADDI, CHILD(72), CHILD(102),
2056 TILE_OPC_SEQI, CHILD(117), TILE_OPC_SLTI, TILE_OPC_SLTI_U, 2158 TILEPRO_OPC_SEQI, CHILD(117), TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U,
2057 BITFIELD(18, 2) /* index 17 */, 2159 BITFIELD(18, 2) /* index 17 */,
2058 TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB, 2160 TILEPRO_OPC_ADD, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_SUB,
2059 BITFIELD(18, 2) /* index 22 */, 2161 BITFIELD(18, 2) /* index 22 */,
2060 TILE_OPC_MNZ, TILE_OPC_MVNZ, TILE_OPC_MVZ, TILE_OPC_MZ, 2162 TILEPRO_OPC_MNZ, TILEPRO_OPC_MVNZ, TILEPRO_OPC_MVZ, TILEPRO_OPC_MZ,
2061 BITFIELD(18, 2) /* index 27 */, 2163 BITFIELD(18, 2) /* index 27 */,
2062 TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR, 2164 TILEPRO_OPC_AND, TILEPRO_OPC_NOR, CHILD(32), TILEPRO_OPC_XOR,
2063 BITFIELD(12, 2) /* index 32 */, 2165 BITFIELD(12, 2) /* index 32 */,
2064 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37), 2166 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(37),
2065 BITFIELD(14, 2) /* index 37 */, 2167 BITFIELD(14, 2) /* index 37 */,
2066 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42), 2168 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(42),
2067 BITFIELD(16, 2) /* index 42 */, 2169 BITFIELD(16, 2) /* index 42 */,
2068 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE, 2170 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
2069 BITFIELD(18, 2) /* index 47 */, 2171 BITFIELD(18, 2) /* index 47 */,
2070 TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA, 2172 TILEPRO_OPC_RL, TILEPRO_OPC_SHL, TILEPRO_OPC_SHR, TILEPRO_OPC_SRA,
2071 BITFIELD(18, 2) /* index 52 */, 2173 BITFIELD(18, 2) /* index 52 */,
2072 TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U, 2174 TILEPRO_OPC_SLTE, TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLT, TILEPRO_OPC_SLT_U,
2073 BITFIELD(18, 2) /* index 57 */, 2175 BITFIELD(18, 2) /* index 57 */,
2074 TILE_OPC_MULHLSA_UU, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE, 2176 TILEPRO_OPC_MULHLSA_UU, TILEPRO_OPC_S3A, TILEPRO_OPC_SEQ, TILEPRO_OPC_SNE,
2075 BITFIELD(18, 2) /* index 62 */, 2177 BITFIELD(18, 2) /* index 62 */,
2076 TILE_OPC_MULHH_SS, TILE_OPC_MULHH_UU, TILE_OPC_MULLL_SS, TILE_OPC_MULLL_UU, 2178 TILEPRO_OPC_MULHH_SS, TILEPRO_OPC_MULHH_UU, TILEPRO_OPC_MULLL_SS,
2179 TILEPRO_OPC_MULLL_UU,
2077 BITFIELD(18, 2) /* index 67 */, 2180 BITFIELD(18, 2) /* index 67 */,
2078 TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_UU, TILE_OPC_MULLLA_SS, 2181 TILEPRO_OPC_MULHHA_SS, TILEPRO_OPC_MULHHA_UU, TILEPRO_OPC_MULLLA_SS,
2079 TILE_OPC_MULLLA_UU, 2182 TILEPRO_OPC_MULLLA_UU,
2080 BITFIELD(0, 2) /* index 72 */, 2183 BITFIELD(0, 2) /* index 72 */,
2081 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77), 2184 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(77),
2082 BITFIELD(2, 2) /* index 77 */, 2185 BITFIELD(2, 2) /* index 77 */,
2083 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82), 2186 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(82),
2084 BITFIELD(4, 2) /* index 82 */, 2187 BITFIELD(4, 2) /* index 82 */,
2085 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87), 2188 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(87),
2086 BITFIELD(6, 2) /* index 87 */, 2189 BITFIELD(6, 2) /* index 87 */,
2087 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(92), 2190 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(92),
2088 BITFIELD(8, 2) /* index 92 */, 2191 BITFIELD(8, 2) /* index 92 */,
2089 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(97), 2192 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(97),
2090 BITFIELD(10, 2) /* index 97 */, 2193 BITFIELD(10, 2) /* index 97 */,
2091 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO, 2194 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
2092 BITFIELD(6, 2) /* index 102 */, 2195 BITFIELD(6, 2) /* index 102 */,
2093 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(107), 2196 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(107),
2094 BITFIELD(8, 2) /* index 107 */, 2197 BITFIELD(8, 2) /* index 107 */,
2095 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(112), 2198 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(112),
2096 BITFIELD(10, 2) /* index 112 */, 2199 BITFIELD(10, 2) /* index 112 */,
2097 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI, 2200 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
2098 BITFIELD(15, 5) /* index 117 */, 2201 BITFIELD(15, 5) /* index 117 */,
2099 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_RLI, 2202 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2100 TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHLI, 2203 TILEPRO_OPC_RLI, TILEPRO_OPC_RLI, TILEPRO_OPC_RLI, TILEPRO_OPC_RLI,
2101 TILE_OPC_SHLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SHRI, TILE_OPC_SHRI, 2204 TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI,
2102 TILE_OPC_SHRI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI, 2205 TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI,
2103 CHILD(150), CHILD(159), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2206 TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI,
2104 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2207 CHILD(150), CHILD(159), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2105 TILE_OPC_NONE, TILE_OPC_NONE, 2208 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2209 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2106 BITFIELD(12, 3) /* index 150 */, 2210 BITFIELD(12, 3) /* index 150 */,
2107 TILE_OPC_NONE, TILE_OPC_BITX, TILE_OPC_BYTEX, TILE_OPC_CLZ, TILE_OPC_CTZ, 2211 TILEPRO_OPC_NONE, TILEPRO_OPC_BITX, TILEPRO_OPC_BYTEX, TILEPRO_OPC_CLZ,
2108 TILE_OPC_FNOP, TILE_OPC_NOP, TILE_OPC_PCNT, 2212 TILEPRO_OPC_CTZ, TILEPRO_OPC_FNOP, TILEPRO_OPC_NOP, TILEPRO_OPC_PCNT,
2109 BITFIELD(12, 3) /* index 159 */, 2213 BITFIELD(12, 3) /* index 159 */,
2110 TILE_OPC_TBLIDXB0, TILE_OPC_TBLIDXB1, TILE_OPC_TBLIDXB2, TILE_OPC_TBLIDXB3, 2214 TILEPRO_OPC_TBLIDXB0, TILEPRO_OPC_TBLIDXB1, TILEPRO_OPC_TBLIDXB2,
2111 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2215 TILEPRO_OPC_TBLIDXB3, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2216 TILEPRO_OPC_NONE,
2112}; 2217};
2113 2218
2114static const unsigned short decode_Y1_fsm[140] = 2219static const unsigned short decode_Y1_fsm[140] =
2115{ 2220{
2116 BITFIELD(59, 4) /* index 0 */, 2221 BITFIELD(59, 4) /* index 0 */,
2117 TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52), 2222 TILEPRO_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
2118 CHILD(57), TILE_OPC_ADDI, CHILD(62), CHILD(92), TILE_OPC_SEQI, CHILD(107), 2223 CHILD(57), TILEPRO_OPC_ADDI, CHILD(62), CHILD(92), TILEPRO_OPC_SEQI,
2119 TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE, 2224 CHILD(107), TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_NONE,
2225 TILEPRO_OPC_NONE,
2120 BITFIELD(49, 2) /* index 17 */, 2226 BITFIELD(49, 2) /* index 17 */,
2121 TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB, 2227 TILEPRO_OPC_ADD, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_SUB,
2122 BITFIELD(49, 2) /* index 22 */, 2228 BITFIELD(49, 2) /* index 22 */,
2123 TILE_OPC_NONE, TILE_OPC_MNZ, TILE_OPC_MZ, TILE_OPC_NONE, 2229 TILEPRO_OPC_NONE, TILEPRO_OPC_MNZ, TILEPRO_OPC_MZ, TILEPRO_OPC_NONE,
2124 BITFIELD(49, 2) /* index 27 */, 2230 BITFIELD(49, 2) /* index 27 */,
2125 TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR, 2231 TILEPRO_OPC_AND, TILEPRO_OPC_NOR, CHILD(32), TILEPRO_OPC_XOR,
2126 BITFIELD(43, 2) /* index 32 */, 2232 BITFIELD(43, 2) /* index 32 */,
2127 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37), 2233 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(37),
2128 BITFIELD(45, 2) /* index 37 */, 2234 BITFIELD(45, 2) /* index 37 */,
2129 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42), 2235 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(42),
2130 BITFIELD(47, 2) /* index 42 */, 2236 BITFIELD(47, 2) /* index 42 */,
2131 TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE, 2237 TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
2132 BITFIELD(49, 2) /* index 47 */, 2238 BITFIELD(49, 2) /* index 47 */,
2133 TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA, 2239 TILEPRO_OPC_RL, TILEPRO_OPC_SHL, TILEPRO_OPC_SHR, TILEPRO_OPC_SRA,
2134 BITFIELD(49, 2) /* index 52 */, 2240 BITFIELD(49, 2) /* index 52 */,
2135 TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U, 2241 TILEPRO_OPC_SLTE, TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLT, TILEPRO_OPC_SLT_U,
2136 BITFIELD(49, 2) /* index 57 */, 2242 BITFIELD(49, 2) /* index 57 */,
2137 TILE_OPC_NONE, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE, 2243 TILEPRO_OPC_NONE, TILEPRO_OPC_S3A, TILEPRO_OPC_SEQ, TILEPRO_OPC_SNE,
2138 BITFIELD(31, 2) /* index 62 */, 2244 BITFIELD(31, 2) /* index 62 */,
2139 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(67), 2245 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(67),
2140 BITFIELD(33, 2) /* index 67 */, 2246 BITFIELD(33, 2) /* index 67 */,
2141 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(72), 2247 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(72),
2142 BITFIELD(35, 2) /* index 72 */, 2248 BITFIELD(35, 2) /* index 72 */,
2143 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77), 2249 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(77),
2144 BITFIELD(37, 2) /* index 77 */, 2250 BITFIELD(37, 2) /* index 77 */,
2145 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82), 2251 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(82),
2146 BITFIELD(39, 2) /* index 82 */, 2252 BITFIELD(39, 2) /* index 82 */,
2147 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87), 2253 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(87),
2148 BITFIELD(41, 2) /* index 87 */, 2254 BITFIELD(41, 2) /* index 87 */,
2149 TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO, 2255 TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
2150 BITFIELD(37, 2) /* index 92 */, 2256 BITFIELD(37, 2) /* index 92 */,
2151 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(97), 2257 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(97),
2152 BITFIELD(39, 2) /* index 97 */, 2258 BITFIELD(39, 2) /* index 97 */,
2153 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(102), 2259 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(102),
2154 BITFIELD(41, 2) /* index 102 */, 2260 BITFIELD(41, 2) /* index 102 */,
2155 TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI, 2261 TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
2156 BITFIELD(48, 3) /* index 107 */, 2262 BITFIELD(48, 3) /* index 107 */,
2157 TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SRAI, 2263 TILEPRO_OPC_NONE, TILEPRO_OPC_RLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHRI,
2158 CHILD(116), TILE_OPC_NONE, TILE_OPC_NONE, 2264 TILEPRO_OPC_SRAI, CHILD(116), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2159 BITFIELD(43, 3) /* index 116 */, 2265 BITFIELD(43, 3) /* index 116 */,
2160 TILE_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILE_OPC_NONE, 2266 TILEPRO_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILEPRO_OPC_NONE,
2161 TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2267 TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2162 BITFIELD(46, 2) /* index 125 */, 2268 BITFIELD(46, 2) /* index 125 */,
2163 TILE_OPC_FNOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2269 TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2164 BITFIELD(46, 2) /* index 130 */, 2270 BITFIELD(46, 2) /* index 130 */,
2165 TILE_OPC_ILL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2271 TILEPRO_OPC_ILL, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2166 BITFIELD(46, 2) /* index 135 */, 2272 BITFIELD(46, 2) /* index 135 */,
2167 TILE_OPC_NOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, 2273 TILEPRO_OPC_NOP, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
2168}; 2274};
2169 2275
2170static const unsigned short decode_Y2_fsm[24] = 2276static const unsigned short decode_Y2_fsm[24] =
2171{ 2277{
2172 BITFIELD(56, 3) /* index 0 */, 2278 BITFIELD(56, 3) /* index 0 */,
2173 CHILD(9), TILE_OPC_LB_U, TILE_OPC_LH, TILE_OPC_LH_U, TILE_OPC_LW, 2279 CHILD(9), TILEPRO_OPC_LB_U, TILEPRO_OPC_LH, TILEPRO_OPC_LH_U,
2174 TILE_OPC_SB, TILE_OPC_SH, TILE_OPC_SW, 2280 TILEPRO_OPC_LW, TILEPRO_OPC_SB, TILEPRO_OPC_SH, TILEPRO_OPC_SW,
2175 BITFIELD(20, 2) /* index 9 */, 2281 BITFIELD(20, 2) /* index 9 */,
2176 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(14), 2282 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(14),
2177 BITFIELD(22, 2) /* index 14 */, 2283 BITFIELD(22, 2) /* index 14 */,
2178 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(19), 2284 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(19),
2179 BITFIELD(24, 2) /* index 19 */, 2285 BITFIELD(24, 2) /* index 19 */,
2180 TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH, 2286 TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_PREFETCH,
2181}; 2287};
2182 2288
2183#undef BITFIELD 2289#undef BITFIELD
2184#undef CHILD 2290#undef CHILD
2185const unsigned short * const 2291const unsigned short * const
2186tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] = 2292tilepro_bundle_decoder_fsms[TILEPRO_NUM_PIPELINE_ENCODINGS] =
2187{ 2293{
2188 decode_X0_fsm, 2294 decode_X0_fsm,
2189 decode_X1_fsm, 2295 decode_X1_fsm,
@@ -2191,220 +2297,220 @@ tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] =
2191 decode_Y1_fsm, 2297 decode_Y1_fsm,
2192 decode_Y2_fsm 2298 decode_Y2_fsm
2193}; 2299};
2194const struct tile_operand tile_operands[43] = 2300const struct tilepro_operand tilepro_operands[43] =
2195{ 2301{
2196 { 2302 {
2197 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X0), 2303 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_X0),
2198 8, 1, 0, 0, 0, 0, 2304 8, 1, 0, 0, 0, 0,
2199 create_Imm8_X0, get_Imm8_X0 2305 create_Imm8_X0, get_Imm8_X0
2200 }, 2306 },
2201 { 2307 {
2202 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X1), 2308 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_X1),
2203 8, 1, 0, 0, 0, 0, 2309 8, 1, 0, 0, 0, 0,
2204 create_Imm8_X1, get_Imm8_X1 2310 create_Imm8_X1, get_Imm8_X1
2205 }, 2311 },
2206 { 2312 {
2207 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y0), 2313 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_Y0),
2208 8, 1, 0, 0, 0, 0, 2314 8, 1, 0, 0, 0, 0,
2209 create_Imm8_Y0, get_Imm8_Y0 2315 create_Imm8_Y0, get_Imm8_Y0
2210 }, 2316 },
2211 { 2317 {
2212 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y1), 2318 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_Y1),
2213 8, 1, 0, 0, 0, 0, 2319 8, 1, 0, 0, 0, 0,
2214 create_Imm8_Y1, get_Imm8_Y1 2320 create_Imm8_Y1, get_Imm8_Y1
2215 }, 2321 },
2216 { 2322 {
2217 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X0), 2323 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM16_X0),
2218 16, 1, 0, 0, 0, 0, 2324 16, 1, 0, 0, 0, 0,
2219 create_Imm16_X0, get_Imm16_X0 2325 create_Imm16_X0, get_Imm16_X0
2220 }, 2326 },
2221 { 2327 {
2222 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X1), 2328 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM16_X1),
2223 16, 1, 0, 0, 0, 0, 2329 16, 1, 0, 0, 0, 0,
2224 create_Imm16_X1, get_Imm16_X1 2330 create_Imm16_X1, get_Imm16_X1
2225 }, 2331 },
2226 { 2332 {
2227 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_JOFFLONG_X1), 2333 TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(TILEPRO_JOFFLONG_X1),
2228 29, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, 2334 29, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2229 create_JOffLong_X1, get_JOffLong_X1 2335 create_JOffLong_X1, get_JOffLong_X1
2230 }, 2336 },
2231 { 2337 {
2232 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2338 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2233 6, 0, 0, 1, 0, 0, 2339 6, 0, 0, 1, 0, 0,
2234 create_Dest_X0, get_Dest_X0 2340 create_Dest_X0, get_Dest_X0
2235 }, 2341 },
2236 { 2342 {
2237 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2343 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2238 6, 0, 1, 0, 0, 0, 2344 6, 0, 1, 0, 0, 0,
2239 create_SrcA_X0, get_SrcA_X0 2345 create_SrcA_X0, get_SrcA_X0
2240 }, 2346 },
2241 { 2347 {
2242 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2348 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2243 6, 0, 0, 1, 0, 0, 2349 6, 0, 0, 1, 0, 0,
2244 create_Dest_X1, get_Dest_X1 2350 create_Dest_X1, get_Dest_X1
2245 }, 2351 },
2246 { 2352 {
2247 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2353 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2248 6, 0, 1, 0, 0, 0, 2354 6, 0, 1, 0, 0, 0,
2249 create_SrcA_X1, get_SrcA_X1 2355 create_SrcA_X1, get_SrcA_X1
2250 }, 2356 },
2251 { 2357 {
2252 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2358 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2253 6, 0, 0, 1, 0, 0, 2359 6, 0, 0, 1, 0, 0,
2254 create_Dest_Y0, get_Dest_Y0 2360 create_Dest_Y0, get_Dest_Y0
2255 }, 2361 },
2256 { 2362 {
2257 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2363 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2258 6, 0, 1, 0, 0, 0, 2364 6, 0, 1, 0, 0, 0,
2259 create_SrcA_Y0, get_SrcA_Y0 2365 create_SrcA_Y0, get_SrcA_Y0
2260 }, 2366 },
2261 { 2367 {
2262 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2368 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2263 6, 0, 0, 1, 0, 0, 2369 6, 0, 0, 1, 0, 0,
2264 create_Dest_Y1, get_Dest_Y1 2370 create_Dest_Y1, get_Dest_Y1
2265 }, 2371 },
2266 { 2372 {
2267 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2373 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2268 6, 0, 1, 0, 0, 0, 2374 6, 0, 1, 0, 0, 0,
2269 create_SrcA_Y1, get_SrcA_Y1 2375 create_SrcA_Y1, get_SrcA_Y1
2270 }, 2376 },
2271 { 2377 {
2272 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2378 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2273 6, 0, 1, 0, 0, 0, 2379 6, 0, 1, 0, 0, 0,
2274 create_SrcA_Y2, get_SrcA_Y2 2380 create_SrcA_Y2, get_SrcA_Y2
2275 }, 2381 },
2276 { 2382 {
2277 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2383 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2278 6, 0, 1, 0, 0, 0, 2384 6, 0, 1, 0, 0, 0,
2279 create_SrcB_X0, get_SrcB_X0 2385 create_SrcB_X0, get_SrcB_X0
2280 }, 2386 },
2281 { 2387 {
2282 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2388 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2283 6, 0, 1, 0, 0, 0, 2389 6, 0, 1, 0, 0, 0,
2284 create_SrcB_X1, get_SrcB_X1 2390 create_SrcB_X1, get_SrcB_X1
2285 }, 2391 },
2286 { 2392 {
2287 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2393 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2288 6, 0, 1, 0, 0, 0, 2394 6, 0, 1, 0, 0, 0,
2289 create_SrcB_Y0, get_SrcB_Y0 2395 create_SrcB_Y0, get_SrcB_Y0
2290 }, 2396 },
2291 { 2397 {
2292 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2398 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2293 6, 0, 1, 0, 0, 0, 2399 6, 0, 1, 0, 0, 0,
2294 create_SrcB_Y1, get_SrcB_Y1 2400 create_SrcB_Y1, get_SrcB_Y1
2295 }, 2401 },
2296 { 2402 {
2297 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_BROFF_X1), 2403 TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(TILEPRO_BROFF_X1),
2298 17, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, 2404 17, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2299 create_BrOff_X1, get_BrOff_X1 2405 create_BrOff_X1, get_BrOff_X1
2300 }, 2406 },
2301 { 2407 {
2302 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2408 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2303 6, 0, 1, 1, 0, 0, 2409 6, 0, 1, 1, 0, 0,
2304 create_Dest_X0, get_Dest_X0 2410 create_Dest_X0, get_Dest_X0
2305 }, 2411 },
2306 { 2412 {
2307 TILE_OP_TYPE_ADDRESS, BFD_RELOC(NONE), 2413 TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
2308 28, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, 2414 28, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
2309 create_JOff_X1, get_JOff_X1 2415 create_JOff_X1, get_JOff_X1
2310 }, 2416 },
2311 { 2417 {
2312 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2418 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2313 6, 0, 0, 1, 0, 0, 2419 6, 0, 0, 1, 0, 0,
2314 create_SrcBDest_Y2, get_SrcBDest_Y2 2420 create_SrcBDest_Y2, get_SrcBDest_Y2
2315 }, 2421 },
2316 { 2422 {
2317 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2423 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2318 6, 0, 1, 1, 0, 0, 2424 6, 0, 1, 1, 0, 0,
2319 create_SrcA_X1, get_SrcA_X1 2425 create_SrcA_X1, get_SrcA_X1
2320 }, 2426 },
2321 { 2427 {
2322 TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MF_IMM15_X1), 2428 TILEPRO_OP_TYPE_SPR, BFD_RELOC(TILEPRO_MF_IMM15_X1),
2323 15, 0, 0, 0, 0, 0, 2429 15, 0, 0, 0, 0, 0,
2324 create_MF_Imm15_X1, get_MF_Imm15_X1 2430 create_MF_Imm15_X1, get_MF_Imm15_X1
2325 }, 2431 },
2326 { 2432 {
2327 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X0), 2433 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMSTART_X0),
2328 5, 0, 0, 0, 0, 0, 2434 5, 0, 0, 0, 0, 0,
2329 create_MMStart_X0, get_MMStart_X0 2435 create_MMStart_X0, get_MMStart_X0
2330 }, 2436 },
2331 { 2437 {
2332 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X0), 2438 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMEND_X0),
2333 5, 0, 0, 0, 0, 0, 2439 5, 0, 0, 0, 0, 0,
2334 create_MMEnd_X0, get_MMEnd_X0 2440 create_MMEnd_X0, get_MMEnd_X0
2335 }, 2441 },
2336 { 2442 {
2337 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X1), 2443 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMSTART_X1),
2338 5, 0, 0, 0, 0, 0, 2444 5, 0, 0, 0, 0, 0,
2339 create_MMStart_X1, get_MMStart_X1 2445 create_MMStart_X1, get_MMStart_X1
2340 }, 2446 },
2341 { 2447 {
2342 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X1), 2448 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMEND_X1),
2343 5, 0, 0, 0, 0, 0, 2449 5, 0, 0, 0, 0, 0,
2344 create_MMEnd_X1, get_MMEnd_X1 2450 create_MMEnd_X1, get_MMEnd_X1
2345 }, 2451 },
2346 { 2452 {
2347 TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MT_IMM15_X1), 2453 TILEPRO_OP_TYPE_SPR, BFD_RELOC(TILEPRO_MT_IMM15_X1),
2348 15, 0, 0, 0, 0, 0, 2454 15, 0, 0, 0, 0, 0,
2349 create_MT_Imm15_X1, get_MT_Imm15_X1 2455 create_MT_Imm15_X1, get_MT_Imm15_X1
2350 }, 2456 },
2351 { 2457 {
2352 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2458 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2353 6, 0, 1, 1, 0, 0, 2459 6, 0, 1, 1, 0, 0,
2354 create_Dest_Y0, get_Dest_Y0 2460 create_Dest_Y0, get_Dest_Y0
2355 }, 2461 },
2356 { 2462 {
2357 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X0), 2463 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_X0),
2358 5, 0, 0, 0, 0, 0, 2464 5, 0, 0, 0, 0, 0,
2359 create_ShAmt_X0, get_ShAmt_X0 2465 create_ShAmt_X0, get_ShAmt_X0
2360 }, 2466 },
2361 { 2467 {
2362 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X1), 2468 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_X1),
2363 5, 0, 0, 0, 0, 0, 2469 5, 0, 0, 0, 0, 0,
2364 create_ShAmt_X1, get_ShAmt_X1 2470 create_ShAmt_X1, get_ShAmt_X1
2365 }, 2471 },
2366 { 2472 {
2367 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y0), 2473 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_Y0),
2368 5, 0, 0, 0, 0, 0, 2474 5, 0, 0, 0, 0, 0,
2369 create_ShAmt_Y0, get_ShAmt_Y0 2475 create_ShAmt_Y0, get_ShAmt_Y0
2370 }, 2476 },
2371 { 2477 {
2372 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y1), 2478 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_Y1),
2373 5, 0, 0, 0, 0, 0, 2479 5, 0, 0, 0, 0, 0,
2374 create_ShAmt_Y1, get_ShAmt_Y1 2480 create_ShAmt_Y1, get_ShAmt_Y1
2375 }, 2481 },
2376 { 2482 {
2377 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2483 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2378 6, 0, 1, 0, 0, 0, 2484 6, 0, 1, 0, 0, 0,
2379 create_SrcBDest_Y2, get_SrcBDest_Y2 2485 create_SrcBDest_Y2, get_SrcBDest_Y2
2380 }, 2486 },
2381 { 2487 {
2382 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE), 2488 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_DEST_IMM8_X1),
2383 8, 1, 0, 0, 0, 0, 2489 8, 1, 0, 0, 0, 0,
2384 create_Dest_Imm8_X1, get_Dest_Imm8_X1 2490 create_Dest_Imm8_X1, get_Dest_Imm8_X1
2385 }, 2491 },
2386 { 2492 {
2387 TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_SN_BROFF), 2493 TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
2388 10, 1, 0, 0, 1, TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES, 2494 10, 1, 0, 0, 1, TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES,
2389 create_BrOff_SN, get_BrOff_SN 2495 create_BrOff_SN, get_BrOff_SN
2390 }, 2496 },
2391 { 2497 {
2392 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_UIMM8), 2498 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
2393 8, 0, 0, 0, 0, 0, 2499 8, 0, 0, 0, 0, 0,
2394 create_Imm8_SN, get_Imm8_SN 2500 create_Imm8_SN, get_Imm8_SN
2395 }, 2501 },
2396 { 2502 {
2397 TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_IMM8), 2503 TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
2398 8, 1, 0, 0, 0, 0, 2504 8, 1, 0, 0, 0, 0,
2399 create_Imm8_SN, get_Imm8_SN 2505 create_Imm8_SN, get_Imm8_SN
2400 }, 2506 },
2401 { 2507 {
2402 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2508 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2403 2, 0, 0, 1, 0, 0, 2509 2, 0, 0, 1, 0, 0,
2404 create_Dest_SN, get_Dest_SN 2510 create_Dest_SN, get_Dest_SN
2405 }, 2511 },
2406 { 2512 {
2407 TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE), 2513 TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
2408 2, 0, 1, 0, 0, 0, 2514 2, 0, 1, 0, 0, 0,
2409 create_Src_SN, get_Src_SN 2515 create_Src_SN, get_Src_SN
2410 } 2516 }
@@ -2416,10 +2522,10 @@ const struct tile_operand tile_operands[43] =
2416/* Given a set of bundle bits and a specific pipe, returns which 2522/* Given a set of bundle bits and a specific pipe, returns which
2417 * instruction the bundle contains in that pipe. 2523 * instruction the bundle contains in that pipe.
2418 */ 2524 */
2419const struct tile_opcode * 2525const struct tilepro_opcode *
2420find_opcode(tile_bundle_bits bits, tile_pipeline pipe) 2526find_opcode(tilepro_bundle_bits bits, tilepro_pipeline pipe)
2421{ 2527{
2422 const unsigned short *table = tile_bundle_decoder_fsms[pipe]; 2528 const unsigned short *table = tilepro_bundle_decoder_fsms[pipe];
2423 int index = 0; 2529 int index = 0;
2424 2530
2425 while (1) 2531 while (1)
@@ -2429,51 +2535,51 @@ find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
2429 ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6); 2535 ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
2430 2536
2431 unsigned short next = table[index + 1 + bitfield]; 2537 unsigned short next = table[index + 1 + bitfield];
2432 if (next <= TILE_OPC_NONE) 2538 if (next <= TILEPRO_OPC_NONE)
2433 return &tile_opcodes[next]; 2539 return &tilepro_opcodes[next];
2434 2540
2435 index = next - TILE_OPC_NONE; 2541 index = next - TILEPRO_OPC_NONE;
2436 } 2542 }
2437} 2543}
2438 2544
2439 2545
2440int 2546int
2441parse_insn_tile(tile_bundle_bits bits, 2547parse_insn_tilepro(tilepro_bundle_bits bits,
2442 unsigned int pc, 2548 unsigned int pc,
2443 struct tile_decoded_instruction 2549 struct tilepro_decoded_instruction
2444 decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]) 2550 decoded[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE])
2445{ 2551{
2446 int num_instructions = 0; 2552 int num_instructions = 0;
2447 int pipe; 2553 int pipe;
2448 2554
2449 int min_pipe, max_pipe; 2555 int min_pipe, max_pipe;
2450 if ((bits & TILE_BUNDLE_Y_ENCODING_MASK) == 0) 2556 if ((bits & TILEPRO_BUNDLE_Y_ENCODING_MASK) == 0)
2451 { 2557 {
2452 min_pipe = TILE_PIPELINE_X0; 2558 min_pipe = TILEPRO_PIPELINE_X0;
2453 max_pipe = TILE_PIPELINE_X1; 2559 max_pipe = TILEPRO_PIPELINE_X1;
2454 } 2560 }
2455 else 2561 else
2456 { 2562 {
2457 min_pipe = TILE_PIPELINE_Y0; 2563 min_pipe = TILEPRO_PIPELINE_Y0;
2458 max_pipe = TILE_PIPELINE_Y2; 2564 max_pipe = TILEPRO_PIPELINE_Y2;
2459 } 2565 }
2460 2566
2461 /* For each pipe, find an instruction that fits. */ 2567 /* For each pipe, find an instruction that fits. */
2462 for (pipe = min_pipe; pipe <= max_pipe; pipe++) 2568 for (pipe = min_pipe; pipe <= max_pipe; pipe++)
2463 { 2569 {
2464 const struct tile_opcode *opc; 2570 const struct tilepro_opcode *opc;
2465 struct tile_decoded_instruction *d; 2571 struct tilepro_decoded_instruction *d;
2466 int i; 2572 int i;
2467 2573
2468 d = &decoded[num_instructions++]; 2574 d = &decoded[num_instructions++];
2469 opc = find_opcode (bits, (tile_pipeline)pipe); 2575 opc = find_opcode (bits, (tilepro_pipeline)pipe);
2470 d->opcode = opc; 2576 d->opcode = opc;
2471 2577
2472 /* Decode each operand, sign extending, etc. as appropriate. */ 2578 /* Decode each operand, sign extending, etc. as appropriate. */
2473 for (i = 0; i < opc->num_operands; i++) 2579 for (i = 0; i < opc->num_operands; i++)
2474 { 2580 {
2475 const struct tile_operand *op = 2581 const struct tilepro_operand *op =
2476 &tile_operands[opc->operands[pipe][i]]; 2582 &tilepro_operands[opc->operands[pipe][i]];
2477 int opval = op->extract (bits); 2583 int opval = op->extract (bits);
2478 if (op->is_signed) 2584 if (op->is_signed)
2479 { 2585 {
@@ -2483,9 +2589,9 @@ parse_insn_tile(tile_bundle_bits bits,
2483 } 2589 }
2484 2590
2485 /* Adjust PC-relative scaled branch offsets. */ 2591 /* Adjust PC-relative scaled branch offsets. */
2486 if (op->type == TILE_OP_TYPE_ADDRESS) 2592 if (op->type == TILEPRO_OP_TYPE_ADDRESS)
2487 { 2593 {
2488 opval *= TILE_BUNDLE_SIZE_IN_BYTES; 2594 opval *= TILEPRO_BUNDLE_SIZE_IN_BYTES;
2489 opval += (int)pc; 2595 opval += (int)pc;
2490 } 2596 }
2491 2597
diff --git a/arch/tile/kernel/tile-desc_64.c b/arch/tile/kernel/tile-desc_64.c
index d57007bed77f..65b5f8aca706 100644
--- a/arch/tile/kernel/tile-desc_64.c
+++ b/arch/tile/kernel/tile-desc_64.c
@@ -1,3 +1,23 @@
1/* TILE-Gx opcode information.
2 *
3 * Copyright 2011 Tilera Corporation. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 *
15 *
16 *
17 *
18 *
19 */
20
1/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */ 21/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
2#define BFD_RELOC(x) -1 22#define BFD_RELOC(x) -1
3 23
@@ -6,10 +26,8 @@
6#define TREG_SN 56 26#define TREG_SN 56
7#define TREG_ZERO 63 27#define TREG_ZERO 63
8 28
9/* FIXME: Rename this. */
10#include <asm/opcode-tile_64.h>
11
12#include <linux/stddef.h> 29#include <linux/stddef.h>
30#include <asm/tile-desc.h>
13 31
14const struct tilegx_opcode tilegx_opcodes[334] = 32const struct tilegx_opcode tilegx_opcodes[334] =
15{ 33{
@@ -2040,12 +2058,12 @@ const struct tilegx_operand tilegx_operands[35] =
2040 create_BrOff_X1, get_BrOff_X1 2058 create_BrOff_X1, get_BrOff_X1
2041 }, 2059 },
2042 { 2060 {
2043 TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE), 2061 TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),
2044 6, 0, 0, 0, 0, 0, 2062 6, 0, 0, 0, 0, 0,
2045 create_BFStart_X0, get_BFStart_X0 2063 create_BFStart_X0, get_BFStart_X0
2046 }, 2064 },
2047 { 2065 {
2048 TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE), 2066 TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),
2049 6, 0, 0, 0, 0, 0, 2067 6, 0, 0, 0, 0, 0,
2050 create_BFEnd_X0, get_BFEnd_X0 2068 create_BFEnd_X0, get_BFEnd_X0
2051 }, 2069 },
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index f9803dfa7357..4f47b8a356df 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -19,13 +19,12 @@
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/uaccess.h> 20#include <linux/uaccess.h>
21#include <linux/ptrace.h> 21#include <linux/ptrace.h>
22#include <asm/opcode-tile.h>
23#include <asm/opcode_constants.h>
24#include <asm/stack.h> 22#include <asm/stack.h>
25#include <asm/traps.h> 23#include <asm/traps.h>
26 24
27#include <arch/interrupts.h> 25#include <arch/interrupts.h>
28#include <arch/spr_def.h> 26#include <arch/spr_def.h>
27#include <arch/opcode.h>
29 28
30void __init trap_init(void) 29void __init trap_init(void)
31{ 30{
@@ -135,7 +134,7 @@ static int special_ill(bundle_bits bundle, int *sigp, int *codep)
135 if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1) 134 if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
136 return 0; 135 return 0;
137#else 136#else
138 if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) 137 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK)
139 return 0; 138 return 0;
140 if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1) 139 if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
141 return 0; 140 return 0;
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
index 49284fae9d09..a87d2a859ba9 100644
--- a/arch/tile/lib/exports.c
+++ b/arch/tile/lib/exports.c
@@ -79,8 +79,6 @@ EXPORT_SYMBOL(__umoddi3);
79int64_t __moddi3(int64_t dividend, int64_t divisor); 79int64_t __moddi3(int64_t dividend, int64_t divisor);
80EXPORT_SYMBOL(__moddi3); 80EXPORT_SYMBOL(__moddi3);
81#ifndef __tilegx__ 81#ifndef __tilegx__
82uint64_t __ll_mul(uint64_t n0, uint64_t n1);
83EXPORT_SYMBOL(__ll_mul);
84int64_t __muldi3(int64_t, int64_t); 82int64_t __muldi3(int64_t, int64_t);
85EXPORT_SYMBOL(__muldi3); 83EXPORT_SYMBOL(__muldi3);
86uint64_t __lshrdi3(uint64_t, unsigned int); 84uint64_t __lshrdi3(uint64_t, unsigned int);
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index b596e54ddd71..8f630cec906e 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -768,25 +768,14 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg,
768 return disk_total; 768 return disk_total;
769} 769}
770 770
771static int blkio_check_dev_num(dev_t dev)
772{
773 int part = 0;
774 struct gendisk *disk;
775
776 disk = get_gendisk(dev, &part);
777 if (!disk || part)
778 return -ENODEV;
779
780 return 0;
781}
782
783static int blkio_policy_parse_and_set(char *buf, 771static int blkio_policy_parse_and_set(char *buf,
784 struct blkio_policy_node *newpn, enum blkio_policy_id plid, int fileid) 772 struct blkio_policy_node *newpn, enum blkio_policy_id plid, int fileid)
785{ 773{
774 struct gendisk *disk = NULL;
786 char *s[4], *p, *major_s = NULL, *minor_s = NULL; 775 char *s[4], *p, *major_s = NULL, *minor_s = NULL;
787 int ret;
788 unsigned long major, minor; 776 unsigned long major, minor;
789 int i = 0; 777 int i = 0, ret = -EINVAL;
778 int part;
790 dev_t dev; 779 dev_t dev;
791 u64 temp; 780 u64 temp;
792 781
@@ -804,37 +793,36 @@ static int blkio_policy_parse_and_set(char *buf,
804 } 793 }
805 794
806 if (i != 2) 795 if (i != 2)
807 return -EINVAL; 796 goto out;
808 797
809 p = strsep(&s[0], ":"); 798 p = strsep(&s[0], ":");
810 if (p != NULL) 799 if (p != NULL)
811 major_s = p; 800 major_s = p;
812 else 801 else
813 return -EINVAL; 802 goto out;
814 803
815 minor_s = s[0]; 804 minor_s = s[0];
816 if (!minor_s) 805 if (!minor_s)
817 return -EINVAL; 806 goto out;
818 807
819 ret = strict_strtoul(major_s, 10, &major); 808 if (strict_strtoul(major_s, 10, &major))
820 if (ret) 809 goto out;
821 return -EINVAL;
822 810
823 ret = strict_strtoul(minor_s, 10, &minor); 811 if (strict_strtoul(minor_s, 10, &minor))
824 if (ret) 812 goto out;
825 return -EINVAL;
826 813
827 dev = MKDEV(major, minor); 814 dev = MKDEV(major, minor);
828 815
829 ret = strict_strtoull(s[1], 10, &temp); 816 if (strict_strtoull(s[1], 10, &temp))
830 if (ret) 817 goto out;
831 return -EINVAL;
832 818
833 /* For rule removal, do not check for device presence. */ 819 /* For rule removal, do not check for device presence. */
834 if (temp) { 820 if (temp) {
835 ret = blkio_check_dev_num(dev); 821 disk = get_gendisk(dev, &part);
836 if (ret) 822 if (!disk || part) {
837 return ret; 823 ret = -ENODEV;
824 goto out;
825 }
838 } 826 }
839 827
840 newpn->dev = dev; 828 newpn->dev = dev;
@@ -843,7 +831,7 @@ static int blkio_policy_parse_and_set(char *buf,
843 case BLKIO_POLICY_PROP: 831 case BLKIO_POLICY_PROP:
844 if ((temp < BLKIO_WEIGHT_MIN && temp > 0) || 832 if ((temp < BLKIO_WEIGHT_MIN && temp > 0) ||
845 temp > BLKIO_WEIGHT_MAX) 833 temp > BLKIO_WEIGHT_MAX)
846 return -EINVAL; 834 goto out;
847 835
848 newpn->plid = plid; 836 newpn->plid = plid;
849 newpn->fileid = fileid; 837 newpn->fileid = fileid;
@@ -860,7 +848,7 @@ static int blkio_policy_parse_and_set(char *buf,
860 case BLKIO_THROTL_read_iops_device: 848 case BLKIO_THROTL_read_iops_device:
861 case BLKIO_THROTL_write_iops_device: 849 case BLKIO_THROTL_write_iops_device:
862 if (temp > THROTL_IOPS_MAX) 850 if (temp > THROTL_IOPS_MAX)
863 return -EINVAL; 851 goto out;
864 852
865 newpn->plid = plid; 853 newpn->plid = plid;
866 newpn->fileid = fileid; 854 newpn->fileid = fileid;
@@ -871,68 +859,96 @@ static int blkio_policy_parse_and_set(char *buf,
871 default: 859 default:
872 BUG(); 860 BUG();
873 } 861 }
874 862 ret = 0;
875 return 0; 863out:
864 put_disk(disk);
865 return ret;
876} 866}
877 867
878unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg, 868unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg,
879 dev_t dev) 869 dev_t dev)
880{ 870{
881 struct blkio_policy_node *pn; 871 struct blkio_policy_node *pn;
872 unsigned long flags;
873 unsigned int weight;
874
875 spin_lock_irqsave(&blkcg->lock, flags);
882 876
883 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP, 877 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP,
884 BLKIO_PROP_weight_device); 878 BLKIO_PROP_weight_device);
885 if (pn) 879 if (pn)
886 return pn->val.weight; 880 weight = pn->val.weight;
887 else 881 else
888 return blkcg->weight; 882 weight = blkcg->weight;
883
884 spin_unlock_irqrestore(&blkcg->lock, flags);
885
886 return weight;
889} 887}
890EXPORT_SYMBOL_GPL(blkcg_get_weight); 888EXPORT_SYMBOL_GPL(blkcg_get_weight);
891 889
892uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev) 890uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev)
893{ 891{
894 struct blkio_policy_node *pn; 892 struct blkio_policy_node *pn;
893 unsigned long flags;
894 uint64_t bps = -1;
895 895
896 spin_lock_irqsave(&blkcg->lock, flags);
896 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, 897 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
897 BLKIO_THROTL_read_bps_device); 898 BLKIO_THROTL_read_bps_device);
898 if (pn) 899 if (pn)
899 return pn->val.bps; 900 bps = pn->val.bps;
900 else 901 spin_unlock_irqrestore(&blkcg->lock, flags);
901 return -1; 902
903 return bps;
902} 904}
903 905
904uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev) 906uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev)
905{ 907{
906 struct blkio_policy_node *pn; 908 struct blkio_policy_node *pn;
909 unsigned long flags;
910 uint64_t bps = -1;
911
912 spin_lock_irqsave(&blkcg->lock, flags);
907 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, 913 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
908 BLKIO_THROTL_write_bps_device); 914 BLKIO_THROTL_write_bps_device);
909 if (pn) 915 if (pn)
910 return pn->val.bps; 916 bps = pn->val.bps;
911 else 917 spin_unlock_irqrestore(&blkcg->lock, flags);
912 return -1; 918
919 return bps;
913} 920}
914 921
915unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev) 922unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev)
916{ 923{
917 struct blkio_policy_node *pn; 924 struct blkio_policy_node *pn;
925 unsigned long flags;
926 unsigned int iops = -1;
918 927
928 spin_lock_irqsave(&blkcg->lock, flags);
919 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, 929 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
920 BLKIO_THROTL_read_iops_device); 930 BLKIO_THROTL_read_iops_device);
921 if (pn) 931 if (pn)
922 return pn->val.iops; 932 iops = pn->val.iops;
923 else 933 spin_unlock_irqrestore(&blkcg->lock, flags);
924 return -1; 934
935 return iops;
925} 936}
926 937
927unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev) 938unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev)
928{ 939{
929 struct blkio_policy_node *pn; 940 struct blkio_policy_node *pn;
941 unsigned long flags;
942 unsigned int iops = -1;
943
944 spin_lock_irqsave(&blkcg->lock, flags);
930 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, 945 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
931 BLKIO_THROTL_write_iops_device); 946 BLKIO_THROTL_write_iops_device);
932 if (pn) 947 if (pn)
933 return pn->val.iops; 948 iops = pn->val.iops;
934 else 949 spin_unlock_irqrestore(&blkcg->lock, flags);
935 return -1; 950
951 return iops;
936} 952}
937 953
938/* Checks whether user asked for deleting a policy rule */ 954/* Checks whether user asked for deleting a policy rule */
@@ -1085,6 +1101,7 @@ static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft,
1085 1101
1086 if (blkio_delete_rule_command(newpn)) { 1102 if (blkio_delete_rule_command(newpn)) {
1087 blkio_policy_delete_node(pn); 1103 blkio_policy_delete_node(pn);
1104 kfree(pn);
1088 spin_unlock_irq(&blkcg->lock); 1105 spin_unlock_irq(&blkcg->lock);
1089 goto update_io_group; 1106 goto update_io_group;
1090 } 1107 }
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
index a71d2904ffb9..6f3ace7e792f 100644
--- a/block/blk-cgroup.h
+++ b/block/blk-cgroup.h
@@ -188,7 +188,7 @@ struct blkio_policy_node {
188 union { 188 union {
189 unsigned int weight; 189 unsigned int weight;
190 /* 190 /*
191 * Rate read/write in terms of byptes per second 191 * Rate read/write in terms of bytes per second
192 * Whether this rate represents read or write is determined 192 * Whether this rate represents read or write is determined
193 * by file type "fileid". 193 * by file type "fileid".
194 */ 194 */
diff --git a/block/blk-core.c b/block/blk-core.c
index d34433ae7917..f43c8a5840ae 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -28,6 +28,7 @@
28#include <linux/task_io_accounting_ops.h> 28#include <linux/task_io_accounting_ops.h>
29#include <linux/fault-inject.h> 29#include <linux/fault-inject.h>
30#include <linux/list_sort.h> 30#include <linux/list_sort.h>
31#include <linux/delay.h>
31 32
32#define CREATE_TRACE_POINTS 33#define CREATE_TRACE_POINTS
33#include <trace/events/block.h> 34#include <trace/events/block.h>
@@ -38,8 +39,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
38EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); 39EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
39EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); 40EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
40 41
41static int __make_request(struct request_queue *q, struct bio *bio);
42
43/* 42/*
44 * For the allocated request tables 43 * For the allocated request tables
45 */ 44 */
@@ -347,30 +346,80 @@ void blk_put_queue(struct request_queue *q)
347} 346}
348EXPORT_SYMBOL(blk_put_queue); 347EXPORT_SYMBOL(blk_put_queue);
349 348
350/* 349/**
351 * Note: If a driver supplied the queue lock, it is disconnected 350 * blk_drain_queue - drain requests from request_queue
352 * by this function. The actual state of the lock doesn't matter 351 * @q: queue to drain
353 * here as the request_queue isn't accessible after this point 352 * @drain_all: whether to drain all requests or only the ones w/ ELVPRIV
354 * (QUEUE_FLAG_DEAD is set) and no other requests will be queued. 353 *
354 * Drain requests from @q. If @drain_all is set, all requests are drained.
355 * If not, only ELVPRIV requests are drained. The caller is responsible
356 * for ensuring that no new requests which need to be drained are queued.
357 */
358void blk_drain_queue(struct request_queue *q, bool drain_all)
359{
360 while (true) {
361 int nr_rqs;
362
363 spin_lock_irq(q->queue_lock);
364
365 elv_drain_elevator(q);
366 if (drain_all)
367 blk_throtl_drain(q);
368
369 __blk_run_queue(q);
370
371 if (drain_all)
372 nr_rqs = q->rq.count[0] + q->rq.count[1];
373 else
374 nr_rqs = q->rq.elvpriv;
375
376 spin_unlock_irq(q->queue_lock);
377
378 if (!nr_rqs)
379 break;
380 msleep(10);
381 }
382}
383
384/**
385 * blk_cleanup_queue - shutdown a request queue
386 * @q: request queue to shutdown
387 *
388 * Mark @q DEAD, drain all pending requests, destroy and put it. All
389 * future requests will be failed immediately with -ENODEV.
355 */ 390 */
356void blk_cleanup_queue(struct request_queue *q) 391void blk_cleanup_queue(struct request_queue *q)
357{ 392{
358 /* 393 spinlock_t *lock = q->queue_lock;
359 * We know we have process context here, so we can be a little
360 * cautious and ensure that pending block actions on this device
361 * are done before moving on. Going into this function, we should
362 * not have processes doing IO to this device.
363 */
364 blk_sync_queue(q);
365 394
366 del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer); 395 /* mark @q DEAD, no new request or merges will be allowed afterwards */
367 mutex_lock(&q->sysfs_lock); 396 mutex_lock(&q->sysfs_lock);
368 queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); 397 queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q);
369 mutex_unlock(&q->sysfs_lock); 398
399 spin_lock_irq(lock);
400 queue_flag_set(QUEUE_FLAG_NOMERGES, q);
401 queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
402 queue_flag_set(QUEUE_FLAG_DEAD, q);
370 403
371 if (q->queue_lock != &q->__queue_lock) 404 if (q->queue_lock != &q->__queue_lock)
372 q->queue_lock = &q->__queue_lock; 405 q->queue_lock = &q->__queue_lock;
373 406
407 spin_unlock_irq(lock);
408 mutex_unlock(&q->sysfs_lock);
409
410 /*
411 * Drain all requests queued before DEAD marking. The caller might
412 * be trying to tear down @q before its elevator is initialized, in
413 * which case we don't want to call into draining.
414 */
415 if (q->elevator)
416 blk_drain_queue(q, true);
417
418 /* @q won't process any more request, flush async actions */
419 del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer);
420 blk_sync_queue(q);
421
422 /* @q is and will stay empty, shutdown and put */
374 blk_put_queue(q); 423 blk_put_queue(q);
375} 424}
376EXPORT_SYMBOL(blk_cleanup_queue); 425EXPORT_SYMBOL(blk_cleanup_queue);
@@ -541,7 +590,7 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
541 /* 590 /*
542 * This also sets hw/phys segments, boundary and size 591 * This also sets hw/phys segments, boundary and size
543 */ 592 */
544 blk_queue_make_request(q, __make_request); 593 blk_queue_make_request(q, blk_queue_bio);
545 594
546 q->sg_reserved_size = INT_MAX; 595 q->sg_reserved_size = INT_MAX;
547 596
@@ -576,7 +625,7 @@ static inline void blk_free_request(struct request_queue *q, struct request *rq)
576} 625}
577 626
578static struct request * 627static struct request *
579blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask) 628blk_alloc_request(struct request_queue *q, unsigned int flags, gfp_t gfp_mask)
580{ 629{
581 struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); 630 struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
582 631
@@ -587,12 +636,10 @@ blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask)
587 636
588 rq->cmd_flags = flags | REQ_ALLOCED; 637 rq->cmd_flags = flags | REQ_ALLOCED;
589 638
590 if (priv) { 639 if ((flags & REQ_ELVPRIV) &&
591 if (unlikely(elv_set_request(q, rq, gfp_mask))) { 640 unlikely(elv_set_request(q, rq, gfp_mask))) {
592 mempool_free(rq, q->rq.rq_pool); 641 mempool_free(rq, q->rq.rq_pool);
593 return NULL; 642 return NULL;
594 }
595 rq->cmd_flags |= REQ_ELVPRIV;
596 } 643 }
597 644
598 return rq; 645 return rq;
@@ -651,12 +698,13 @@ static void __freed_request(struct request_queue *q, int sync)
651 * A request has just been released. Account for it, update the full and 698 * A request has just been released. Account for it, update the full and
652 * congestion status, wake up any waiters. Called under q->queue_lock. 699 * congestion status, wake up any waiters. Called under q->queue_lock.
653 */ 700 */
654static void freed_request(struct request_queue *q, int sync, int priv) 701static void freed_request(struct request_queue *q, unsigned int flags)
655{ 702{
656 struct request_list *rl = &q->rq; 703 struct request_list *rl = &q->rq;
704 int sync = rw_is_sync(flags);
657 705
658 rl->count[sync]--; 706 rl->count[sync]--;
659 if (priv) 707 if (flags & REQ_ELVPRIV)
660 rl->elvpriv--; 708 rl->elvpriv--;
661 709
662 __freed_request(q, sync); 710 __freed_request(q, sync);
@@ -684,10 +732,19 @@ static bool blk_rq_should_init_elevator(struct bio *bio)
684 return true; 732 return true;
685} 733}
686 734
687/* 735/**
688 * Get a free request, queue_lock must be held. 736 * get_request - get a free request
689 * Returns NULL on failure, with queue_lock held. 737 * @q: request_queue to allocate request from
690 * Returns !NULL on success, with queue_lock *not held*. 738 * @rw_flags: RW and SYNC flags
739 * @bio: bio to allocate request for (can be %NULL)
740 * @gfp_mask: allocation mask
741 *
742 * Get a free request from @q. This function may fail under memory
743 * pressure or if @q is dead.
744 *
745 * Must be callled with @q->queue_lock held and,
746 * Returns %NULL on failure, with @q->queue_lock held.
747 * Returns !%NULL on success, with @q->queue_lock *not held*.
691 */ 748 */
692static struct request *get_request(struct request_queue *q, int rw_flags, 749static struct request *get_request(struct request_queue *q, int rw_flags,
693 struct bio *bio, gfp_t gfp_mask) 750 struct bio *bio, gfp_t gfp_mask)
@@ -696,7 +753,10 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
696 struct request_list *rl = &q->rq; 753 struct request_list *rl = &q->rq;
697 struct io_context *ioc = NULL; 754 struct io_context *ioc = NULL;
698 const bool is_sync = rw_is_sync(rw_flags) != 0; 755 const bool is_sync = rw_is_sync(rw_flags) != 0;
699 int may_queue, priv = 0; 756 int may_queue;
757
758 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
759 return NULL;
700 760
701 may_queue = elv_may_queue(q, rw_flags); 761 may_queue = elv_may_queue(q, rw_flags);
702 if (may_queue == ELV_MQUEUE_NO) 762 if (may_queue == ELV_MQUEUE_NO)
@@ -740,17 +800,17 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
740 rl->count[is_sync]++; 800 rl->count[is_sync]++;
741 rl->starved[is_sync] = 0; 801 rl->starved[is_sync] = 0;
742 802
743 if (blk_rq_should_init_elevator(bio)) { 803 if (blk_rq_should_init_elevator(bio) &&
744 priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); 804 !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags)) {
745 if (priv) 805 rw_flags |= REQ_ELVPRIV;
746 rl->elvpriv++; 806 rl->elvpriv++;
747 } 807 }
748 808
749 if (blk_queue_io_stat(q)) 809 if (blk_queue_io_stat(q))
750 rw_flags |= REQ_IO_STAT; 810 rw_flags |= REQ_IO_STAT;
751 spin_unlock_irq(q->queue_lock); 811 spin_unlock_irq(q->queue_lock);
752 812
753 rq = blk_alloc_request(q, rw_flags, priv, gfp_mask); 813 rq = blk_alloc_request(q, rw_flags, gfp_mask);
754 if (unlikely(!rq)) { 814 if (unlikely(!rq)) {
755 /* 815 /*
756 * Allocation failed presumably due to memory. Undo anything 816 * Allocation failed presumably due to memory. Undo anything
@@ -760,7 +820,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
760 * wait queue, but this is pretty rare. 820 * wait queue, but this is pretty rare.
761 */ 821 */
762 spin_lock_irq(q->queue_lock); 822 spin_lock_irq(q->queue_lock);
763 freed_request(q, is_sync, priv); 823 freed_request(q, rw_flags);
764 824
765 /* 825 /*
766 * in the very unlikely event that allocation failed and no 826 * in the very unlikely event that allocation failed and no
@@ -790,11 +850,18 @@ out:
790 return rq; 850 return rq;
791} 851}
792 852
793/* 853/**
794 * No available requests for this queue, wait for some requests to become 854 * get_request_wait - get a free request with retry
795 * available. 855 * @q: request_queue to allocate request from
856 * @rw_flags: RW and SYNC flags
857 * @bio: bio to allocate request for (can be %NULL)
858 *
859 * Get a free request from @q. This function keeps retrying under memory
860 * pressure and fails iff @q is dead.
796 * 861 *
797 * Called with q->queue_lock held, and returns with it unlocked. 862 * Must be callled with @q->queue_lock held and,
863 * Returns %NULL on failure, with @q->queue_lock held.
864 * Returns !%NULL on success, with @q->queue_lock *not held*.
798 */ 865 */
799static struct request *get_request_wait(struct request_queue *q, int rw_flags, 866static struct request *get_request_wait(struct request_queue *q, int rw_flags,
800 struct bio *bio) 867 struct bio *bio)
@@ -808,6 +875,9 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
808 struct io_context *ioc; 875 struct io_context *ioc;
809 struct request_list *rl = &q->rq; 876 struct request_list *rl = &q->rq;
810 877
878 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
879 return NULL;
880
811 prepare_to_wait_exclusive(&rl->wait[is_sync], &wait, 881 prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
812 TASK_UNINTERRUPTIBLE); 882 TASK_UNINTERRUPTIBLE);
813 883
@@ -838,19 +908,15 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
838{ 908{
839 struct request *rq; 909 struct request *rq;
840 910
841 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
842 return NULL;
843
844 BUG_ON(rw != READ && rw != WRITE); 911 BUG_ON(rw != READ && rw != WRITE);
845 912
846 spin_lock_irq(q->queue_lock); 913 spin_lock_irq(q->queue_lock);
847 if (gfp_mask & __GFP_WAIT) { 914 if (gfp_mask & __GFP_WAIT)
848 rq = get_request_wait(q, rw, NULL); 915 rq = get_request_wait(q, rw, NULL);
849 } else { 916 else
850 rq = get_request(q, rw, NULL, gfp_mask); 917 rq = get_request(q, rw, NULL, gfp_mask);
851 if (!rq) 918 if (!rq)
852 spin_unlock_irq(q->queue_lock); 919 spin_unlock_irq(q->queue_lock);
853 }
854 /* q->queue_lock is unlocked at this point */ 920 /* q->queue_lock is unlocked at this point */
855 921
856 return rq; 922 return rq;
@@ -1052,14 +1118,13 @@ void __blk_put_request(struct request_queue *q, struct request *req)
1052 * it didn't come out of our reserved rq pools 1118 * it didn't come out of our reserved rq pools
1053 */ 1119 */
1054 if (req->cmd_flags & REQ_ALLOCED) { 1120 if (req->cmd_flags & REQ_ALLOCED) {
1055 int is_sync = rq_is_sync(req) != 0; 1121 unsigned int flags = req->cmd_flags;
1056 int priv = req->cmd_flags & REQ_ELVPRIV;
1057 1122
1058 BUG_ON(!list_empty(&req->queuelist)); 1123 BUG_ON(!list_empty(&req->queuelist));
1059 BUG_ON(!hlist_unhashed(&req->hash)); 1124 BUG_ON(!hlist_unhashed(&req->hash));
1060 1125
1061 blk_free_request(q, req); 1126 blk_free_request(q, req);
1062 freed_request(q, is_sync, priv); 1127 freed_request(q, flags);
1063 } 1128 }
1064} 1129}
1065EXPORT_SYMBOL_GPL(__blk_put_request); 1130EXPORT_SYMBOL_GPL(__blk_put_request);
@@ -1161,18 +1226,32 @@ static bool bio_attempt_front_merge(struct request_queue *q,
1161 return true; 1226 return true;
1162} 1227}
1163 1228
1164/* 1229/**
1165 * Attempts to merge with the plugged list in the current process. Returns 1230 * attempt_plug_merge - try to merge with %current's plugged list
1166 * true if merge was successful, otherwise false. 1231 * @q: request_queue new bio is being queued at
1232 * @bio: new bio being queued
1233 * @request_count: out parameter for number of traversed plugged requests
1234 *
1235 * Determine whether @bio being queued on @q can be merged with a request
1236 * on %current's plugged list. Returns %true if merge was successful,
1237 * otherwise %false.
1238 *
1239 * This function is called without @q->queue_lock; however, elevator is
1240 * accessed iff there already are requests on the plugged list which in
1241 * turn guarantees validity of the elevator.
1242 *
1243 * Note that, on successful merge, elevator operation
1244 * elevator_bio_merged_fn() will be called without queue lock. Elevator
1245 * must be ready for this.
1167 */ 1246 */
1168static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q, 1247static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
1169 struct bio *bio, unsigned int *request_count) 1248 unsigned int *request_count)
1170{ 1249{
1171 struct blk_plug *plug; 1250 struct blk_plug *plug;
1172 struct request *rq; 1251 struct request *rq;
1173 bool ret = false; 1252 bool ret = false;
1174 1253
1175 plug = tsk->plug; 1254 plug = current->plug;
1176 if (!plug) 1255 if (!plug)
1177 goto out; 1256 goto out;
1178 *request_count = 0; 1257 *request_count = 0;
@@ -1202,7 +1281,6 @@ out:
1202 1281
1203void init_request_from_bio(struct request *req, struct bio *bio) 1282void init_request_from_bio(struct request *req, struct bio *bio)
1204{ 1283{
1205 req->cpu = bio->bi_comp_cpu;
1206 req->cmd_type = REQ_TYPE_FS; 1284 req->cmd_type = REQ_TYPE_FS;
1207 1285
1208 req->cmd_flags |= bio->bi_rw & REQ_COMMON_MASK; 1286 req->cmd_flags |= bio->bi_rw & REQ_COMMON_MASK;
@@ -1215,7 +1293,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1215 blk_rq_bio_prep(req->q, req, bio); 1293 blk_rq_bio_prep(req->q, req, bio);
1216} 1294}
1217 1295
1218static int __make_request(struct request_queue *q, struct bio *bio) 1296void blk_queue_bio(struct request_queue *q, struct bio *bio)
1219{ 1297{
1220 const bool sync = !!(bio->bi_rw & REQ_SYNC); 1298 const bool sync = !!(bio->bi_rw & REQ_SYNC);
1221 struct blk_plug *plug; 1299 struct blk_plug *plug;
@@ -1240,8 +1318,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
1240 * Check if we can merge with the plugged list before grabbing 1318 * Check if we can merge with the plugged list before grabbing
1241 * any locks. 1319 * any locks.
1242 */ 1320 */
1243 if (attempt_plug_merge(current, q, bio, &request_count)) 1321 if (attempt_plug_merge(q, bio, &request_count))
1244 goto out; 1322 return;
1245 1323
1246 spin_lock_irq(q->queue_lock); 1324 spin_lock_irq(q->queue_lock);
1247 1325
@@ -1275,6 +1353,10 @@ get_rq:
1275 * Returns with the queue unlocked. 1353 * Returns with the queue unlocked.
1276 */ 1354 */
1277 req = get_request_wait(q, rw_flags, bio); 1355 req = get_request_wait(q, rw_flags, bio);
1356 if (unlikely(!req)) {
1357 bio_endio(bio, -ENODEV); /* @q is dead */
1358 goto out_unlock;
1359 }
1278 1360
1279 /* 1361 /*
1280 * After dropping the lock and possibly sleeping here, our request 1362 * After dropping the lock and possibly sleeping here, our request
@@ -1284,8 +1366,7 @@ get_rq:
1284 */ 1366 */
1285 init_request_from_bio(req, bio); 1367 init_request_from_bio(req, bio);
1286 1368
1287 if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) || 1369 if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags))
1288 bio_flagged(bio, BIO_CPU_AFFINE))
1289 req->cpu = raw_smp_processor_id(); 1370 req->cpu = raw_smp_processor_id();
1290 1371
1291 plug = current->plug; 1372 plug = current->plug;
@@ -1316,9 +1397,8 @@ get_rq:
1316out_unlock: 1397out_unlock:
1317 spin_unlock_irq(q->queue_lock); 1398 spin_unlock_irq(q->queue_lock);
1318 } 1399 }
1319out:
1320 return 0;
1321} 1400}
1401EXPORT_SYMBOL_GPL(blk_queue_bio); /* for device mapper only */
1322 1402
1323/* 1403/*
1324 * If bio->bi_dev is a partition, remap the location 1404 * If bio->bi_dev is a partition, remap the location
@@ -1417,165 +1497,135 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
1417 return 0; 1497 return 0;
1418} 1498}
1419 1499
1420/** 1500static noinline_for_stack bool
1421 * generic_make_request - hand a buffer to its device driver for I/O 1501generic_make_request_checks(struct bio *bio)
1422 * @bio: The bio describing the location in memory and on the device.
1423 *
1424 * generic_make_request() is used to make I/O requests of block
1425 * devices. It is passed a &struct bio, which describes the I/O that needs
1426 * to be done.
1427 *
1428 * generic_make_request() does not return any status. The
1429 * success/failure status of the request, along with notification of
1430 * completion, is delivered asynchronously through the bio->bi_end_io
1431 * function described (one day) else where.
1432 *
1433 * The caller of generic_make_request must make sure that bi_io_vec
1434 * are set to describe the memory buffer, and that bi_dev and bi_sector are
1435 * set to describe the device address, and the
1436 * bi_end_io and optionally bi_private are set to describe how
1437 * completion notification should be signaled.
1438 *
1439 * generic_make_request and the drivers it calls may use bi_next if this
1440 * bio happens to be merged with someone else, and may change bi_dev and
1441 * bi_sector for remaps as it sees fit. So the values of these fields
1442 * should NOT be depended on after the call to generic_make_request.
1443 */
1444static inline void __generic_make_request(struct bio *bio)
1445{ 1502{
1446 struct request_queue *q; 1503 struct request_queue *q;
1447 sector_t old_sector; 1504 int nr_sectors = bio_sectors(bio);
1448 int ret, nr_sectors = bio_sectors(bio);
1449 dev_t old_dev;
1450 int err = -EIO; 1505 int err = -EIO;
1506 char b[BDEVNAME_SIZE];
1507 struct hd_struct *part;
1451 1508
1452 might_sleep(); 1509 might_sleep();
1453 1510
1454 if (bio_check_eod(bio, nr_sectors)) 1511 if (bio_check_eod(bio, nr_sectors))
1455 goto end_io; 1512 goto end_io;
1456 1513
1457 /* 1514 q = bdev_get_queue(bio->bi_bdev);
1458 * Resolve the mapping until finished. (drivers are 1515 if (unlikely(!q)) {
1459 * still free to implement/resolve their own stacking 1516 printk(KERN_ERR
1460 * by explicitly returning 0) 1517 "generic_make_request: Trying to access "
1461 * 1518 "nonexistent block-device %s (%Lu)\n",
1462 * NOTE: we don't repeat the blk_size check for each new device. 1519 bdevname(bio->bi_bdev, b),
1463 * Stacking drivers are expected to know what they are doing. 1520 (long long) bio->bi_sector);
1464 */ 1521 goto end_io;
1465 old_sector = -1; 1522 }
1466 old_dev = 0;
1467 do {
1468 char b[BDEVNAME_SIZE];
1469 struct hd_struct *part;
1470
1471 q = bdev_get_queue(bio->bi_bdev);
1472 if (unlikely(!q)) {
1473 printk(KERN_ERR
1474 "generic_make_request: Trying to access "
1475 "nonexistent block-device %s (%Lu)\n",
1476 bdevname(bio->bi_bdev, b),
1477 (long long) bio->bi_sector);
1478 goto end_io;
1479 }
1480
1481 if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
1482 nr_sectors > queue_max_hw_sectors(q))) {
1483 printk(KERN_ERR "bio too big device %s (%u > %u)\n",
1484 bdevname(bio->bi_bdev, b),
1485 bio_sectors(bio),
1486 queue_max_hw_sectors(q));
1487 goto end_io;
1488 }
1489
1490 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
1491 goto end_io;
1492
1493 part = bio->bi_bdev->bd_part;
1494 if (should_fail_request(part, bio->bi_size) ||
1495 should_fail_request(&part_to_disk(part)->part0,
1496 bio->bi_size))
1497 goto end_io;
1498
1499 /*
1500 * If this device has partitions, remap block n
1501 * of partition p to block n+start(p) of the disk.
1502 */
1503 blk_partition_remap(bio);
1504 1523
1505 if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) 1524 if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
1506 goto end_io; 1525 nr_sectors > queue_max_hw_sectors(q))) {
1526 printk(KERN_ERR "bio too big device %s (%u > %u)\n",
1527 bdevname(bio->bi_bdev, b),
1528 bio_sectors(bio),
1529 queue_max_hw_sectors(q));
1530 goto end_io;
1531 }
1507 1532
1508 if (old_sector != -1) 1533 part = bio->bi_bdev->bd_part;
1509 trace_block_bio_remap(q, bio, old_dev, old_sector); 1534 if (should_fail_request(part, bio->bi_size) ||
1535 should_fail_request(&part_to_disk(part)->part0,
1536 bio->bi_size))
1537 goto end_io;
1510 1538
1511 old_sector = bio->bi_sector; 1539 /*
1512 old_dev = bio->bi_bdev->bd_dev; 1540 * If this device has partitions, remap block n
1541 * of partition p to block n+start(p) of the disk.
1542 */
1543 blk_partition_remap(bio);
1513 1544
1514 if (bio_check_eod(bio, nr_sectors)) 1545 if (bio_integrity_enabled(bio) && bio_integrity_prep(bio))
1515 goto end_io; 1546 goto end_io;
1516 1547
1517 /* 1548 if (bio_check_eod(bio, nr_sectors))
1518 * Filter flush bio's early so that make_request based 1549 goto end_io;
1519 * drivers without flush support don't have to worry
1520 * about them.
1521 */
1522 if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) && !q->flush_flags) {
1523 bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
1524 if (!nr_sectors) {
1525 err = 0;
1526 goto end_io;
1527 }
1528 }
1529 1550
1530 if ((bio->bi_rw & REQ_DISCARD) && 1551 /*
1531 (!blk_queue_discard(q) || 1552 * Filter flush bio's early so that make_request based
1532 ((bio->bi_rw & REQ_SECURE) && 1553 * drivers without flush support don't have to worry
1533 !blk_queue_secdiscard(q)))) { 1554 * about them.
1534 err = -EOPNOTSUPP; 1555 */
1556 if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) && !q->flush_flags) {
1557 bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
1558 if (!nr_sectors) {
1559 err = 0;
1535 goto end_io; 1560 goto end_io;
1536 } 1561 }
1562 }
1537 1563
1538 if (blk_throtl_bio(q, &bio)) 1564 if ((bio->bi_rw & REQ_DISCARD) &&
1539 goto end_io; 1565 (!blk_queue_discard(q) ||
1540 1566 ((bio->bi_rw & REQ_SECURE) &&
1541 /* 1567 !blk_queue_secdiscard(q)))) {
1542 * If bio = NULL, bio has been throttled and will be submitted 1568 err = -EOPNOTSUPP;
1543 * later. 1569 goto end_io;
1544 */ 1570 }
1545 if (!bio)
1546 break;
1547
1548 trace_block_bio_queue(q, bio);
1549 1571
1550 ret = q->make_request_fn(q, bio); 1572 if (blk_throtl_bio(q, bio))
1551 } while (ret); 1573 return false; /* throttled, will be resubmitted later */
1552 1574
1553 return; 1575 trace_block_bio_queue(q, bio);
1576 return true;
1554 1577
1555end_io: 1578end_io:
1556 bio_endio(bio, err); 1579 bio_endio(bio, err);
1580 return false;
1557} 1581}
1558 1582
1559/* 1583/**
1560 * We only want one ->make_request_fn to be active at a time, 1584 * generic_make_request - hand a buffer to its device driver for I/O
1561 * else stack usage with stacked devices could be a problem. 1585 * @bio: The bio describing the location in memory and on the device.
1562 * So use current->bio_list to keep a list of requests 1586 *
1563 * submited by a make_request_fn function. 1587 * generic_make_request() is used to make I/O requests of block
1564 * current->bio_list is also used as a flag to say if 1588 * devices. It is passed a &struct bio, which describes the I/O that needs
1565 * generic_make_request is currently active in this task or not. 1589 * to be done.
1566 * If it is NULL, then no make_request is active. If it is non-NULL, 1590 *
1567 * then a make_request is active, and new requests should be added 1591 * generic_make_request() does not return any status. The
1568 * at the tail 1592 * success/failure status of the request, along with notification of
1593 * completion, is delivered asynchronously through the bio->bi_end_io
1594 * function described (one day) else where.
1595 *
1596 * The caller of generic_make_request must make sure that bi_io_vec
1597 * are set to describe the memory buffer, and that bi_dev and bi_sector are
1598 * set to describe the device address, and the
1599 * bi_end_io and optionally bi_private are set to describe how
1600 * completion notification should be signaled.
1601 *
1602 * generic_make_request and the drivers it calls may use bi_next if this
1603 * bio happens to be merged with someone else, and may resubmit the bio to
1604 * a lower device by calling into generic_make_request recursively, which
1605 * means the bio should NOT be touched after the call to ->make_request_fn.
1569 */ 1606 */
1570void generic_make_request(struct bio *bio) 1607void generic_make_request(struct bio *bio)
1571{ 1608{
1572 struct bio_list bio_list_on_stack; 1609 struct bio_list bio_list_on_stack;
1573 1610
1611 if (!generic_make_request_checks(bio))
1612 return;
1613
1614 /*
1615 * We only want one ->make_request_fn to be active at a time, else
1616 * stack usage with stacked devices could be a problem. So use
1617 * current->bio_list to keep a list of requests submited by a
1618 * make_request_fn function. current->bio_list is also used as a
1619 * flag to say if generic_make_request is currently active in this
1620 * task or not. If it is NULL, then no make_request is active. If
1621 * it is non-NULL, then a make_request is active, and new requests
1622 * should be added at the tail
1623 */
1574 if (current->bio_list) { 1624 if (current->bio_list) {
1575 /* make_request is active */
1576 bio_list_add(current->bio_list, bio); 1625 bio_list_add(current->bio_list, bio);
1577 return; 1626 return;
1578 } 1627 }
1628
1579 /* following loop may be a bit non-obvious, and so deserves some 1629 /* following loop may be a bit non-obvious, and so deserves some
1580 * explanation. 1630 * explanation.
1581 * Before entering the loop, bio->bi_next is NULL (as all callers 1631 * Before entering the loop, bio->bi_next is NULL (as all callers
@@ -1583,22 +1633,21 @@ void generic_make_request(struct bio *bio)
1583 * We pretend that we have just taken it off a longer list, so 1633 * We pretend that we have just taken it off a longer list, so
1584 * we assign bio_list to a pointer to the bio_list_on_stack, 1634 * we assign bio_list to a pointer to the bio_list_on_stack,
1585 * thus initialising the bio_list of new bios to be 1635 * thus initialising the bio_list of new bios to be
1586 * added. __generic_make_request may indeed add some more bios 1636 * added. ->make_request() may indeed add some more bios
1587 * through a recursive call to generic_make_request. If it 1637 * through a recursive call to generic_make_request. If it
1588 * did, we find a non-NULL value in bio_list and re-enter the loop 1638 * did, we find a non-NULL value in bio_list and re-enter the loop
1589 * from the top. In this case we really did just take the bio 1639 * from the top. In this case we really did just take the bio
1590 * of the top of the list (no pretending) and so remove it from 1640 * of the top of the list (no pretending) and so remove it from
1591 * bio_list, and call into __generic_make_request again. 1641 * bio_list, and call into ->make_request() again.
1592 *
1593 * The loop was structured like this to make only one call to
1594 * __generic_make_request (which is important as it is large and
1595 * inlined) and to keep the structure simple.
1596 */ 1642 */
1597 BUG_ON(bio->bi_next); 1643 BUG_ON(bio->bi_next);
1598 bio_list_init(&bio_list_on_stack); 1644 bio_list_init(&bio_list_on_stack);
1599 current->bio_list = &bio_list_on_stack; 1645 current->bio_list = &bio_list_on_stack;
1600 do { 1646 do {
1601 __generic_make_request(bio); 1647 struct request_queue *q = bdev_get_queue(bio->bi_bdev);
1648
1649 q->make_request_fn(q, bio);
1650
1602 bio = bio_list_pop(current->bio_list); 1651 bio = bio_list_pop(current->bio_list);
1603 } while (bio); 1652 } while (bio);
1604 current->bio_list = NULL; /* deactivate */ 1653 current->bio_list = NULL; /* deactivate */
@@ -1725,6 +1774,8 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
1725 where = ELEVATOR_INSERT_FLUSH; 1774 where = ELEVATOR_INSERT_FLUSH;
1726 1775
1727 add_acct_request(q, rq, where); 1776 add_acct_request(q, rq, where);
1777 if (where == ELEVATOR_INSERT_FLUSH)
1778 __blk_run_queue(q);
1728 spin_unlock_irqrestore(q->queue_lock, flags); 1779 spin_unlock_irqrestore(q->queue_lock, flags);
1729 1780
1730 return 0; 1781 return 0;
@@ -2628,6 +2679,20 @@ EXPORT_SYMBOL(kblockd_schedule_delayed_work);
2628 2679
2629#define PLUG_MAGIC 0x91827364 2680#define PLUG_MAGIC 0x91827364
2630 2681
2682/**
2683 * blk_start_plug - initialize blk_plug and track it inside the task_struct
2684 * @plug: The &struct blk_plug that needs to be initialized
2685 *
2686 * Description:
2687 * Tracking blk_plug inside the task_struct will help with auto-flushing the
2688 * pending I/O should the task end up blocking between blk_start_plug() and
2689 * blk_finish_plug(). This is important from a performance perspective, but
2690 * also ensures that we don't deadlock. For instance, if the task is blocking
2691 * for a memory allocation, memory reclaim could end up wanting to free a
2692 * page belonging to that request that is currently residing in our private
2693 * plug. By flushing the pending I/O when the process goes to sleep, we avoid
2694 * this kind of deadlock.
2695 */
2631void blk_start_plug(struct blk_plug *plug) 2696void blk_start_plug(struct blk_plug *plug)
2632{ 2697{
2633 struct task_struct *tsk = current; 2698 struct task_struct *tsk = current;
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 491eb30a242d..720ad607ff91 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -320,7 +320,7 @@ void blk_insert_flush(struct request *rq)
320 return; 320 return;
321 } 321 }
322 322
323 BUG_ON(!rq->bio || rq->bio != rq->biotail); 323 BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */
324 324
325 /* 325 /*
326 * If there's data but flush is not necessary, the request can be 326 * If there's data but flush is not necessary, the request can be
@@ -330,7 +330,6 @@ void blk_insert_flush(struct request *rq)
330 if ((policy & REQ_FSEQ_DATA) && 330 if ((policy & REQ_FSEQ_DATA) &&
331 !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { 331 !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) {
332 list_add_tail(&rq->queuelist, &q->queue_head); 332 list_add_tail(&rq->queuelist, &q->queue_head);
333 blk_run_queue_async(q);
334 return; 333 return;
335 } 334 }
336 335
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 60fda88c57f0..e7f9f657f105 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -457,11 +457,11 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
457} 457}
458 458
459/** 459/**
460 * blk_cleanup_queue: - release a &struct request_queue when it is no longer needed 460 * blk_release_queue: - release a &struct request_queue when it is no longer needed
461 * @kobj: the kobj belonging of the request queue to be released 461 * @kobj: the kobj belonging to the request queue to be released
462 * 462 *
463 * Description: 463 * Description:
464 * blk_cleanup_queue is the pair to blk_init_queue() or 464 * blk_release_queue is the pair to blk_init_queue() or
465 * blk_queue_make_request(). It should be called when a request queue is 465 * blk_queue_make_request(). It should be called when a request queue is
466 * being released; typically when a block device is being de-registered. 466 * being released; typically when a block device is being de-registered.
467 * Currently, its primary task it to free all the &struct request 467 * Currently, its primary task it to free all the &struct request
@@ -490,6 +490,7 @@ static void blk_release_queue(struct kobject *kobj)
490 if (q->queue_tags) 490 if (q->queue_tags)
491 __blk_queue_free_tags(q); 491 __blk_queue_free_tags(q);
492 492
493 blk_throtl_release(q);
493 blk_trace_shutdown(q); 494 blk_trace_shutdown(q);
494 495
495 bdi_destroy(&q->backing_dev_info); 496 bdi_destroy(&q->backing_dev_info);
diff --git a/block/blk-tag.c b/block/blk-tag.c
index ece65fc4c79b..e74d6d13838f 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -286,12 +286,14 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
286 286
287 BUG_ON(tag == -1); 287 BUG_ON(tag == -1);
288 288
289 if (unlikely(tag >= bqt->real_max_depth)) 289 if (unlikely(tag >= bqt->max_depth)) {
290 /* 290 /*
291 * This can happen after tag depth has been reduced. 291 * This can happen after tag depth has been reduced.
292 * FIXME: how about a warning or info message here? 292 * But tag shouldn't be larger than real_max_depth.
293 */ 293 */
294 WARN_ON(tag >= bqt->real_max_depth);
294 return; 295 return;
296 }
295 297
296 list_del_init(&rq->queuelist); 298 list_del_init(&rq->queuelist);
297 rq->cmd_flags &= ~REQ_QUEUED; 299 rq->cmd_flags &= ~REQ_QUEUED;
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index a19f58c6fc3a..4553245d9317 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -10,6 +10,7 @@
10#include <linux/bio.h> 10#include <linux/bio.h>
11#include <linux/blktrace_api.h> 11#include <linux/blktrace_api.h>
12#include "blk-cgroup.h" 12#include "blk-cgroup.h"
13#include "blk.h"
13 14
14/* Max dispatch from a group in 1 round */ 15/* Max dispatch from a group in 1 round */
15static int throtl_grp_quantum = 8; 16static int throtl_grp_quantum = 8;
@@ -302,16 +303,16 @@ throtl_grp *throtl_find_tg(struct throtl_data *td, struct blkio_cgroup *blkcg)
302 return tg; 303 return tg;
303} 304}
304 305
305/*
306 * This function returns with queue lock unlocked in case of error, like
307 * request queue is no more
308 */
309static struct throtl_grp * throtl_get_tg(struct throtl_data *td) 306static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
310{ 307{
311 struct throtl_grp *tg = NULL, *__tg = NULL; 308 struct throtl_grp *tg = NULL, *__tg = NULL;
312 struct blkio_cgroup *blkcg; 309 struct blkio_cgroup *blkcg;
313 struct request_queue *q = td->queue; 310 struct request_queue *q = td->queue;
314 311
312 /* no throttling for dead queue */
313 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
314 return NULL;
315
315 rcu_read_lock(); 316 rcu_read_lock();
316 blkcg = task_blkio_cgroup(current); 317 blkcg = task_blkio_cgroup(current);
317 tg = throtl_find_tg(td, blkcg); 318 tg = throtl_find_tg(td, blkcg);
@@ -323,32 +324,22 @@ static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
323 /* 324 /*
324 * Need to allocate a group. Allocation of group also needs allocation 325 * Need to allocate a group. Allocation of group also needs allocation
325 * of per cpu stats which in-turn takes a mutex() and can block. Hence 326 * of per cpu stats which in-turn takes a mutex() and can block. Hence
326 * we need to drop rcu lock and queue_lock before we call alloc 327 * we need to drop rcu lock and queue_lock before we call alloc.
327 *
328 * Take the request queue reference to make sure queue does not
329 * go away once we return from allocation.
330 */ 328 */
331 blk_get_queue(q);
332 rcu_read_unlock(); 329 rcu_read_unlock();
333 spin_unlock_irq(q->queue_lock); 330 spin_unlock_irq(q->queue_lock);
334 331
335 tg = throtl_alloc_tg(td); 332 tg = throtl_alloc_tg(td);
336 /*
337 * We might have slept in group allocation. Make sure queue is not
338 * dead
339 */
340 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
341 blk_put_queue(q);
342 if (tg)
343 kfree(tg);
344
345 return ERR_PTR(-ENODEV);
346 }
347 blk_put_queue(q);
348 333
349 /* Group allocated and queue is still alive. take the lock */ 334 /* Group allocated and queue is still alive. take the lock */
350 spin_lock_irq(q->queue_lock); 335 spin_lock_irq(q->queue_lock);
351 336
337 /* Make sure @q is still alive */
338 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
339 kfree(tg);
340 return NULL;
341 }
342
352 /* 343 /*
353 * Initialize the new group. After sleeping, read the blkcg again. 344 * Initialize the new group. After sleeping, read the blkcg again.
354 */ 345 */
@@ -1014,11 +1005,6 @@ static void throtl_release_tgs(struct throtl_data *td)
1014 } 1005 }
1015} 1006}
1016 1007
1017static void throtl_td_free(struct throtl_data *td)
1018{
1019 kfree(td);
1020}
1021
1022/* 1008/*
1023 * Blk cgroup controller notification saying that blkio_group object is being 1009 * Blk cgroup controller notification saying that blkio_group object is being
1024 * delinked as associated cgroup object is going away. That also means that 1010 * delinked as associated cgroup object is going away. That also means that
@@ -1123,17 +1109,17 @@ static struct blkio_policy_type blkio_policy_throtl = {
1123 .plid = BLKIO_POLICY_THROTL, 1109 .plid = BLKIO_POLICY_THROTL,
1124}; 1110};
1125 1111
1126int blk_throtl_bio(struct request_queue *q, struct bio **biop) 1112bool blk_throtl_bio(struct request_queue *q, struct bio *bio)
1127{ 1113{
1128 struct throtl_data *td = q->td; 1114 struct throtl_data *td = q->td;
1129 struct throtl_grp *tg; 1115 struct throtl_grp *tg;
1130 struct bio *bio = *biop;
1131 bool rw = bio_data_dir(bio), update_disptime = true; 1116 bool rw = bio_data_dir(bio), update_disptime = true;
1132 struct blkio_cgroup *blkcg; 1117 struct blkio_cgroup *blkcg;
1118 bool throttled = false;
1133 1119
1134 if (bio->bi_rw & REQ_THROTTLED) { 1120 if (bio->bi_rw & REQ_THROTTLED) {
1135 bio->bi_rw &= ~REQ_THROTTLED; 1121 bio->bi_rw &= ~REQ_THROTTLED;
1136 return 0; 1122 goto out;
1137 } 1123 }
1138 1124
1139 /* 1125 /*
@@ -1152,7 +1138,7 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop)
1152 blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size, 1138 blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size,
1153 rw, rw_is_sync(bio->bi_rw)); 1139 rw, rw_is_sync(bio->bi_rw));
1154 rcu_read_unlock(); 1140 rcu_read_unlock();
1155 return 0; 1141 goto out;
1156 } 1142 }
1157 } 1143 }
1158 rcu_read_unlock(); 1144 rcu_read_unlock();
@@ -1161,18 +1147,10 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop)
1161 * Either group has not been allocated yet or it is not an unlimited 1147 * Either group has not been allocated yet or it is not an unlimited
1162 * IO group 1148 * IO group
1163 */ 1149 */
1164
1165 spin_lock_irq(q->queue_lock); 1150 spin_lock_irq(q->queue_lock);
1166 tg = throtl_get_tg(td); 1151 tg = throtl_get_tg(td);
1167 1152 if (unlikely(!tg))
1168 if (IS_ERR(tg)) { 1153 goto out_unlock;
1169 if (PTR_ERR(tg) == -ENODEV) {
1170 /*
1171 * Queue is gone. No queue lock held here.
1172 */
1173 return -ENODEV;
1174 }
1175 }
1176 1154
1177 if (tg->nr_queued[rw]) { 1155 if (tg->nr_queued[rw]) {
1178 /* 1156 /*
@@ -1200,7 +1178,7 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop)
1200 * So keep on trimming slice even if bio is not queued. 1178 * So keep on trimming slice even if bio is not queued.
1201 */ 1179 */
1202 throtl_trim_slice(td, tg, rw); 1180 throtl_trim_slice(td, tg, rw);
1203 goto out; 1181 goto out_unlock;
1204 } 1182 }
1205 1183
1206queue_bio: 1184queue_bio:
@@ -1212,16 +1190,52 @@ queue_bio:
1212 tg->nr_queued[READ], tg->nr_queued[WRITE]); 1190 tg->nr_queued[READ], tg->nr_queued[WRITE]);
1213 1191
1214 throtl_add_bio_tg(q->td, tg, bio); 1192 throtl_add_bio_tg(q->td, tg, bio);
1215 *biop = NULL; 1193 throttled = true;
1216 1194
1217 if (update_disptime) { 1195 if (update_disptime) {
1218 tg_update_disptime(td, tg); 1196 tg_update_disptime(td, tg);
1219 throtl_schedule_next_dispatch(td); 1197 throtl_schedule_next_dispatch(td);
1220 } 1198 }
1221 1199
1200out_unlock:
1201 spin_unlock_irq(q->queue_lock);
1222out: 1202out:
1203 return throttled;
1204}
1205
1206/**
1207 * blk_throtl_drain - drain throttled bios
1208 * @q: request_queue to drain throttled bios for
1209 *
1210 * Dispatch all currently throttled bios on @q through ->make_request_fn().
1211 */
1212void blk_throtl_drain(struct request_queue *q)
1213 __releases(q->queue_lock) __acquires(q->queue_lock)
1214{
1215 struct throtl_data *td = q->td;
1216 struct throtl_rb_root *st = &td->tg_service_tree;
1217 struct throtl_grp *tg;
1218 struct bio_list bl;
1219 struct bio *bio;
1220
1221 WARN_ON_ONCE(!queue_is_locked(q));
1222
1223 bio_list_init(&bl);
1224
1225 while ((tg = throtl_rb_first(st))) {
1226 throtl_dequeue_tg(td, tg);
1227
1228 while ((bio = bio_list_peek(&tg->bio_lists[READ])))
1229 tg_dispatch_one_bio(td, tg, bio_data_dir(bio), &bl);
1230 while ((bio = bio_list_peek(&tg->bio_lists[WRITE])))
1231 tg_dispatch_one_bio(td, tg, bio_data_dir(bio), &bl);
1232 }
1223 spin_unlock_irq(q->queue_lock); 1233 spin_unlock_irq(q->queue_lock);
1224 return 0; 1234
1235 while ((bio = bio_list_pop(&bl)))
1236 generic_make_request(bio);
1237
1238 spin_lock_irq(q->queue_lock);
1225} 1239}
1226 1240
1227int blk_throtl_init(struct request_queue *q) 1241int blk_throtl_init(struct request_queue *q)
@@ -1296,7 +1310,11 @@ void blk_throtl_exit(struct request_queue *q)
1296 * it. 1310 * it.
1297 */ 1311 */
1298 throtl_shutdown_wq(q); 1312 throtl_shutdown_wq(q);
1299 throtl_td_free(td); 1313}
1314
1315void blk_throtl_release(struct request_queue *q)
1316{
1317 kfree(q->td);
1300} 1318}
1301 1319
1302static int __init throtl_init(void) 1320static int __init throtl_init(void)
diff --git a/block/blk.h b/block/blk.h
index 20b900a377c9..3f6551b3c92d 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -15,6 +15,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
15 struct bio *bio); 15 struct bio *bio);
16int blk_rq_append_bio(struct request_queue *q, struct request *rq, 16int blk_rq_append_bio(struct request_queue *q, struct request *rq,
17 struct bio *bio); 17 struct bio *bio);
18void blk_drain_queue(struct request_queue *q, bool drain_all);
18void blk_dequeue_request(struct request *rq); 19void blk_dequeue_request(struct request *rq);
19void __blk_queue_free_tags(struct request_queue *q); 20void __blk_queue_free_tags(struct request_queue *q);
20bool __blk_end_bidi_request(struct request *rq, int error, 21bool __blk_end_bidi_request(struct request *rq, int error,
@@ -188,4 +189,21 @@ static inline int blk_do_io_stat(struct request *rq)
188 (rq->cmd_flags & REQ_DISCARD)); 189 (rq->cmd_flags & REQ_DISCARD));
189} 190}
190 191
191#endif 192#ifdef CONFIG_BLK_DEV_THROTTLING
193extern bool blk_throtl_bio(struct request_queue *q, struct bio *bio);
194extern void blk_throtl_drain(struct request_queue *q);
195extern int blk_throtl_init(struct request_queue *q);
196extern void blk_throtl_exit(struct request_queue *q);
197extern void blk_throtl_release(struct request_queue *q);
198#else /* CONFIG_BLK_DEV_THROTTLING */
199static inline bool blk_throtl_bio(struct request_queue *q, struct bio *bio)
200{
201 return false;
202}
203static inline void blk_throtl_drain(struct request_queue *q) { }
204static inline int blk_throtl_init(struct request_queue *q) { return 0; }
205static inline void blk_throtl_exit(struct request_queue *q) { }
206static inline void blk_throtl_release(struct request_queue *q) { }
207#endif /* CONFIG_BLK_DEV_THROTTLING */
208
209#endif /* BLK_INTERNAL_H */
diff --git a/block/elevator.c b/block/elevator.c
index a3b64bc71d88..66343d6917d0 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/compiler.h> 33#include <linux/compiler.h>
34#include <linux/delay.h>
35#include <linux/blktrace_api.h> 34#include <linux/blktrace_api.h>
36#include <linux/hash.h> 35#include <linux/hash.h>
37#include <linux/uaccess.h> 36#include <linux/uaccess.h>
@@ -182,7 +181,7 @@ static void elevator_attach(struct request_queue *q, struct elevator_queue *eq,
182 eq->elevator_data = data; 181 eq->elevator_data = data;
183} 182}
184 183
185static char chosen_elevator[16]; 184static char chosen_elevator[ELV_NAME_MAX];
186 185
187static int __init elevator_setup(char *str) 186static int __init elevator_setup(char *str)
188{ 187{
@@ -606,43 +605,35 @@ void elv_requeue_request(struct request_queue *q, struct request *rq)
606void elv_drain_elevator(struct request_queue *q) 605void elv_drain_elevator(struct request_queue *q)
607{ 606{
608 static int printed; 607 static int printed;
608
609 lockdep_assert_held(q->queue_lock);
610
609 while (q->elevator->ops->elevator_dispatch_fn(q, 1)) 611 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
610 ; 612 ;
611 if (q->nr_sorted == 0) 613 if (q->nr_sorted && printed++ < 10) {
612 return;
613 if (printed++ < 10) {
614 printk(KERN_ERR "%s: forced dispatching is broken " 614 printk(KERN_ERR "%s: forced dispatching is broken "
615 "(nr_sorted=%u), please report this\n", 615 "(nr_sorted=%u), please report this\n",
616 q->elevator->elevator_type->elevator_name, q->nr_sorted); 616 q->elevator->elevator_type->elevator_name, q->nr_sorted);
617 } 617 }
618} 618}
619 619
620/*
621 * Call with queue lock held, interrupts disabled
622 */
623void elv_quiesce_start(struct request_queue *q) 620void elv_quiesce_start(struct request_queue *q)
624{ 621{
625 if (!q->elevator) 622 if (!q->elevator)
626 return; 623 return;
627 624
625 spin_lock_irq(q->queue_lock);
628 queue_flag_set(QUEUE_FLAG_ELVSWITCH, q); 626 queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
627 spin_unlock_irq(q->queue_lock);
629 628
630 /* 629 blk_drain_queue(q, false);
631 * make sure we don't have any requests in flight
632 */
633 elv_drain_elevator(q);
634 while (q->rq.elvpriv) {
635 __blk_run_queue(q);
636 spin_unlock_irq(q->queue_lock);
637 msleep(10);
638 spin_lock_irq(q->queue_lock);
639 elv_drain_elevator(q);
640 }
641} 630}
642 631
643void elv_quiesce_end(struct request_queue *q) 632void elv_quiesce_end(struct request_queue *q)
644{ 633{
634 spin_lock_irq(q->queue_lock);
645 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); 635 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
636 spin_unlock_irq(q->queue_lock);
646} 637}
647 638
648void __elv_add_request(struct request_queue *q, struct request *rq, int where) 639void __elv_add_request(struct request_queue *q, struct request *rq, int where)
@@ -972,7 +963,6 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
972 /* 963 /*
973 * Turn on BYPASS and drain all requests w/ elevator private data 964 * Turn on BYPASS and drain all requests w/ elevator private data
974 */ 965 */
975 spin_lock_irq(q->queue_lock);
976 elv_quiesce_start(q); 966 elv_quiesce_start(q);
977 967
978 /* 968 /*
@@ -983,8 +973,8 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
983 /* 973 /*
984 * attach and start new elevator 974 * attach and start new elevator
985 */ 975 */
976 spin_lock_irq(q->queue_lock);
986 elevator_attach(q, e, data); 977 elevator_attach(q, e, data);
987
988 spin_unlock_irq(q->queue_lock); 978 spin_unlock_irq(q->queue_lock);
989 979
990 if (old_elevator->registered) { 980 if (old_elevator->registered) {
@@ -999,9 +989,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
999 * finally exit old elevator and turn off BYPASS. 989 * finally exit old elevator and turn off BYPASS.
1000 */ 990 */
1001 elevator_exit(old_elevator); 991 elevator_exit(old_elevator);
1002 spin_lock_irq(q->queue_lock);
1003 elv_quiesce_end(q); 992 elv_quiesce_end(q);
1004 spin_unlock_irq(q->queue_lock);
1005 993
1006 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); 994 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
1007 995
@@ -1015,10 +1003,7 @@ fail_register:
1015 elevator_exit(e); 1003 elevator_exit(e);
1016 q->elevator = old_elevator; 1004 q->elevator = old_elevator;
1017 elv_register_queue(q); 1005 elv_register_queue(q);
1018 1006 elv_quiesce_end(q);
1019 spin_lock_irq(q->queue_lock);
1020 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
1021 spin_unlock_irq(q->queue_lock);
1022 1007
1023 return err; 1008 return err;
1024} 1009}
diff --git a/block/genhd.c b/block/genhd.c
index 94855a9717de..9253839714ff 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -537,7 +537,7 @@ void register_disk(struct gendisk *disk)
537 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); 537 disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
538 538
539 /* No minors to use for partitions */ 539 /* No minors to use for partitions */
540 if (!disk_partitionable(disk)) 540 if (!disk_part_scan_enabled(disk))
541 goto exit; 541 goto exit;
542 542
543 /* No such device (e.g., media were just removed) */ 543 /* No such device (e.g., media were just removed) */
@@ -612,6 +612,12 @@ void add_disk(struct gendisk *disk)
612 register_disk(disk); 612 register_disk(disk);
613 blk_register_queue(disk); 613 blk_register_queue(disk);
614 614
615 /*
616 * Take an extra ref on queue which will be put on disk_release()
617 * so that it sticks around as long as @disk is there.
618 */
619 WARN_ON_ONCE(blk_get_queue(disk->queue));
620
615 retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, 621 retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
616 "bdi"); 622 "bdi");
617 WARN_ON(retval); 623 WARN_ON(retval);
@@ -842,7 +848,7 @@ static int show_partition(struct seq_file *seqf, void *v)
842 char buf[BDEVNAME_SIZE]; 848 char buf[BDEVNAME_SIZE];
843 849
844 /* Don't show non-partitionable removeable devices or empty devices */ 850 /* Don't show non-partitionable removeable devices or empty devices */
845 if (!get_capacity(sgp) || (!disk_partitionable(sgp) && 851 if (!get_capacity(sgp) || (!disk_max_parts(sgp) &&
846 (sgp->flags & GENHD_FL_REMOVABLE))) 852 (sgp->flags & GENHD_FL_REMOVABLE)))
847 return 0; 853 return 0;
848 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) 854 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
@@ -1166,6 +1172,8 @@ static void disk_release(struct device *dev)
1166 disk_replace_part_tbl(disk, NULL); 1172 disk_replace_part_tbl(disk, NULL);
1167 free_part_stats(&disk->part0); 1173 free_part_stats(&disk->part0);
1168 free_part_info(&disk->part0); 1174 free_part_info(&disk->part0);
1175 if (disk->queue)
1176 blk_put_queue(disk->queue);
1169 kfree(disk); 1177 kfree(disk);
1170} 1178}
1171struct class block_class = { 1179struct class block_class = {
diff --git a/block/ioctl.c b/block/ioctl.c
index 1124cd297263..5c74efc01903 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -101,7 +101,7 @@ static int blkdev_reread_part(struct block_device *bdev)
101 struct gendisk *disk = bdev->bd_disk; 101 struct gendisk *disk = bdev->bd_disk;
102 int res; 102 int res;
103 103
104 if (!disk_partitionable(disk) || bdev != bdev->bd_contains) 104 if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains)
105 return -EINVAL; 105 return -EINVAL;
106 if (!capable(CAP_SYS_ADMIN)) 106 if (!capable(CAP_SYS_ADMIN))
107 return -EACCES; 107 return -EACCES;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 4f4230b79bb6..fbdf0d802ec4 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -565,7 +565,7 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
565{ 565{
566 int err; 566 int err;
567 567
568 if (!q || blk_get_queue(q)) 568 if (!q)
569 return -ENXIO; 569 return -ENXIO;
570 570
571 switch (cmd) { 571 switch (cmd) {
@@ -686,7 +686,6 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
686 err = -ENOTTY; 686 err = -ENOTTY;
687 } 687 }
688 688
689 blk_put_queue(q);
690 return err; 689 return err;
691} 690}
692EXPORT_SYMBOL(scsi_cmd_ioctl); 691EXPORT_SYMBOL(scsi_cmd_ioctl);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 0e46faef1d30..6d9a3ab58db2 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -398,6 +398,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
398 }, 398 },
399 { 399 {
400 .callback = init_nvs_nosave, 400 .callback = init_nvs_nosave,
401 .ident = "Sony Vaio VPCEB17FX",
402 .matches = {
403 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
404 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
405 },
406 },
407 {
408 .callback = init_nvs_nosave,
401 .ident = "Sony Vaio VGN-SR11M", 409 .ident = "Sony Vaio VGN-SR11M",
402 .matches = { 410 .matches = {
403 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 411 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index c03277d37748..004f2ce3dc73 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -202,11 +202,18 @@ static int __devexit ahci_remove(struct platform_device *pdev)
202 return 0; 202 return 0;
203} 203}
204 204
205static const struct of_device_id ahci_of_match[] = {
206 { .compatible = "calxeda,hb-ahci", },
207 {},
208};
209MODULE_DEVICE_TABLE(of, ahci_of_match);
210
205static struct platform_driver ahci_driver = { 211static struct platform_driver ahci_driver = {
206 .remove = __devexit_p(ahci_remove), 212 .remove = __devexit_p(ahci_remove),
207 .driver = { 213 .driver = {
208 .name = "ahci", 214 .name = "ahci",
209 .owner = THIS_MODULE, 215 .owner = THIS_MODULE,
216 .of_match_table = ahci_of_match,
210 }, 217 },
211 .id_table = ahci_devtype, 218 .id_table = ahci_devtype,
212}; 219};
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 6bb3aafa85ed..124dbf60c9bf 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -29,13 +29,10 @@ static int rpm_suspend(struct device *dev, int rpmflags);
29void update_pm_runtime_accounting(struct device *dev) 29void update_pm_runtime_accounting(struct device *dev)
30{ 30{
31 unsigned long now = jiffies; 31 unsigned long now = jiffies;
32 int delta; 32 unsigned long delta;
33 33
34 delta = now - dev->power.accounting_timestamp; 34 delta = now - dev->power.accounting_timestamp;
35 35
36 if (delta < 0)
37 delta = 0;
38
39 dev->power.accounting_timestamp = now; 36 dev->power.accounting_timestamp = now;
40 37
41 if (dev->power.disable_depth > 0) 38 if (dev->power.disable_depth > 0)
@@ -296,6 +293,9 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
296 * the callback was running then carry it out, otherwise send an idle 293 * the callback was running then carry it out, otherwise send an idle
297 * notification for its parent (if the suspend succeeded and both 294 * notification for its parent (if the suspend succeeded and both
298 * ignore_children of parent->power and irq_safe of dev->power are not set). 295 * ignore_children of parent->power and irq_safe of dev->power are not set).
296 * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
297 * flag is set and the next autosuspend-delay expiration time is in the
298 * future, schedule another autosuspend attempt.
299 * 299 *
300 * This function must be called under dev->power.lock with interrupts disabled. 300 * This function must be called under dev->power.lock with interrupts disabled.
301 */ 301 */
@@ -416,10 +416,21 @@ static int rpm_suspend(struct device *dev, int rpmflags)
416 if (retval) { 416 if (retval) {
417 __update_runtime_status(dev, RPM_ACTIVE); 417 __update_runtime_status(dev, RPM_ACTIVE);
418 dev->power.deferred_resume = false; 418 dev->power.deferred_resume = false;
419 if (retval == -EAGAIN || retval == -EBUSY) 419 if (retval == -EAGAIN || retval == -EBUSY) {
420 dev->power.runtime_error = 0; 420 dev->power.runtime_error = 0;
421 else 421
422 /*
423 * If the callback routine failed an autosuspend, and
424 * if the last_busy time has been updated so that there
425 * is a new autosuspend expiration time, automatically
426 * reschedule another autosuspend.
427 */
428 if ((rpmflags & RPM_AUTO) &&
429 pm_runtime_autosuspend_expiration(dev) != 0)
430 goto repeat;
431 } else {
422 pm_runtime_cancel_pending(dev); 432 pm_runtime_cancel_pending(dev);
433 }
423 wake_up_all(&dev->power.wait_queue); 434 wake_up_all(&dev->power.wait_queue);
424 goto out; 435 goto out;
425 } 436 }
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 528f6318ded1..167ba0af47f5 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -159,7 +159,7 @@ aoeblk_release(struct gendisk *disk, fmode_t mode)
159 return 0; 159 return 0;
160} 160}
161 161
162static int 162static void
163aoeblk_make_request(struct request_queue *q, struct bio *bio) 163aoeblk_make_request(struct request_queue *q, struct bio *bio)
164{ 164{
165 struct sk_buff_head queue; 165 struct sk_buff_head queue;
@@ -172,25 +172,25 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
172 if (bio == NULL) { 172 if (bio == NULL) {
173 printk(KERN_ERR "aoe: bio is NULL\n"); 173 printk(KERN_ERR "aoe: bio is NULL\n");
174 BUG(); 174 BUG();
175 return 0; 175 return;
176 } 176 }
177 d = bio->bi_bdev->bd_disk->private_data; 177 d = bio->bi_bdev->bd_disk->private_data;
178 if (d == NULL) { 178 if (d == NULL) {
179 printk(KERN_ERR "aoe: bd_disk->private_data is NULL\n"); 179 printk(KERN_ERR "aoe: bd_disk->private_data is NULL\n");
180 BUG(); 180 BUG();
181 bio_endio(bio, -ENXIO); 181 bio_endio(bio, -ENXIO);
182 return 0; 182 return;
183 } else if (bio->bi_io_vec == NULL) { 183 } else if (bio->bi_io_vec == NULL) {
184 printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); 184 printk(KERN_ERR "aoe: bi_io_vec is NULL\n");
185 BUG(); 185 BUG();
186 bio_endio(bio, -ENXIO); 186 bio_endio(bio, -ENXIO);
187 return 0; 187 return;
188 } 188 }
189 buf = mempool_alloc(d->bufpool, GFP_NOIO); 189 buf = mempool_alloc(d->bufpool, GFP_NOIO);
190 if (buf == NULL) { 190 if (buf == NULL) {
191 printk(KERN_INFO "aoe: buf allocation failure\n"); 191 printk(KERN_INFO "aoe: buf allocation failure\n");
192 bio_endio(bio, -ENOMEM); 192 bio_endio(bio, -ENOMEM);
193 return 0; 193 return;
194 } 194 }
195 memset(buf, 0, sizeof(*buf)); 195 memset(buf, 0, sizeof(*buf));
196 INIT_LIST_HEAD(&buf->bufs); 196 INIT_LIST_HEAD(&buf->bufs);
@@ -211,7 +211,7 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
211 spin_unlock_irqrestore(&d->lock, flags); 211 spin_unlock_irqrestore(&d->lock, flags);
212 mempool_free(buf, d->bufpool); 212 mempool_free(buf, d->bufpool);
213 bio_endio(bio, -ENXIO); 213 bio_endio(bio, -ENXIO);
214 return 0; 214 return;
215 } 215 }
216 216
217 list_add_tail(&buf->bufs, &d->bufq); 217 list_add_tail(&buf->bufs, &d->bufq);
@@ -222,8 +222,6 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
222 222
223 spin_unlock_irqrestore(&d->lock, flags); 223 spin_unlock_irqrestore(&d->lock, flags);
224 aoenet_xmit(&queue); 224 aoenet_xmit(&queue);
225
226 return 0;
227} 225}
228 226
229static int 227static int
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index dba1c32e1ddf..d22119d49e53 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -323,7 +323,7 @@ out:
323 return err; 323 return err;
324} 324}
325 325
326static int brd_make_request(struct request_queue *q, struct bio *bio) 326static void brd_make_request(struct request_queue *q, struct bio *bio)
327{ 327{
328 struct block_device *bdev = bio->bi_bdev; 328 struct block_device *bdev = bio->bi_bdev;
329 struct brd_device *brd = bdev->bd_disk->private_data; 329 struct brd_device *brd = bdev->bd_disk->private_data;
@@ -359,8 +359,6 @@ static int brd_make_request(struct request_queue *q, struct bio *bio)
359 359
360out: 360out:
361 bio_endio(bio, err); 361 bio_endio(bio, err);
362
363 return 0;
364} 362}
365 363
366#ifdef CONFIG_BLK_DEV_XIP 364#ifdef CONFIG_BLK_DEV_XIP
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 8f4ef656a1af..486f94ef24d4 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -68,6 +68,10 @@ static int cciss_tape_cmds = 6;
68module_param(cciss_tape_cmds, int, 0644); 68module_param(cciss_tape_cmds, int, 0644);
69MODULE_PARM_DESC(cciss_tape_cmds, 69MODULE_PARM_DESC(cciss_tape_cmds,
70 "number of commands to allocate for tape devices (default: 6)"); 70 "number of commands to allocate for tape devices (default: 6)");
71static int cciss_simple_mode;
72module_param(cciss_simple_mode, int, S_IRUGO|S_IWUSR);
73MODULE_PARM_DESC(cciss_simple_mode,
74 "Use 'simple mode' rather than 'performant mode'");
71 75
72static DEFINE_MUTEX(cciss_mutex); 76static DEFINE_MUTEX(cciss_mutex);
73static struct proc_dir_entry *proc_cciss; 77static struct proc_dir_entry *proc_cciss;
@@ -176,6 +180,7 @@ static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol,
176 unsigned int block_size, InquiryData_struct *inq_buff, 180 unsigned int block_size, InquiryData_struct *inq_buff,
177 drive_info_struct *drv); 181 drive_info_struct *drv);
178static void __devinit cciss_interrupt_mode(ctlr_info_t *); 182static void __devinit cciss_interrupt_mode(ctlr_info_t *);
183static int __devinit cciss_enter_simple_mode(struct ctlr_info *h);
179static void start_io(ctlr_info_t *h); 184static void start_io(ctlr_info_t *h);
180static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, 185static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
181 __u8 page_code, unsigned char scsi3addr[], 186 __u8 page_code, unsigned char scsi3addr[],
@@ -388,7 +393,7 @@ static void cciss_seq_show_header(struct seq_file *seq)
388 h->product_name, 393 h->product_name,
389 (unsigned long)h->board_id, 394 (unsigned long)h->board_id,
390 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], 395 h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
391 h->firm_ver[3], (unsigned int)h->intr[PERF_MODE_INT], 396 h->firm_ver[3], (unsigned int)h->intr[h->intr_mode],
392 h->num_luns, 397 h->num_luns,
393 h->Qdepth, h->commands_outstanding, 398 h->Qdepth, h->commands_outstanding,
394 h->maxQsinceinit, h->max_outstanding, h->maxSG); 399 h->maxQsinceinit, h->max_outstanding, h->maxSG);
@@ -636,6 +641,18 @@ static ssize_t host_store_rescan(struct device *dev,
636} 641}
637static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); 642static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
638 643
644static ssize_t host_show_transport_mode(struct device *dev,
645 struct device_attribute *attr,
646 char *buf)
647{
648 struct ctlr_info *h = to_hba(dev);
649
650 return snprintf(buf, 20, "%s\n",
651 h->transMethod & CFGTBL_Trans_Performant ?
652 "performant" : "simple");
653}
654static DEVICE_ATTR(transport_mode, S_IRUGO, host_show_transport_mode, NULL);
655
639static ssize_t dev_show_unique_id(struct device *dev, 656static ssize_t dev_show_unique_id(struct device *dev,
640 struct device_attribute *attr, 657 struct device_attribute *attr,
641 char *buf) 658 char *buf)
@@ -808,6 +825,7 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
808static struct attribute *cciss_host_attrs[] = { 825static struct attribute *cciss_host_attrs[] = {
809 &dev_attr_rescan.attr, 826 &dev_attr_rescan.attr,
810 &dev_attr_resettable.attr, 827 &dev_attr_resettable.attr,
828 &dev_attr_transport_mode.attr,
811 NULL 829 NULL
812}; 830};
813 831
@@ -3984,6 +4002,9 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
3984{ 4002{
3985 __u32 trans_support; 4003 __u32 trans_support;
3986 4004
4005 if (cciss_simple_mode)
4006 return;
4007
3987 dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); 4008 dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n");
3988 /* Attempt to put controller into performant mode if supported */ 4009 /* Attempt to put controller into performant mode if supported */
3989 /* Does board support performant mode? */ 4010 /* Does board support performant mode? */
@@ -4081,7 +4102,7 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *h)
4081default_int_mode: 4102default_int_mode:
4082#endif /* CONFIG_PCI_MSI */ 4103#endif /* CONFIG_PCI_MSI */
4083 /* if we get here we're going to use the default interrupt mode */ 4104 /* if we get here we're going to use the default interrupt mode */
4084 h->intr[PERF_MODE_INT] = h->pdev->irq; 4105 h->intr[h->intr_mode] = h->pdev->irq;
4085 return; 4106 return;
4086} 4107}
4087 4108
@@ -4341,6 +4362,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
4341 } 4362 }
4342 cciss_enable_scsi_prefetch(h); 4363 cciss_enable_scsi_prefetch(h);
4343 cciss_p600_dma_prefetch_quirk(h); 4364 cciss_p600_dma_prefetch_quirk(h);
4365 err = cciss_enter_simple_mode(h);
4366 if (err)
4367 goto err_out_free_res;
4344 cciss_put_controller_into_performant_mode(h); 4368 cciss_put_controller_into_performant_mode(h);
4345 return 0; 4369 return 0;
4346 4370
@@ -4533,6 +4557,13 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev,
4533 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 4557 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
4534 pmcsr |= PCI_D0; 4558 pmcsr |= PCI_D0;
4535 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); 4559 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
4560
4561 /*
4562 * The P600 requires a small delay when changing states.
4563 * Otherwise we may think the board did not reset and we bail.
4564 * This for kdump only and is particular to the P600.
4565 */
4566 msleep(500);
4536 } 4567 }
4537 return 0; 4568 return 0;
4538} 4569}
@@ -4843,20 +4874,20 @@ static int cciss_request_irq(ctlr_info_t *h,
4843 irqreturn_t (*intxhandler)(int, void *)) 4874 irqreturn_t (*intxhandler)(int, void *))
4844{ 4875{
4845 if (h->msix_vector || h->msi_vector) { 4876 if (h->msix_vector || h->msi_vector) {
4846 if (!request_irq(h->intr[PERF_MODE_INT], msixhandler, 4877 if (!request_irq(h->intr[h->intr_mode], msixhandler,
4847 IRQF_DISABLED, h->devname, h)) 4878 IRQF_DISABLED, h->devname, h))
4848 return 0; 4879 return 0;
4849 dev_err(&h->pdev->dev, "Unable to get msi irq %d" 4880 dev_err(&h->pdev->dev, "Unable to get msi irq %d"
4850 " for %s\n", h->intr[PERF_MODE_INT], 4881 " for %s\n", h->intr[h->intr_mode],
4851 h->devname); 4882 h->devname);
4852 return -1; 4883 return -1;
4853 } 4884 }
4854 4885
4855 if (!request_irq(h->intr[PERF_MODE_INT], intxhandler, 4886 if (!request_irq(h->intr[h->intr_mode], intxhandler,
4856 IRQF_DISABLED, h->devname, h)) 4887 IRQF_DISABLED, h->devname, h))
4857 return 0; 4888 return 0;
4858 dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", 4889 dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
4859 h->intr[PERF_MODE_INT], h->devname); 4890 h->intr[h->intr_mode], h->devname);
4860 return -1; 4891 return -1;
4861} 4892}
4862 4893
@@ -4887,7 +4918,7 @@ static void cciss_undo_allocations_after_kdump_soft_reset(ctlr_info_t *h)
4887{ 4918{
4888 int ctlr = h->ctlr; 4919 int ctlr = h->ctlr;
4889 4920
4890 free_irq(h->intr[PERF_MODE_INT], h); 4921 free_irq(h->intr[h->intr_mode], h);
4891#ifdef CONFIG_PCI_MSI 4922#ifdef CONFIG_PCI_MSI
4892 if (h->msix_vector) 4923 if (h->msix_vector)
4893 pci_disable_msix(h->pdev); 4924 pci_disable_msix(h->pdev);
@@ -4953,6 +4984,7 @@ reinit_after_soft_reset:
4953 h = hba[i]; 4984 h = hba[i];
4954 h->pdev = pdev; 4985 h->pdev = pdev;
4955 h->busy_initializing = 1; 4986 h->busy_initializing = 1;
4987 h->intr_mode = cciss_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
4956 INIT_LIST_HEAD(&h->cmpQ); 4988 INIT_LIST_HEAD(&h->cmpQ);
4957 INIT_LIST_HEAD(&h->reqQ); 4989 INIT_LIST_HEAD(&h->reqQ);
4958 mutex_init(&h->busy_shutting_down); 4990 mutex_init(&h->busy_shutting_down);
@@ -5009,7 +5041,7 @@ reinit_after_soft_reset:
5009 5041
5010 dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", 5042 dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
5011 h->devname, pdev->device, pci_name(pdev), 5043 h->devname, pdev->device, pci_name(pdev),
5012 h->intr[PERF_MODE_INT], dac ? "" : " not"); 5044 h->intr[h->intr_mode], dac ? "" : " not");
5013 5045
5014 if (cciss_allocate_cmd_pool(h)) 5046 if (cciss_allocate_cmd_pool(h))
5015 goto clean4; 5047 goto clean4;
@@ -5056,7 +5088,7 @@ reinit_after_soft_reset:
5056 spin_lock_irqsave(&h->lock, flags); 5088 spin_lock_irqsave(&h->lock, flags);
5057 h->access.set_intr_mask(h, CCISS_INTR_OFF); 5089 h->access.set_intr_mask(h, CCISS_INTR_OFF);
5058 spin_unlock_irqrestore(&h->lock, flags); 5090 spin_unlock_irqrestore(&h->lock, flags);
5059 free_irq(h->intr[PERF_MODE_INT], h); 5091 free_irq(h->intr[h->intr_mode], h);
5060 rc = cciss_request_irq(h, cciss_msix_discard_completions, 5092 rc = cciss_request_irq(h, cciss_msix_discard_completions,
5061 cciss_intx_discard_completions); 5093 cciss_intx_discard_completions);
5062 if (rc) { 5094 if (rc) {
@@ -5133,7 +5165,7 @@ clean4:
5133 cciss_free_cmd_pool(h); 5165 cciss_free_cmd_pool(h);
5134 cciss_free_scatterlists(h); 5166 cciss_free_scatterlists(h);
5135 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); 5167 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
5136 free_irq(h->intr[PERF_MODE_INT], h); 5168 free_irq(h->intr[h->intr_mode], h);
5137clean2: 5169clean2:
5138 unregister_blkdev(h->major, h->devname); 5170 unregister_blkdev(h->major, h->devname);
5139clean1: 5171clean1:
@@ -5172,9 +5204,31 @@ static void cciss_shutdown(struct pci_dev *pdev)
5172 if (return_code != IO_OK) 5204 if (return_code != IO_OK)
5173 dev_warn(&h->pdev->dev, "Error flushing cache\n"); 5205 dev_warn(&h->pdev->dev, "Error flushing cache\n");
5174 h->access.set_intr_mask(h, CCISS_INTR_OFF); 5206 h->access.set_intr_mask(h, CCISS_INTR_OFF);
5175 free_irq(h->intr[PERF_MODE_INT], h); 5207 free_irq(h->intr[h->intr_mode], h);
5208}
5209
5210static int __devinit cciss_enter_simple_mode(struct ctlr_info *h)
5211{
5212 u32 trans_support;
5213
5214 trans_support = readl(&(h->cfgtable->TransportSupport));
5215 if (!(trans_support & SIMPLE_MODE))
5216 return -ENOTSUPP;
5217
5218 h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
5219 writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
5220 writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
5221 cciss_wait_for_mode_change_ack(h);
5222 print_cfg_table(h);
5223 if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) {
5224 dev_warn(&h->pdev->dev, "unable to get board into simple mode\n");
5225 return -ENODEV;
5226 }
5227 h->transMethod = CFGTBL_Trans_Simple;
5228 return 0;
5176} 5229}
5177 5230
5231
5178static void __devexit cciss_remove_one(struct pci_dev *pdev) 5232static void __devexit cciss_remove_one(struct pci_dev *pdev)
5179{ 5233{
5180 ctlr_info_t *h; 5234 ctlr_info_t *h;
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index c049548e68b7..7fda30e4a241 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -92,6 +92,7 @@ struct ctlr_info
92 unsigned int intr[4]; 92 unsigned int intr[4];
93 unsigned int msix_vector; 93 unsigned int msix_vector;
94 unsigned int msi_vector; 94 unsigned int msi_vector;
95 int intr_mode;
95 int cciss_max_sectors; 96 int cciss_max_sectors;
96 BYTE cciss_read; 97 BYTE cciss_read;
97 BYTE cciss_write; 98 BYTE cciss_write;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index b2fceb53e809..9125bbeacd4d 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -620,6 +620,7 @@ static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
620 } 620 }
621 vendor_id = pdev->vendor; 621 vendor_id = pdev->vendor;
622 device_id = pdev->device; 622 device_id = pdev->device;
623 revision = pdev->revision;
623 irq = pdev->irq; 624 irq = pdev->irq;
624 625
625 for(i=0; i<6; i++) 626 for(i=0; i<6; i++)
@@ -632,7 +633,6 @@ static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
632 } 633 }
633 634
634 pci_read_config_word(pdev, PCI_COMMAND, &command); 635 pci_read_config_word(pdev, PCI_COMMAND, &command);
635 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
636 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size); 636 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
637 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer); 637 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
638 638
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 1706d60b8c99..9cf20355ceec 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1506,7 +1506,7 @@ extern void drbd_free_mdev(struct drbd_conf *mdev);
1506extern int proc_details; 1506extern int proc_details;
1507 1507
1508/* drbd_req */ 1508/* drbd_req */
1509extern int drbd_make_request(struct request_queue *q, struct bio *bio); 1509extern void drbd_make_request(struct request_queue *q, struct bio *bio);
1510extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); 1510extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req);
1511extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec); 1511extern int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec);
1512extern int is_valid_ar_handle(struct drbd_request *, sector_t); 1512extern int is_valid_ar_handle(struct drbd_request *, sector_t);
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 3424d675b769..4a0f314086e5 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1073,7 +1073,7 @@ static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write)
1073 return 0; 1073 return 0;
1074} 1074}
1075 1075
1076int drbd_make_request(struct request_queue *q, struct bio *bio) 1076void drbd_make_request(struct request_queue *q, struct bio *bio)
1077{ 1077{
1078 unsigned int s_enr, e_enr; 1078 unsigned int s_enr, e_enr;
1079 struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; 1079 struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata;
@@ -1081,7 +1081,7 @@ int drbd_make_request(struct request_queue *q, struct bio *bio)
1081 1081
1082 if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) { 1082 if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) {
1083 bio_endio(bio, -EPERM); 1083 bio_endio(bio, -EPERM);
1084 return 0; 1084 return;
1085 } 1085 }
1086 1086
1087 start_time = jiffies; 1087 start_time = jiffies;
@@ -1100,7 +1100,8 @@ int drbd_make_request(struct request_queue *q, struct bio *bio)
1100 1100
1101 if (likely(s_enr == e_enr)) { 1101 if (likely(s_enr == e_enr)) {
1102 inc_ap_bio(mdev, 1); 1102 inc_ap_bio(mdev, 1);
1103 return drbd_make_request_common(mdev, bio, start_time); 1103 drbd_make_request_common(mdev, bio, start_time);
1104 return;
1104 } 1105 }
1105 1106
1106 /* can this bio be split generically? 1107 /* can this bio be split generically?
@@ -1148,7 +1149,6 @@ int drbd_make_request(struct request_queue *q, struct bio *bio)
1148 1149
1149 bio_pair_release(bp); 1150 bio_pair_release(bp);
1150 } 1151 }
1151 return 0;
1152} 1152}
1153 1153
1154/* This is called by bio_add_page(). With this function we reduce 1154/* This is called by bio_add_page(). With this function we reduce
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 4720c7ade0ae..3d806820280e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -76,6 +76,8 @@
76#include <linux/splice.h> 76#include <linux/splice.h>
77#include <linux/sysfs.h> 77#include <linux/sysfs.h>
78#include <linux/miscdevice.h> 78#include <linux/miscdevice.h>
79#include <linux/falloc.h>
80
79#include <asm/uaccess.h> 81#include <asm/uaccess.h>
80 82
81static DEFINE_IDR(loop_index_idr); 83static DEFINE_IDR(loop_index_idr);
@@ -203,74 +205,6 @@ lo_do_transfer(struct loop_device *lo, int cmd,
203} 205}
204 206
205/** 207/**
206 * do_lo_send_aops - helper for writing data to a loop device
207 *
208 * This is the fast version for backing filesystems which implement the address
209 * space operations write_begin and write_end.
210 */
211static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
212 loff_t pos, struct page *unused)
213{
214 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
215 struct address_space *mapping = file->f_mapping;
216 pgoff_t index;
217 unsigned offset, bv_offs;
218 int len, ret;
219
220 mutex_lock(&mapping->host->i_mutex);
221 index = pos >> PAGE_CACHE_SHIFT;
222 offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
223 bv_offs = bvec->bv_offset;
224 len = bvec->bv_len;
225 while (len > 0) {
226 sector_t IV;
227 unsigned size, copied;
228 int transfer_result;
229 struct page *page;
230 void *fsdata;
231
232 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
233 size = PAGE_CACHE_SIZE - offset;
234 if (size > len)
235 size = len;
236
237 ret = pagecache_write_begin(file, mapping, pos, size, 0,
238 &page, &fsdata);
239 if (ret)
240 goto fail;
241
242 file_update_time(file);
243
244 transfer_result = lo_do_transfer(lo, WRITE, page, offset,
245 bvec->bv_page, bv_offs, size, IV);
246 copied = size;
247 if (unlikely(transfer_result))
248 copied = 0;
249
250 ret = pagecache_write_end(file, mapping, pos, size, copied,
251 page, fsdata);
252 if (ret < 0 || ret != copied)
253 goto fail;
254
255 if (unlikely(transfer_result))
256 goto fail;
257
258 bv_offs += copied;
259 len -= copied;
260 offset = 0;
261 index++;
262 pos += copied;
263 }
264 ret = 0;
265out:
266 mutex_unlock(&mapping->host->i_mutex);
267 return ret;
268fail:
269 ret = -1;
270 goto out;
271}
272
273/**
274 * __do_lo_send_write - helper for writing data to a loop device 208 * __do_lo_send_write - helper for writing data to a loop device
275 * 209 *
276 * This helper just factors out common code between do_lo_send_direct_write() 210 * This helper just factors out common code between do_lo_send_direct_write()
@@ -297,10 +231,8 @@ static int __do_lo_send_write(struct file *file,
297/** 231/**
298 * do_lo_send_direct_write - helper for writing data to a loop device 232 * do_lo_send_direct_write - helper for writing data to a loop device
299 * 233 *
300 * This is the fast, non-transforming version for backing filesystems which do 234 * This is the fast, non-transforming version that does not need double
301 * not implement the address space operations write_begin and write_end. 235 * buffering.
302 * It uses the write file operation which should be present on all writeable
303 * filesystems.
304 */ 236 */
305static int do_lo_send_direct_write(struct loop_device *lo, 237static int do_lo_send_direct_write(struct loop_device *lo,
306 struct bio_vec *bvec, loff_t pos, struct page *page) 238 struct bio_vec *bvec, loff_t pos, struct page *page)
@@ -316,15 +248,9 @@ static int do_lo_send_direct_write(struct loop_device *lo,
316/** 248/**
317 * do_lo_send_write - helper for writing data to a loop device 249 * do_lo_send_write - helper for writing data to a loop device
318 * 250 *
319 * This is the slow, transforming version for filesystems which do not 251 * This is the slow, transforming version that needs to double buffer the
320 * implement the address space operations write_begin and write_end. It 252 * data as it cannot do the transformations in place without having direct
321 * uses the write file operation which should be present on all writeable 253 * access to the destination pages of the backing file.
322 * filesystems.
323 *
324 * Using fops->write is slower than using aops->{prepare,commit}_write in the
325 * transforming case because we need to double buffer the data as we cannot do
326 * the transformations in place as we do not have direct access to the
327 * destination pages of the backing file.
328 */ 254 */
329static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, 255static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,
330 loff_t pos, struct page *page) 256 loff_t pos, struct page *page)
@@ -350,17 +276,16 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
350 struct page *page = NULL; 276 struct page *page = NULL;
351 int i, ret = 0; 277 int i, ret = 0;
352 278
353 do_lo_send = do_lo_send_aops; 279 if (lo->transfer != transfer_none) {
354 if (!(lo->lo_flags & LO_FLAGS_USE_AOPS)) { 280 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
281 if (unlikely(!page))
282 goto fail;
283 kmap(page);
284 do_lo_send = do_lo_send_write;
285 } else {
355 do_lo_send = do_lo_send_direct_write; 286 do_lo_send = do_lo_send_direct_write;
356 if (lo->transfer != transfer_none) {
357 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
358 if (unlikely(!page))
359 goto fail;
360 kmap(page);
361 do_lo_send = do_lo_send_write;
362 }
363 } 287 }
288
364 bio_for_each_segment(bvec, bio, i) { 289 bio_for_each_segment(bvec, bio, i) {
365 ret = do_lo_send(lo, bvec, pos, page); 290 ret = do_lo_send(lo, bvec, pos, page);
366 if (ret < 0) 291 if (ret < 0)
@@ -484,6 +409,29 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
484 } 409 }
485 } 410 }
486 411
412 /*
413 * We use punch hole to reclaim the free space used by the
414 * image a.k.a. discard. However we do support discard if
415 * encryption is enabled, because it may give an attacker
416 * useful information.
417 */
418 if (bio->bi_rw & REQ_DISCARD) {
419 struct file *file = lo->lo_backing_file;
420 int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
421
422 if ((!file->f_op->fallocate) ||
423 lo->lo_encrypt_key_size) {
424 ret = -EOPNOTSUPP;
425 goto out;
426 }
427 ret = file->f_op->fallocate(file, mode, pos,
428 bio->bi_size);
429 if (unlikely(ret && ret != -EINVAL &&
430 ret != -EOPNOTSUPP))
431 ret = -EIO;
432 goto out;
433 }
434
487 ret = lo_send(lo, bio, pos); 435 ret = lo_send(lo, bio, pos);
488 436
489 if ((bio->bi_rw & REQ_FUA) && !ret) { 437 if ((bio->bi_rw & REQ_FUA) && !ret) {
@@ -514,7 +462,7 @@ static struct bio *loop_get_bio(struct loop_device *lo)
514 return bio_list_pop(&lo->lo_bio_list); 462 return bio_list_pop(&lo->lo_bio_list);
515} 463}
516 464
517static int loop_make_request(struct request_queue *q, struct bio *old_bio) 465static void loop_make_request(struct request_queue *q, struct bio *old_bio)
518{ 466{
519 struct loop_device *lo = q->queuedata; 467 struct loop_device *lo = q->queuedata;
520 int rw = bio_rw(old_bio); 468 int rw = bio_rw(old_bio);
@@ -532,12 +480,11 @@ static int loop_make_request(struct request_queue *q, struct bio *old_bio)
532 loop_add_bio(lo, old_bio); 480 loop_add_bio(lo, old_bio);
533 wake_up(&lo->lo_event); 481 wake_up(&lo->lo_event);
534 spin_unlock_irq(&lo->lo_lock); 482 spin_unlock_irq(&lo->lo_lock);
535 return 0; 483 return;
536 484
537out: 485out:
538 spin_unlock_irq(&lo->lo_lock); 486 spin_unlock_irq(&lo->lo_lock);
539 bio_io_error(old_bio); 487 bio_io_error(old_bio);
540 return 0;
541} 488}
542 489
543struct switch_request { 490struct switch_request {
@@ -700,7 +647,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
700 goto out_putf; 647 goto out_putf;
701 648
702 fput(old_file); 649 fput(old_file);
703 if (max_part > 0) 650 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
704 ioctl_by_bdev(bdev, BLKRRPART, 0); 651 ioctl_by_bdev(bdev, BLKRRPART, 0);
705 return 0; 652 return 0;
706 653
@@ -777,16 +724,25 @@ static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
777 return sprintf(buf, "%s\n", autoclear ? "1" : "0"); 724 return sprintf(buf, "%s\n", autoclear ? "1" : "0");
778} 725}
779 726
727static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
728{
729 int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN);
730
731 return sprintf(buf, "%s\n", partscan ? "1" : "0");
732}
733
780LOOP_ATTR_RO(backing_file); 734LOOP_ATTR_RO(backing_file);
781LOOP_ATTR_RO(offset); 735LOOP_ATTR_RO(offset);
782LOOP_ATTR_RO(sizelimit); 736LOOP_ATTR_RO(sizelimit);
783LOOP_ATTR_RO(autoclear); 737LOOP_ATTR_RO(autoclear);
738LOOP_ATTR_RO(partscan);
784 739
785static struct attribute *loop_attrs[] = { 740static struct attribute *loop_attrs[] = {
786 &loop_attr_backing_file.attr, 741 &loop_attr_backing_file.attr,
787 &loop_attr_offset.attr, 742 &loop_attr_offset.attr,
788 &loop_attr_sizelimit.attr, 743 &loop_attr_sizelimit.attr,
789 &loop_attr_autoclear.attr, 744 &loop_attr_autoclear.attr,
745 &loop_attr_partscan.attr,
790 NULL, 746 NULL,
791}; 747};
792 748
@@ -807,6 +763,35 @@ static void loop_sysfs_exit(struct loop_device *lo)
807 &loop_attribute_group); 763 &loop_attribute_group);
808} 764}
809 765
766static void loop_config_discard(struct loop_device *lo)
767{
768 struct file *file = lo->lo_backing_file;
769 struct inode *inode = file->f_mapping->host;
770 struct request_queue *q = lo->lo_queue;
771
772 /*
773 * We use punch hole to reclaim the free space used by the
774 * image a.k.a. discard. However we do support discard if
775 * encryption is enabled, because it may give an attacker
776 * useful information.
777 */
778 if ((!file->f_op->fallocate) ||
779 lo->lo_encrypt_key_size) {
780 q->limits.discard_granularity = 0;
781 q->limits.discard_alignment = 0;
782 q->limits.max_discard_sectors = 0;
783 q->limits.discard_zeroes_data = 0;
784 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
785 return;
786 }
787
788 q->limits.discard_granularity = inode->i_sb->s_blocksize;
789 q->limits.discard_alignment = inode->i_sb->s_blocksize;
790 q->limits.max_discard_sectors = UINT_MAX >> 9;
791 q->limits.discard_zeroes_data = 1;
792 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
793}
794
810static int loop_set_fd(struct loop_device *lo, fmode_t mode, 795static int loop_set_fd(struct loop_device *lo, fmode_t mode,
811 struct block_device *bdev, unsigned int arg) 796 struct block_device *bdev, unsigned int arg)
812{ 797{
@@ -849,35 +834,23 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
849 mapping = file->f_mapping; 834 mapping = file->f_mapping;
850 inode = mapping->host; 835 inode = mapping->host;
851 836
852 if (!(file->f_mode & FMODE_WRITE))
853 lo_flags |= LO_FLAGS_READ_ONLY;
854
855 error = -EINVAL; 837 error = -EINVAL;
856 if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { 838 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
857 const struct address_space_operations *aops = mapping->a_ops; 839 goto out_putf;
858
859 if (aops->write_begin)
860 lo_flags |= LO_FLAGS_USE_AOPS;
861 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
862 lo_flags |= LO_FLAGS_READ_ONLY;
863 840
864 lo_blocksize = S_ISBLK(inode->i_mode) ? 841 if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) ||
865 inode->i_bdev->bd_block_size : PAGE_SIZE; 842 !file->f_op->write)
843 lo_flags |= LO_FLAGS_READ_ONLY;
866 844
867 error = 0; 845 lo_blocksize = S_ISBLK(inode->i_mode) ?
868 } else { 846 inode->i_bdev->bd_block_size : PAGE_SIZE;
869 goto out_putf;
870 }
871 847
848 error = -EFBIG;
872 size = get_loop_size(lo, file); 849 size = get_loop_size(lo, file);
873 850 if ((loff_t)(sector_t)size != size)
874 if ((loff_t)(sector_t)size != size) {
875 error = -EFBIG;
876 goto out_putf; 851 goto out_putf;
877 }
878 852
879 if (!(mode & FMODE_WRITE)) 853 error = 0;
880 lo_flags |= LO_FLAGS_READ_ONLY;
881 854
882 set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); 855 set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
883 856
@@ -919,7 +892,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
919 } 892 }
920 lo->lo_state = Lo_bound; 893 lo->lo_state = Lo_bound;
921 wake_up_process(lo->lo_thread); 894 wake_up_process(lo->lo_thread);
922 if (max_part > 0) 895 if (part_shift)
896 lo->lo_flags |= LO_FLAGS_PARTSCAN;
897 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
923 ioctl_by_bdev(bdev, BLKRRPART, 0); 898 ioctl_by_bdev(bdev, BLKRRPART, 0);
924 return 0; 899 return 0;
925 900
@@ -980,10 +955,11 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
980 return err; 955 return err;
981} 956}
982 957
983static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) 958static int loop_clr_fd(struct loop_device *lo)
984{ 959{
985 struct file *filp = lo->lo_backing_file; 960 struct file *filp = lo->lo_backing_file;
986 gfp_t gfp = lo->old_gfp_mask; 961 gfp_t gfp = lo->old_gfp_mask;
962 struct block_device *bdev = lo->lo_device;
987 963
988 if (lo->lo_state != Lo_bound) 964 if (lo->lo_state != Lo_bound)
989 return -ENXIO; 965 return -ENXIO;
@@ -1012,7 +988,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
1012 lo->lo_offset = 0; 988 lo->lo_offset = 0;
1013 lo->lo_sizelimit = 0; 989 lo->lo_sizelimit = 0;
1014 lo->lo_encrypt_key_size = 0; 990 lo->lo_encrypt_key_size = 0;
1015 lo->lo_flags = 0;
1016 lo->lo_thread = NULL; 991 lo->lo_thread = NULL;
1017 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); 992 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
1018 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); 993 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
@@ -1030,8 +1005,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
1030 lo->lo_state = Lo_unbound; 1005 lo->lo_state = Lo_unbound;
1031 /* This is safe: open() is still holding a reference. */ 1006 /* This is safe: open() is still holding a reference. */
1032 module_put(THIS_MODULE); 1007 module_put(THIS_MODULE);
1033 if (max_part > 0 && bdev) 1008 if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
1034 ioctl_by_bdev(bdev, BLKRRPART, 0); 1009 ioctl_by_bdev(bdev, BLKRRPART, 0);
1010 lo->lo_flags = 0;
1011 if (!part_shift)
1012 lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
1035 mutex_unlock(&lo->lo_ctl_mutex); 1013 mutex_unlock(&lo->lo_ctl_mutex);
1036 /* 1014 /*
1037 * Need not hold lo_ctl_mutex to fput backing file. 1015 * Need not hold lo_ctl_mutex to fput backing file.
@@ -1085,6 +1063,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1085 if (figure_loop_size(lo)) 1063 if (figure_loop_size(lo))
1086 return -EFBIG; 1064 return -EFBIG;
1087 } 1065 }
1066 loop_config_discard(lo);
1088 1067
1089 memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); 1068 memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
1090 memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); 1069 memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
@@ -1100,6 +1079,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1100 (info->lo_flags & LO_FLAGS_AUTOCLEAR)) 1079 (info->lo_flags & LO_FLAGS_AUTOCLEAR))
1101 lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; 1080 lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
1102 1081
1082 if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
1083 !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
1084 lo->lo_flags |= LO_FLAGS_PARTSCAN;
1085 lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
1086 ioctl_by_bdev(lo->lo_device, BLKRRPART, 0);
1087 }
1088
1103 lo->lo_encrypt_key_size = info->lo_encrypt_key_size; 1089 lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
1104 lo->lo_init[0] = info->lo_init[0]; 1090 lo->lo_init[0] = info->lo_init[0];
1105 lo->lo_init[1] = info->lo_init[1]; 1091 lo->lo_init[1] = info->lo_init[1];
@@ -1293,7 +1279,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1293 break; 1279 break;
1294 case LOOP_CLR_FD: 1280 case LOOP_CLR_FD:
1295 /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ 1281 /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
1296 err = loop_clr_fd(lo, bdev); 1282 err = loop_clr_fd(lo);
1297 if (!err) 1283 if (!err)
1298 goto out_unlocked; 1284 goto out_unlocked;
1299 break; 1285 break;
@@ -1513,7 +1499,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
1513 * In autoclear mode, stop the loop thread 1499 * In autoclear mode, stop the loop thread
1514 * and remove configuration after last close. 1500 * and remove configuration after last close.
1515 */ 1501 */
1516 err = loop_clr_fd(lo, NULL); 1502 err = loop_clr_fd(lo);
1517 if (!err) 1503 if (!err)
1518 goto out_unlocked; 1504 goto out_unlocked;
1519 } else { 1505 } else {
@@ -1635,6 +1621,27 @@ static int loop_add(struct loop_device **l, int i)
1635 if (!disk) 1621 if (!disk)
1636 goto out_free_queue; 1622 goto out_free_queue;
1637 1623
1624 /*
1625 * Disable partition scanning by default. The in-kernel partition
1626 * scanning can be requested individually per-device during its
1627 * setup. Userspace can always add and remove partitions from all
1628 * devices. The needed partition minors are allocated from the
1629 * extended minor space, the main loop device numbers will continue
1630 * to match the loop minors, regardless of the number of partitions
1631 * used.
1632 *
1633 * If max_part is given, partition scanning is globally enabled for
1634 * all loop devices. The minors for the main loop devices will be
1635 * multiples of max_part.
1636 *
1637 * Note: Global-for-all-devices, set-only-at-init, read-only module
1638 * parameteters like 'max_loop' and 'max_part' make things needlessly
1639 * complicated, are too static, inflexible and may surprise
1640 * userspace tools. Parameters like this in general should be avoided.
1641 */
1642 if (!part_shift)
1643 disk->flags |= GENHD_FL_NO_PART_SCAN;
1644 disk->flags |= GENHD_FL_EXT_DEVT;
1638 mutex_init(&lo->lo_ctl_mutex); 1645 mutex_init(&lo->lo_ctl_mutex);
1639 lo->lo_number = i; 1646 lo->lo_number = i;
1640 lo->lo_thread = NULL; 1647 lo->lo_thread = NULL;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index f533f3375e24..c3f0ee16594d 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -127,8 +127,7 @@ static void sock_shutdown(struct nbd_device *lo, int lock)
127 if (lock) 127 if (lock)
128 mutex_lock(&lo->tx_lock); 128 mutex_lock(&lo->tx_lock);
129 if (lo->sock) { 129 if (lo->sock) {
130 printk(KERN_WARNING "%s: shutting down socket\n", 130 dev_warn(disk_to_dev(lo->disk), "shutting down socket\n");
131 lo->disk->disk_name);
132 kernel_sock_shutdown(lo->sock, SHUT_RDWR); 131 kernel_sock_shutdown(lo->sock, SHUT_RDWR);
133 lo->sock = NULL; 132 lo->sock = NULL;
134 } 133 }
@@ -158,8 +157,9 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
158 sigset_t blocked, oldset; 157 sigset_t blocked, oldset;
159 158
160 if (unlikely(!sock)) { 159 if (unlikely(!sock)) {
161 printk(KERN_ERR "%s: Attempted %s on closed socket in sock_xmit\n", 160 dev_err(disk_to_dev(lo->disk),
162 lo->disk->disk_name, (send ? "send" : "recv")); 161 "Attempted %s on closed socket in sock_xmit\n",
162 (send ? "send" : "recv"));
163 return -EINVAL; 163 return -EINVAL;
164 } 164 }
165 165
@@ -250,8 +250,8 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
250 result = sock_xmit(lo, 1, &request, sizeof(request), 250 result = sock_xmit(lo, 1, &request, sizeof(request),
251 (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0); 251 (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0);
252 if (result <= 0) { 252 if (result <= 0) {
253 printk(KERN_ERR "%s: Send control failed (result %d)\n", 253 dev_err(disk_to_dev(lo->disk),
254 lo->disk->disk_name, result); 254 "Send control failed (result %d)\n", result);
255 goto error_out; 255 goto error_out;
256 } 256 }
257 257
@@ -270,8 +270,9 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
270 lo->disk->disk_name, req, bvec->bv_len); 270 lo->disk->disk_name, req, bvec->bv_len);
271 result = sock_send_bvec(lo, bvec, flags); 271 result = sock_send_bvec(lo, bvec, flags);
272 if (result <= 0) { 272 if (result <= 0) {
273 printk(KERN_ERR "%s: Send data failed (result %d)\n", 273 dev_err(disk_to_dev(lo->disk),
274 lo->disk->disk_name, result); 274 "Send data failed (result %d)\n",
275 result);
275 goto error_out; 276 goto error_out;
276 } 277 }
277 } 278 }
@@ -328,14 +329,13 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
328 reply.magic = 0; 329 reply.magic = 0;
329 result = sock_xmit(lo, 0, &reply, sizeof(reply), MSG_WAITALL); 330 result = sock_xmit(lo, 0, &reply, sizeof(reply), MSG_WAITALL);
330 if (result <= 0) { 331 if (result <= 0) {
331 printk(KERN_ERR "%s: Receive control failed (result %d)\n", 332 dev_err(disk_to_dev(lo->disk),
332 lo->disk->disk_name, result); 333 "Receive control failed (result %d)\n", result);
333 goto harderror; 334 goto harderror;
334 } 335 }
335 336
336 if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { 337 if (ntohl(reply.magic) != NBD_REPLY_MAGIC) {
337 printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", 338 dev_err(disk_to_dev(lo->disk), "Wrong magic (0x%lx)\n",
338 lo->disk->disk_name,
339 (unsigned long)ntohl(reply.magic)); 339 (unsigned long)ntohl(reply.magic));
340 result = -EPROTO; 340 result = -EPROTO;
341 goto harderror; 341 goto harderror;
@@ -347,15 +347,15 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
347 if (result != -ENOENT) 347 if (result != -ENOENT)
348 goto harderror; 348 goto harderror;
349 349
350 printk(KERN_ERR "%s: Unexpected reply (%p)\n", 350 dev_err(disk_to_dev(lo->disk), "Unexpected reply (%p)\n",
351 lo->disk->disk_name, reply.handle); 351 reply.handle);
352 result = -EBADR; 352 result = -EBADR;
353 goto harderror; 353 goto harderror;
354 } 354 }
355 355
356 if (ntohl(reply.error)) { 356 if (ntohl(reply.error)) {
357 printk(KERN_ERR "%s: Other side returned error (%d)\n", 357 dev_err(disk_to_dev(lo->disk), "Other side returned error (%d)\n",
358 lo->disk->disk_name, ntohl(reply.error)); 358 ntohl(reply.error));
359 req->errors++; 359 req->errors++;
360 return req; 360 return req;
361 } 361 }
@@ -369,8 +369,8 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
369 rq_for_each_segment(bvec, req, iter) { 369 rq_for_each_segment(bvec, req, iter) {
370 result = sock_recv_bvec(lo, bvec); 370 result = sock_recv_bvec(lo, bvec);
371 if (result <= 0) { 371 if (result <= 0) {
372 printk(KERN_ERR "%s: Receive data failed (result %d)\n", 372 dev_err(disk_to_dev(lo->disk), "Receive data failed (result %d)\n",
373 lo->disk->disk_name, result); 373 result);
374 req->errors++; 374 req->errors++;
375 return req; 375 return req;
376 } 376 }
@@ -405,10 +405,10 @@ static int nbd_do_it(struct nbd_device *lo)
405 405
406 BUG_ON(lo->magic != LO_MAGIC); 406 BUG_ON(lo->magic != LO_MAGIC);
407 407
408 lo->pid = current->pid; 408 lo->pid = task_pid_nr(current);
409 ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); 409 ret = device_create_file(disk_to_dev(lo->disk), &pid_attr);
410 if (ret) { 410 if (ret) {
411 printk(KERN_ERR "nbd: sysfs_create_file failed!"); 411 dev_err(disk_to_dev(lo->disk), "device_create_file failed!\n");
412 lo->pid = 0; 412 lo->pid = 0;
413 return ret; 413 return ret;
414 } 414 }
@@ -416,7 +416,7 @@ static int nbd_do_it(struct nbd_device *lo)
416 while ((req = nbd_read_stat(lo)) != NULL) 416 while ((req = nbd_read_stat(lo)) != NULL)
417 nbd_end_request(req); 417 nbd_end_request(req);
418 418
419 sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); 419 device_remove_file(disk_to_dev(lo->disk), &pid_attr);
420 lo->pid = 0; 420 lo->pid = 0;
421 return 0; 421 return 0;
422} 422}
@@ -457,8 +457,8 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req)
457 if (rq_data_dir(req) == WRITE) { 457 if (rq_data_dir(req) == WRITE) {
458 nbd_cmd(req) = NBD_CMD_WRITE; 458 nbd_cmd(req) = NBD_CMD_WRITE;
459 if (lo->flags & NBD_READ_ONLY) { 459 if (lo->flags & NBD_READ_ONLY) {
460 printk(KERN_ERR "%s: Write on read-only\n", 460 dev_err(disk_to_dev(lo->disk),
461 lo->disk->disk_name); 461 "Write on read-only\n");
462 goto error_out; 462 goto error_out;
463 } 463 }
464 } 464 }
@@ -468,16 +468,15 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req)
468 mutex_lock(&lo->tx_lock); 468 mutex_lock(&lo->tx_lock);
469 if (unlikely(!lo->sock)) { 469 if (unlikely(!lo->sock)) {
470 mutex_unlock(&lo->tx_lock); 470 mutex_unlock(&lo->tx_lock);
471 printk(KERN_ERR "%s: Attempted send on closed socket\n", 471 dev_err(disk_to_dev(lo->disk),
472 lo->disk->disk_name); 472 "Attempted send on closed socket\n");
473 goto error_out; 473 goto error_out;
474 } 474 }
475 475
476 lo->active_req = req; 476 lo->active_req = req;
477 477
478 if (nbd_send_req(lo, req) != 0) { 478 if (nbd_send_req(lo, req) != 0) {
479 printk(KERN_ERR "%s: Request send failed\n", 479 dev_err(disk_to_dev(lo->disk), "Request send failed\n");
480 lo->disk->disk_name);
481 req->errors++; 480 req->errors++;
482 nbd_end_request(req); 481 nbd_end_request(req);
483 } else { 482 } else {
@@ -549,8 +548,8 @@ static void do_nbd_request(struct request_queue *q)
549 BUG_ON(lo->magic != LO_MAGIC); 548 BUG_ON(lo->magic != LO_MAGIC);
550 549
551 if (unlikely(!lo->sock)) { 550 if (unlikely(!lo->sock)) {
552 printk(KERN_ERR "%s: Attempted send on closed socket\n", 551 dev_err(disk_to_dev(lo->disk),
553 lo->disk->disk_name); 552 "Attempted send on closed socket\n");
554 req->errors++; 553 req->errors++;
555 nbd_end_request(req); 554 nbd_end_request(req);
556 spin_lock_irq(q->queue_lock); 555 spin_lock_irq(q->queue_lock);
@@ -576,7 +575,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
576 case NBD_DISCONNECT: { 575 case NBD_DISCONNECT: {
577 struct request sreq; 576 struct request sreq;
578 577
579 printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name); 578 dev_info(disk_to_dev(lo->disk), "NBD_DISCONNECT\n");
580 579
581 blk_rq_init(NULL, &sreq); 580 blk_rq_init(NULL, &sreq);
582 sreq.cmd_type = REQ_TYPE_SPECIAL; 581 sreq.cmd_type = REQ_TYPE_SPECIAL;
@@ -674,7 +673,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
674 file = lo->file; 673 file = lo->file;
675 lo->file = NULL; 674 lo->file = NULL;
676 nbd_clear_que(lo); 675 nbd_clear_que(lo);
677 printk(KERN_WARNING "%s: queue cleared\n", lo->disk->disk_name); 676 dev_warn(disk_to_dev(lo->disk), "queue cleared\n");
678 if (file) 677 if (file)
679 fput(file); 678 fput(file);
680 lo->bytesize = 0; 679 lo->bytesize = 0;
@@ -694,8 +693,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
694 return 0; 693 return 0;
695 694
696 case NBD_PRINT_DEBUG: 695 case NBD_PRINT_DEBUG:
697 printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n", 696 dev_info(disk_to_dev(lo->disk),
698 bdev->bd_disk->disk_name, 697 "next = %p, prev = %p, head = %p\n",
699 lo->queue_head.next, lo->queue_head.prev, 698 lo->queue_head.next, lo->queue_head.prev,
700 &lo->queue_head); 699 &lo->queue_head);
701 return 0; 700 return 0;
@@ -745,7 +744,7 @@ static int __init nbd_init(void)
745 BUILD_BUG_ON(sizeof(struct nbd_request) != 28); 744 BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
746 745
747 if (max_part < 0) { 746 if (max_part < 0) {
748 printk(KERN_CRIT "nbd: max_part must be >= 0\n"); 747 printk(KERN_ERR "nbd: max_part must be >= 0\n");
749 return -EINVAL; 748 return -EINVAL;
750 } 749 }
751 750
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index e133f094ab08..a63b0a2b7805 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2444,7 +2444,7 @@ static void pkt_end_io_read_cloned(struct bio *bio, int err)
2444 pkt_bio_finished(pd); 2444 pkt_bio_finished(pd);
2445} 2445}
2446 2446
2447static int pkt_make_request(struct request_queue *q, struct bio *bio) 2447static void pkt_make_request(struct request_queue *q, struct bio *bio)
2448{ 2448{
2449 struct pktcdvd_device *pd; 2449 struct pktcdvd_device *pd;
2450 char b[BDEVNAME_SIZE]; 2450 char b[BDEVNAME_SIZE];
@@ -2473,7 +2473,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
2473 cloned_bio->bi_end_io = pkt_end_io_read_cloned; 2473 cloned_bio->bi_end_io = pkt_end_io_read_cloned;
2474 pd->stats.secs_r += bio->bi_size >> 9; 2474 pd->stats.secs_r += bio->bi_size >> 9;
2475 pkt_queue_bio(pd, cloned_bio); 2475 pkt_queue_bio(pd, cloned_bio);
2476 return 0; 2476 return;
2477 } 2477 }
2478 2478
2479 if (!test_bit(PACKET_WRITABLE, &pd->flags)) { 2479 if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
@@ -2509,7 +2509,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
2509 pkt_make_request(q, &bp->bio1); 2509 pkt_make_request(q, &bp->bio1);
2510 pkt_make_request(q, &bp->bio2); 2510 pkt_make_request(q, &bp->bio2);
2511 bio_pair_release(bp); 2511 bio_pair_release(bp);
2512 return 0; 2512 return;
2513 } 2513 }
2514 } 2514 }
2515 2515
@@ -2533,7 +2533,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
2533 } 2533 }
2534 spin_unlock(&pkt->lock); 2534 spin_unlock(&pkt->lock);
2535 spin_unlock(&pd->cdrw.active_list_lock); 2535 spin_unlock(&pd->cdrw.active_list_lock);
2536 return 0; 2536 return;
2537 } else { 2537 } else {
2538 blocked_bio = 1; 2538 blocked_bio = 1;
2539 } 2539 }
@@ -2584,10 +2584,9 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
2584 */ 2584 */
2585 wake_up(&pd->wqueue); 2585 wake_up(&pd->wqueue);
2586 } 2586 }
2587 return 0; 2587 return;
2588end_io: 2588end_io:
2589 bio_io_error(bio); 2589 bio_io_error(bio);
2590 return 0;
2591} 2590}
2592 2591
2593 2592
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index b3bdb8af89cf..7fad7af87eb2 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -596,7 +596,7 @@ out:
596 return next; 596 return next;
597} 597}
598 598
599static int ps3vram_make_request(struct request_queue *q, struct bio *bio) 599static void ps3vram_make_request(struct request_queue *q, struct bio *bio)
600{ 600{
601 struct ps3_system_bus_device *dev = q->queuedata; 601 struct ps3_system_bus_device *dev = q->queuedata;
602 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); 602 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
@@ -610,13 +610,11 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
610 spin_unlock_irq(&priv->lock); 610 spin_unlock_irq(&priv->lock);
611 611
612 if (busy) 612 if (busy)
613 return 0; 613 return;
614 614
615 do { 615 do {
616 bio = ps3vram_do_bio(dev, bio); 616 bio = ps3vram_do_bio(dev, bio);
617 } while (bio); 617 } while (bio);
618
619 return 0;
620} 618}
621 619
622static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) 620static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 031ca720d926..aa2712060bfb 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -513,7 +513,7 @@ static void process_page(unsigned long data)
513 } 513 }
514} 514}
515 515
516static int mm_make_request(struct request_queue *q, struct bio *bio) 516static void mm_make_request(struct request_queue *q, struct bio *bio)
517{ 517{
518 struct cardinfo *card = q->queuedata; 518 struct cardinfo *card = q->queuedata;
519 pr_debug("mm_make_request %llu %u\n", 519 pr_debug("mm_make_request %llu %u\n",
@@ -525,7 +525,7 @@ static int mm_make_request(struct request_queue *q, struct bio *bio)
525 card->biotail = &bio->bi_next; 525 card->biotail = &bio->bi_next;
526 spin_unlock_irq(&card->lock); 526 spin_unlock_irq(&card->lock);
527 527
528 return 0; 528 return;
529} 529}
530 530
531static irqreturn_t mm_interrupt(int irq, void *__card) 531static irqreturn_t mm_interrupt(int irq, void *__card)
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 1540792b1e54..15ec4db194d1 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -39,6 +39,9 @@
39#include <linux/list.h> 39#include <linux/list.h>
40#include <linux/delay.h> 40#include <linux/delay.h>
41#include <linux/freezer.h> 41#include <linux/freezer.h>
42#include <linux/loop.h>
43#include <linux/falloc.h>
44#include <linux/fs.h>
42 45
43#include <xen/events.h> 46#include <xen/events.h>
44#include <xen/page.h> 47#include <xen/page.h>
@@ -258,13 +261,16 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
258 261
259static void print_stats(struct xen_blkif *blkif) 262static void print_stats(struct xen_blkif *blkif)
260{ 263{
261 pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d\n", 264 pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d"
265 " | ds %4d\n",
262 current->comm, blkif->st_oo_req, 266 current->comm, blkif->st_oo_req,
263 blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req); 267 blkif->st_rd_req, blkif->st_wr_req,
268 blkif->st_f_req, blkif->st_ds_req);
264 blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); 269 blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
265 blkif->st_rd_req = 0; 270 blkif->st_rd_req = 0;
266 blkif->st_wr_req = 0; 271 blkif->st_wr_req = 0;
267 blkif->st_oo_req = 0; 272 blkif->st_oo_req = 0;
273 blkif->st_ds_req = 0;
268} 274}
269 275
270int xen_blkif_schedule(void *arg) 276int xen_blkif_schedule(void *arg)
@@ -410,6 +416,59 @@ static int xen_blkbk_map(struct blkif_request *req,
410 return ret; 416 return ret;
411} 417}
412 418
419static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req)
420{
421 int err = 0;
422 int status = BLKIF_RSP_OKAY;
423 struct block_device *bdev = blkif->vbd.bdev;
424
425 if (blkif->blk_backend_type == BLKIF_BACKEND_PHY)
426 /* just forward the discard request */
427 err = blkdev_issue_discard(bdev,
428 req->u.discard.sector_number,
429 req->u.discard.nr_sectors,
430 GFP_KERNEL, 0);
431 else if (blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
432 /* punch a hole in the backing file */
433 struct loop_device *lo = bdev->bd_disk->private_data;
434 struct file *file = lo->lo_backing_file;
435
436 if (file->f_op->fallocate)
437 err = file->f_op->fallocate(file,
438 FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
439 req->u.discard.sector_number << 9,
440 req->u.discard.nr_sectors << 9);
441 else
442 err = -EOPNOTSUPP;
443 } else
444 err = -EOPNOTSUPP;
445
446 if (err == -EOPNOTSUPP) {
447 pr_debug(DRV_PFX "discard op failed, not supported\n");
448 status = BLKIF_RSP_EOPNOTSUPP;
449 } else if (err)
450 status = BLKIF_RSP_ERROR;
451
452 make_response(blkif, req->id, req->operation, status);
453}
454
455static void xen_blk_drain_io(struct xen_blkif *blkif)
456{
457 atomic_set(&blkif->drain, 1);
458 do {
459 /* The initial value is one, and one refcnt taken at the
460 * start of the xen_blkif_schedule thread. */
461 if (atomic_read(&blkif->refcnt) <= 2)
462 break;
463 wait_for_completion_interruptible_timeout(
464 &blkif->drain_complete, HZ);
465
466 if (!atomic_read(&blkif->drain))
467 break;
468 } while (!kthread_should_stop());
469 atomic_set(&blkif->drain, 0);
470}
471
413/* 472/*
414 * Completion callback on the bio's. Called as bh->b_end_io() 473 * Completion callback on the bio's. Called as bh->b_end_io()
415 */ 474 */
@@ -422,6 +481,11 @@ static void __end_block_io_op(struct pending_req *pending_req, int error)
422 pr_debug(DRV_PFX "flush diskcache op failed, not supported\n"); 481 pr_debug(DRV_PFX "flush diskcache op failed, not supported\n");
423 xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0); 482 xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0);
424 pending_req->status = BLKIF_RSP_EOPNOTSUPP; 483 pending_req->status = BLKIF_RSP_EOPNOTSUPP;
484 } else if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) &&
485 (error == -EOPNOTSUPP)) {
486 pr_debug(DRV_PFX "write barrier op failed, not supported\n");
487 xen_blkbk_barrier(XBT_NIL, pending_req->blkif->be, 0);
488 pending_req->status = BLKIF_RSP_EOPNOTSUPP;
425 } else if (error) { 489 } else if (error) {
426 pr_debug(DRV_PFX "Buffer not up-to-date at end of operation," 490 pr_debug(DRV_PFX "Buffer not up-to-date at end of operation,"
427 " error=%d\n", error); 491 " error=%d\n", error);
@@ -438,6 +502,10 @@ static void __end_block_io_op(struct pending_req *pending_req, int error)
438 make_response(pending_req->blkif, pending_req->id, 502 make_response(pending_req->blkif, pending_req->id,
439 pending_req->operation, pending_req->status); 503 pending_req->operation, pending_req->status);
440 xen_blkif_put(pending_req->blkif); 504 xen_blkif_put(pending_req->blkif);
505 if (atomic_read(&pending_req->blkif->refcnt) <= 2) {
506 if (atomic_read(&pending_req->blkif->drain))
507 complete(&pending_req->blkif->drain_complete);
508 }
441 free_req(pending_req); 509 free_req(pending_req);
442 } 510 }
443} 511}
@@ -532,7 +600,6 @@ do_block_io_op(struct xen_blkif *blkif)
532 600
533 return more_to_do; 601 return more_to_do;
534} 602}
535
536/* 603/*
537 * Transmutation of the 'struct blkif_request' to a proper 'struct bio' 604 * Transmutation of the 'struct blkif_request' to a proper 'struct bio'
538 * and call the 'submit_bio' to pass it to the underlying storage. 605 * and call the 'submit_bio' to pass it to the underlying storage.
@@ -549,6 +616,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
549 int i, nbio = 0; 616 int i, nbio = 0;
550 int operation; 617 int operation;
551 struct blk_plug plug; 618 struct blk_plug plug;
619 bool drain = false;
552 620
553 switch (req->operation) { 621 switch (req->operation) {
554 case BLKIF_OP_READ: 622 case BLKIF_OP_READ:
@@ -559,11 +627,16 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
559 blkif->st_wr_req++; 627 blkif->st_wr_req++;
560 operation = WRITE_ODIRECT; 628 operation = WRITE_ODIRECT;
561 break; 629 break;
630 case BLKIF_OP_WRITE_BARRIER:
631 drain = true;
562 case BLKIF_OP_FLUSH_DISKCACHE: 632 case BLKIF_OP_FLUSH_DISKCACHE:
563 blkif->st_f_req++; 633 blkif->st_f_req++;
564 operation = WRITE_FLUSH; 634 operation = WRITE_FLUSH;
565 break; 635 break;
566 case BLKIF_OP_WRITE_BARRIER: 636 case BLKIF_OP_DISCARD:
637 blkif->st_ds_req++;
638 operation = REQ_DISCARD;
639 break;
567 default: 640 default:
568 operation = 0; /* make gcc happy */ 641 operation = 0; /* make gcc happy */
569 goto fail_response; 642 goto fail_response;
@@ -572,7 +645,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
572 645
573 /* Check that the number of segments is sane. */ 646 /* Check that the number of segments is sane. */
574 nseg = req->nr_segments; 647 nseg = req->nr_segments;
575 if (unlikely(nseg == 0 && operation != WRITE_FLUSH) || 648 if (unlikely(nseg == 0 && operation != WRITE_FLUSH &&
649 operation != REQ_DISCARD) ||
576 unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { 650 unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
577 pr_debug(DRV_PFX "Bad number of segments in request (%d)\n", 651 pr_debug(DRV_PFX "Bad number of segments in request (%d)\n",
578 nseg); 652 nseg);
@@ -621,16 +695,25 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
621 } 695 }
622 } 696 }
623 697
698 /* Wait on all outstanding I/O's and once that has been completed
699 * issue the WRITE_FLUSH.
700 */
701 if (drain)
702 xen_blk_drain_io(pending_req->blkif);
703
624 /* 704 /*
625 * If we have failed at this point, we need to undo the M2P override, 705 * If we have failed at this point, we need to undo the M2P override,
626 * set gnttab_set_unmap_op on all of the grant references and perform 706 * set gnttab_set_unmap_op on all of the grant references and perform
627 * the hypercall to unmap the grants - that is all done in 707 * the hypercall to unmap the grants - that is all done in
628 * xen_blkbk_unmap. 708 * xen_blkbk_unmap.
629 */ 709 */
630 if (xen_blkbk_map(req, pending_req, seg)) 710 if (operation != REQ_DISCARD && xen_blkbk_map(req, pending_req, seg))
631 goto fail_flush; 711 goto fail_flush;
632 712
633 /* This corresponding xen_blkif_put is done in __end_block_io_op */ 713 /*
714 * This corresponding xen_blkif_put is done in __end_block_io_op, or
715 * below (in "!bio") if we are handling a BLKIF_OP_DISCARD.
716 */
634 xen_blkif_get(blkif); 717 xen_blkif_get(blkif);
635 718
636 for (i = 0; i < nseg; i++) { 719 for (i = 0; i < nseg; i++) {
@@ -654,18 +737,25 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
654 preq.sector_number += seg[i].nsec; 737 preq.sector_number += seg[i].nsec;
655 } 738 }
656 739
657 /* This will be hit if the operation was a flush. */ 740 /* This will be hit if the operation was a flush or discard. */
658 if (!bio) { 741 if (!bio) {
659 BUG_ON(operation != WRITE_FLUSH); 742 BUG_ON(operation != WRITE_FLUSH && operation != REQ_DISCARD);
660 743
661 bio = bio_alloc(GFP_KERNEL, 0); 744 if (operation == WRITE_FLUSH) {
662 if (unlikely(bio == NULL)) 745 bio = bio_alloc(GFP_KERNEL, 0);
663 goto fail_put_bio; 746 if (unlikely(bio == NULL))
747 goto fail_put_bio;
664 748
665 biolist[nbio++] = bio; 749 biolist[nbio++] = bio;
666 bio->bi_bdev = preq.bdev; 750 bio->bi_bdev = preq.bdev;
667 bio->bi_private = pending_req; 751 bio->bi_private = pending_req;
668 bio->bi_end_io = end_block_io_op; 752 bio->bi_end_io = end_block_io_op;
753 } else if (operation == REQ_DISCARD) {
754 xen_blk_discard(blkif, req);
755 xen_blkif_put(blkif);
756 free_req(pending_req);
757 return 0;
758 }
669 } 759 }
670 760
671 /* 761 /*
@@ -685,7 +775,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
685 775
686 if (operation == READ) 776 if (operation == READ)
687 blkif->st_rd_sect += preq.nr_sects; 777 blkif->st_rd_sect += preq.nr_sects;
688 else if (operation == WRITE || operation == WRITE_FLUSH) 778 else if (operation & WRITE)
689 blkif->st_wr_sect += preq.nr_sects; 779 blkif->st_wr_sect += preq.nr_sects;
690 780
691 return 0; 781 return 0;
@@ -765,9 +855,9 @@ static int __init xen_blkif_init(void)
765 855
766 mmap_pages = xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; 856 mmap_pages = xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
767 857
768 blkbk->pending_reqs = kmalloc(sizeof(blkbk->pending_reqs[0]) * 858 blkbk->pending_reqs = kzalloc(sizeof(blkbk->pending_reqs[0]) *
769 xen_blkif_reqs, GFP_KERNEL); 859 xen_blkif_reqs, GFP_KERNEL);
770 blkbk->pending_grant_handles = kzalloc(sizeof(blkbk->pending_grant_handles[0]) * 860 blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) *
771 mmap_pages, GFP_KERNEL); 861 mmap_pages, GFP_KERNEL);
772 blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) * 862 blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) *
773 mmap_pages, GFP_KERNEL); 863 mmap_pages, GFP_KERNEL);
@@ -790,8 +880,6 @@ static int __init xen_blkif_init(void)
790 if (rc) 880 if (rc)
791 goto failed_init; 881 goto failed_init;
792 882
793 memset(blkbk->pending_reqs, 0, sizeof(blkbk->pending_reqs));
794
795 INIT_LIST_HEAD(&blkbk->pending_free); 883 INIT_LIST_HEAD(&blkbk->pending_free);
796 spin_lock_init(&blkbk->pending_free_lock); 884 spin_lock_init(&blkbk->pending_free_lock);
797 init_waitqueue_head(&blkbk->pending_free_wq); 885 init_waitqueue_head(&blkbk->pending_free_wq);
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index c4bd34063ecc..de09f525d6c1 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -62,13 +62,26 @@ struct blkif_common_response {
62 62
63/* i386 protocol version */ 63/* i386 protocol version */
64#pragma pack(push, 4) 64#pragma pack(push, 4)
65
66struct blkif_x86_32_request_rw {
67 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
68 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
69};
70
71struct blkif_x86_32_request_discard {
72 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
73 uint64_t nr_sectors;
74};
75
65struct blkif_x86_32_request { 76struct blkif_x86_32_request {
66 uint8_t operation; /* BLKIF_OP_??? */ 77 uint8_t operation; /* BLKIF_OP_??? */
67 uint8_t nr_segments; /* number of segments */ 78 uint8_t nr_segments; /* number of segments */
68 blkif_vdev_t handle; /* only for read/write requests */ 79 blkif_vdev_t handle; /* only for read/write requests */
69 uint64_t id; /* private guest value, echoed in resp */ 80 uint64_t id; /* private guest value, echoed in resp */
70 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ 81 union {
71 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 82 struct blkif_x86_32_request_rw rw;
83 struct blkif_x86_32_request_discard discard;
84 } u;
72}; 85};
73struct blkif_x86_32_response { 86struct blkif_x86_32_response {
74 uint64_t id; /* copied from request */ 87 uint64_t id; /* copied from request */
@@ -78,13 +91,26 @@ struct blkif_x86_32_response {
78#pragma pack(pop) 91#pragma pack(pop)
79 92
80/* x86_64 protocol version */ 93/* x86_64 protocol version */
94
95struct blkif_x86_64_request_rw {
96 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
97 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
98};
99
100struct blkif_x86_64_request_discard {
101 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
102 uint64_t nr_sectors;
103};
104
81struct blkif_x86_64_request { 105struct blkif_x86_64_request {
82 uint8_t operation; /* BLKIF_OP_??? */ 106 uint8_t operation; /* BLKIF_OP_??? */
83 uint8_t nr_segments; /* number of segments */ 107 uint8_t nr_segments; /* number of segments */
84 blkif_vdev_t handle; /* only for read/write requests */ 108 blkif_vdev_t handle; /* only for read/write requests */
85 uint64_t __attribute__((__aligned__(8))) id; 109 uint64_t __attribute__((__aligned__(8))) id;
86 blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ 110 union {
87 struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 111 struct blkif_x86_64_request_rw rw;
112 struct blkif_x86_64_request_discard discard;
113 } u;
88}; 114};
89struct blkif_x86_64_response { 115struct blkif_x86_64_response {
90 uint64_t __attribute__((__aligned__(8))) id; 116 uint64_t __attribute__((__aligned__(8))) id;
@@ -112,6 +138,11 @@ enum blkif_protocol {
112 BLKIF_PROTOCOL_X86_64 = 3, 138 BLKIF_PROTOCOL_X86_64 = 3,
113}; 139};
114 140
141enum blkif_backend_type {
142 BLKIF_BACKEND_PHY = 1,
143 BLKIF_BACKEND_FILE = 2,
144};
145
115struct xen_vbd { 146struct xen_vbd {
116 /* What the domain refers to this vbd as. */ 147 /* What the domain refers to this vbd as. */
117 blkif_vdev_t handle; 148 blkif_vdev_t handle;
@@ -137,6 +168,7 @@ struct xen_blkif {
137 unsigned int irq; 168 unsigned int irq;
138 /* Comms information. */ 169 /* Comms information. */
139 enum blkif_protocol blk_protocol; 170 enum blkif_protocol blk_protocol;
171 enum blkif_backend_type blk_backend_type;
140 union blkif_back_rings blk_rings; 172 union blkif_back_rings blk_rings;
141 struct vm_struct *blk_ring_area; 173 struct vm_struct *blk_ring_area;
142 /* The VBD attached to this interface. */ 174 /* The VBD attached to this interface. */
@@ -148,6 +180,9 @@ struct xen_blkif {
148 atomic_t refcnt; 180 atomic_t refcnt;
149 181
150 wait_queue_head_t wq; 182 wait_queue_head_t wq;
183 /* for barrier (drain) requests */
184 struct completion drain_complete;
185 atomic_t drain;
151 /* One thread per one blkif. */ 186 /* One thread per one blkif. */
152 struct task_struct *xenblkd; 187 struct task_struct *xenblkd;
153 unsigned int waiting_reqs; 188 unsigned int waiting_reqs;
@@ -158,6 +193,7 @@ struct xen_blkif {
158 int st_wr_req; 193 int st_wr_req;
159 int st_oo_req; 194 int st_oo_req;
160 int st_f_req; 195 int st_f_req;
196 int st_ds_req;
161 int st_rd_sect; 197 int st_rd_sect;
162 int st_wr_sect; 198 int st_wr_sect;
163 199
@@ -181,7 +217,7 @@ struct xen_blkif {
181 217
182struct phys_req { 218struct phys_req {
183 unsigned short dev; 219 unsigned short dev;
184 unsigned short nr_sects; 220 blkif_sector_t nr_sects;
185 struct block_device *bdev; 221 struct block_device *bdev;
186 blkif_sector_t sector_number; 222 blkif_sector_t sector_number;
187}; 223};
@@ -195,6 +231,8 @@ int xen_blkif_schedule(void *arg);
195int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, 231int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
196 struct backend_info *be, int state); 232 struct backend_info *be, int state);
197 233
234int xen_blkbk_barrier(struct xenbus_transaction xbt,
235 struct backend_info *be, int state);
198struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); 236struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
199 237
200static inline void blkif_get_x86_32_req(struct blkif_request *dst, 238static inline void blkif_get_x86_32_req(struct blkif_request *dst,
@@ -205,12 +243,25 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
205 dst->nr_segments = src->nr_segments; 243 dst->nr_segments = src->nr_segments;
206 dst->handle = src->handle; 244 dst->handle = src->handle;
207 dst->id = src->id; 245 dst->id = src->id;
208 dst->u.rw.sector_number = src->sector_number; 246 switch (src->operation) {
209 barrier(); 247 case BLKIF_OP_READ:
210 if (n > dst->nr_segments) 248 case BLKIF_OP_WRITE:
211 n = dst->nr_segments; 249 case BLKIF_OP_WRITE_BARRIER:
212 for (i = 0; i < n; i++) 250 case BLKIF_OP_FLUSH_DISKCACHE:
213 dst->u.rw.seg[i] = src->seg[i]; 251 dst->u.rw.sector_number = src->u.rw.sector_number;
252 barrier();
253 if (n > dst->nr_segments)
254 n = dst->nr_segments;
255 for (i = 0; i < n; i++)
256 dst->u.rw.seg[i] = src->u.rw.seg[i];
257 break;
258 case BLKIF_OP_DISCARD:
259 dst->u.discard.sector_number = src->u.discard.sector_number;
260 dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
261 break;
262 default:
263 break;
264 }
214} 265}
215 266
216static inline void blkif_get_x86_64_req(struct blkif_request *dst, 267static inline void blkif_get_x86_64_req(struct blkif_request *dst,
@@ -221,12 +272,25 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
221 dst->nr_segments = src->nr_segments; 272 dst->nr_segments = src->nr_segments;
222 dst->handle = src->handle; 273 dst->handle = src->handle;
223 dst->id = src->id; 274 dst->id = src->id;
224 dst->u.rw.sector_number = src->sector_number; 275 switch (src->operation) {
225 barrier(); 276 case BLKIF_OP_READ:
226 if (n > dst->nr_segments) 277 case BLKIF_OP_WRITE:
227 n = dst->nr_segments; 278 case BLKIF_OP_WRITE_BARRIER:
228 for (i = 0; i < n; i++) 279 case BLKIF_OP_FLUSH_DISKCACHE:
229 dst->u.rw.seg[i] = src->seg[i]; 280 dst->u.rw.sector_number = src->u.rw.sector_number;
281 barrier();
282 if (n > dst->nr_segments)
283 n = dst->nr_segments;
284 for (i = 0; i < n; i++)
285 dst->u.rw.seg[i] = src->u.rw.seg[i];
286 break;
287 case BLKIF_OP_DISCARD:
288 dst->u.discard.sector_number = src->u.discard.sector_number;
289 dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
290 break;
291 default:
292 break;
293 }
230} 294}
231 295
232#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */ 296#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 5fd2010f7d2b..2c008afe63d9 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -114,6 +114,8 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
114 spin_lock_init(&blkif->blk_ring_lock); 114 spin_lock_init(&blkif->blk_ring_lock);
115 atomic_set(&blkif->refcnt, 1); 115 atomic_set(&blkif->refcnt, 1);
116 init_waitqueue_head(&blkif->wq); 116 init_waitqueue_head(&blkif->wq);
117 init_completion(&blkif->drain_complete);
118 atomic_set(&blkif->drain, 0);
117 blkif->st_print = jiffies; 119 blkif->st_print = jiffies;
118 init_waitqueue_head(&blkif->waiting_to_free); 120 init_waitqueue_head(&blkif->waiting_to_free);
119 121
@@ -272,6 +274,7 @@ VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
272VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); 274VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
273VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); 275VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
274VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req); 276VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req);
277VBD_SHOW(ds_req, "%d\n", be->blkif->st_ds_req);
275VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect); 278VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
276VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect); 279VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
277 280
@@ -280,6 +283,7 @@ static struct attribute *xen_vbdstat_attrs[] = {
280 &dev_attr_rd_req.attr, 283 &dev_attr_rd_req.attr,
281 &dev_attr_wr_req.attr, 284 &dev_attr_wr_req.attr,
282 &dev_attr_f_req.attr, 285 &dev_attr_f_req.attr,
286 &dev_attr_ds_req.attr,
283 &dev_attr_rd_sect.attr, 287 &dev_attr_rd_sect.attr,
284 &dev_attr_wr_sect.attr, 288 &dev_attr_wr_sect.attr,
285 NULL 289 NULL
@@ -419,6 +423,73 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
419 return err; 423 return err;
420} 424}
421 425
426int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
427{
428 struct xenbus_device *dev = be->dev;
429 struct xen_blkif *blkif = be->blkif;
430 char *type;
431 int err;
432 int state = 0;
433
434 type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL);
435 if (!IS_ERR(type)) {
436 if (strncmp(type, "file", 4) == 0) {
437 state = 1;
438 blkif->blk_backend_type = BLKIF_BACKEND_FILE;
439 }
440 if (strncmp(type, "phy", 3) == 0) {
441 struct block_device *bdev = be->blkif->vbd.bdev;
442 struct request_queue *q = bdev_get_queue(bdev);
443 if (blk_queue_discard(q)) {
444 err = xenbus_printf(xbt, dev->nodename,
445 "discard-granularity", "%u",
446 q->limits.discard_granularity);
447 if (err) {
448 xenbus_dev_fatal(dev, err,
449 "writing discard-granularity");
450 goto kfree;
451 }
452 err = xenbus_printf(xbt, dev->nodename,
453 "discard-alignment", "%u",
454 q->limits.discard_alignment);
455 if (err) {
456 xenbus_dev_fatal(dev, err,
457 "writing discard-alignment");
458 goto kfree;
459 }
460 state = 1;
461 blkif->blk_backend_type = BLKIF_BACKEND_PHY;
462 }
463 }
464 } else {
465 err = PTR_ERR(type);
466 xenbus_dev_fatal(dev, err, "reading type");
467 goto out;
468 }
469
470 err = xenbus_printf(xbt, dev->nodename, "feature-discard",
471 "%d", state);
472 if (err)
473 xenbus_dev_fatal(dev, err, "writing feature-discard");
474kfree:
475 kfree(type);
476out:
477 return err;
478}
479int xen_blkbk_barrier(struct xenbus_transaction xbt,
480 struct backend_info *be, int state)
481{
482 struct xenbus_device *dev = be->dev;
483 int err;
484
485 err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
486 "%d", state);
487 if (err)
488 xenbus_dev_fatal(dev, err, "writing feature-barrier");
489
490 return err;
491}
492
422/* 493/*
423 * Entry point to this code when a new device is created. Allocate the basic 494 * Entry point to this code when a new device is created. Allocate the basic
424 * structures, and watch the store waiting for the hotplug scripts to tell us 495 * structures, and watch the store waiting for the hotplug scripts to tell us
@@ -650,6 +721,11 @@ again:
650 if (err) 721 if (err)
651 goto abort; 722 goto abort;
652 723
724 err = xen_blkbk_discard(xbt, be);
725
726 /* If we can't advertise it is OK. */
727 err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
728
653 err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", 729 err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
654 (unsigned long long)vbd_sz(&be->blkif->vbd)); 730 (unsigned long long)vbd_sz(&be->blkif->vbd));
655 if (err) { 731 if (err) {
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 9ea8c2576c70..7b2ec5908413 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -98,6 +98,9 @@ struct blkfront_info
98 unsigned long shadow_free; 98 unsigned long shadow_free;
99 unsigned int feature_flush; 99 unsigned int feature_flush;
100 unsigned int flush_op; 100 unsigned int flush_op;
101 unsigned int feature_discard;
102 unsigned int discard_granularity;
103 unsigned int discard_alignment;
101 int is_ready; 104 int is_ready;
102}; 105};
103 106
@@ -302,29 +305,36 @@ static int blkif_queue_request(struct request *req)
302 ring_req->operation = info->flush_op; 305 ring_req->operation = info->flush_op;
303 } 306 }
304 307
305 ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); 308 if (unlikely(req->cmd_flags & REQ_DISCARD)) {
306 BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); 309 /* id, sector_number and handle are set above. */
310 ring_req->operation = BLKIF_OP_DISCARD;
311 ring_req->nr_segments = 0;
312 ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
313 } else {
314 ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
315 BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
307 316
308 for_each_sg(info->sg, sg, ring_req->nr_segments, i) { 317 for_each_sg(info->sg, sg, ring_req->nr_segments, i) {
309 buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); 318 buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg)));
310 fsect = sg->offset >> 9; 319 fsect = sg->offset >> 9;
311 lsect = fsect + (sg->length >> 9) - 1; 320 lsect = fsect + (sg->length >> 9) - 1;
312 /* install a grant reference. */ 321 /* install a grant reference. */
313 ref = gnttab_claim_grant_reference(&gref_head); 322 ref = gnttab_claim_grant_reference(&gref_head);
314 BUG_ON(ref == -ENOSPC); 323 BUG_ON(ref == -ENOSPC);
315 324
316 gnttab_grant_foreign_access_ref( 325 gnttab_grant_foreign_access_ref(
317 ref, 326 ref,
318 info->xbdev->otherend_id, 327 info->xbdev->otherend_id,
319 buffer_mfn, 328 buffer_mfn,
320 rq_data_dir(req) ); 329 rq_data_dir(req));
321 330
322 info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); 331 info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn);
323 ring_req->u.rw.seg[i] = 332 ring_req->u.rw.seg[i] =
324 (struct blkif_request_segment) { 333 (struct blkif_request_segment) {
325 .gref = ref, 334 .gref = ref,
326 .first_sect = fsect, 335 .first_sect = fsect,
327 .last_sect = lsect }; 336 .last_sect = lsect };
337 }
328 } 338 }
329 339
330 info->ring.req_prod_pvt++; 340 info->ring.req_prod_pvt++;
@@ -370,7 +380,9 @@ static void do_blkif_request(struct request_queue *rq)
370 380
371 blk_start_request(req); 381 blk_start_request(req);
372 382
373 if (req->cmd_type != REQ_TYPE_FS) { 383 if ((req->cmd_type != REQ_TYPE_FS) ||
384 ((req->cmd_flags & (REQ_FLUSH | REQ_FUA)) &&
385 !info->flush_op)) {
374 __blk_end_request_all(req, -EIO); 386 __blk_end_request_all(req, -EIO);
375 continue; 387 continue;
376 } 388 }
@@ -399,6 +411,7 @@ wait:
399static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) 411static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
400{ 412{
401 struct request_queue *rq; 413 struct request_queue *rq;
414 struct blkfront_info *info = gd->private_data;
402 415
403 rq = blk_init_queue(do_blkif_request, &blkif_io_lock); 416 rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
404 if (rq == NULL) 417 if (rq == NULL)
@@ -406,6 +419,13 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
406 419
407 queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); 420 queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
408 421
422 if (info->feature_discard) {
423 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq);
424 blk_queue_max_discard_sectors(rq, get_capacity(gd));
425 rq->limits.discard_granularity = info->discard_granularity;
426 rq->limits.discard_alignment = info->discard_alignment;
427 }
428
409 /* Hard sector size and max sectors impersonate the equiv. hardware. */ 429 /* Hard sector size and max sectors impersonate the equiv. hardware. */
410 blk_queue_logical_block_size(rq, sector_size); 430 blk_queue_logical_block_size(rq, sector_size);
411 blk_queue_max_hw_sectors(rq, 512); 431 blk_queue_max_hw_sectors(rq, 512);
@@ -722,6 +742,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
722 742
723 error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; 743 error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
724 switch (bret->operation) { 744 switch (bret->operation) {
745 case BLKIF_OP_DISCARD:
746 if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
747 struct request_queue *rq = info->rq;
748 printk(KERN_WARNING "blkfront: %s: discard op failed\n",
749 info->gd->disk_name);
750 error = -EOPNOTSUPP;
751 info->feature_discard = 0;
752 queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
753 }
754 __blk_end_request_all(req, error);
755 break;
725 case BLKIF_OP_FLUSH_DISKCACHE: 756 case BLKIF_OP_FLUSH_DISKCACHE:
726 case BLKIF_OP_WRITE_BARRIER: 757 case BLKIF_OP_WRITE_BARRIER:
727 if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { 758 if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
@@ -1098,6 +1129,33 @@ blkfront_closing(struct blkfront_info *info)
1098 bdput(bdev); 1129 bdput(bdev);
1099} 1130}
1100 1131
1132static void blkfront_setup_discard(struct blkfront_info *info)
1133{
1134 int err;
1135 char *type;
1136 unsigned int discard_granularity;
1137 unsigned int discard_alignment;
1138
1139 type = xenbus_read(XBT_NIL, info->xbdev->otherend, "type", NULL);
1140 if (IS_ERR(type))
1141 return;
1142
1143 if (strncmp(type, "phy", 3) == 0) {
1144 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1145 "discard-granularity", "%u", &discard_granularity,
1146 "discard-alignment", "%u", &discard_alignment,
1147 NULL);
1148 if (!err) {
1149 info->feature_discard = 1;
1150 info->discard_granularity = discard_granularity;
1151 info->discard_alignment = discard_alignment;
1152 }
1153 } else if (strncmp(type, "file", 4) == 0)
1154 info->feature_discard = 1;
1155
1156 kfree(type);
1157}
1158
1101/* 1159/*
1102 * Invoked when the backend is finally 'ready' (and has told produced 1160 * Invoked when the backend is finally 'ready' (and has told produced
1103 * the details about the physical device - #sectors, size, etc). 1161 * the details about the physical device - #sectors, size, etc).
@@ -1108,7 +1166,7 @@ static void blkfront_connect(struct blkfront_info *info)
1108 unsigned long sector_size; 1166 unsigned long sector_size;
1109 unsigned int binfo; 1167 unsigned int binfo;
1110 int err; 1168 int err;
1111 int barrier, flush; 1169 int barrier, flush, discard;
1112 1170
1113 switch (info->connected) { 1171 switch (info->connected) {
1114 case BLKIF_STATE_CONNECTED: 1172 case BLKIF_STATE_CONNECTED:
@@ -1178,7 +1236,14 @@ static void blkfront_connect(struct blkfront_info *info)
1178 info->feature_flush = REQ_FLUSH; 1236 info->feature_flush = REQ_FLUSH;
1179 info->flush_op = BLKIF_OP_FLUSH_DISKCACHE; 1237 info->flush_op = BLKIF_OP_FLUSH_DISKCACHE;
1180 } 1238 }
1181 1239
1240 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1241 "feature-discard", "%d", &discard,
1242 NULL);
1243
1244 if (!err && discard)
1245 blkfront_setup_discard(info);
1246
1182 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); 1247 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
1183 if (err) { 1248 if (err) {
1184 xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", 1249 xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
@@ -1385,6 +1450,8 @@ static struct xenbus_driver blkfront = {
1385 1450
1386static int __init xlblk_init(void) 1451static int __init xlblk_init(void)
1387{ 1452{
1453 int ret;
1454
1388 if (!xen_domain()) 1455 if (!xen_domain())
1389 return -ENODEV; 1456 return -ENODEV;
1390 1457
@@ -1394,7 +1461,13 @@ static int __init xlblk_init(void)
1394 return -ENODEV; 1461 return -ENODEV;
1395 } 1462 }
1396 1463
1397 return xenbus_register_frontend(&blkfront); 1464 ret = xenbus_register_frontend(&blkfront);
1465 if (ret) {
1466 unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
1467 return ret;
1468 }
1469
1470 return 0;
1398} 1471}
1399module_init(xlblk_init); 1472module_init(xlblk_init);
1400 1473
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 2e3b3d38c465..ab8f469f5cf8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
193config PL330_DMA 193config PL330_DMA
194 tristate "DMA API Driver for PL330" 194 tristate "DMA API Driver for PL330"
195 select DMA_ENGINE 195 select DMA_ENGINE
196 depends on PL330 196 depends on ARM_AMBA
197 select PL330
197 help 198 help
198 Select if your platform has one or more PL330 DMACs. 199 Select if your platform has one or more PL330 DMACs.
199 You need to provide platform specific settings via 200 You need to provide platform specific settings via
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index be21e3f138a8..b7cbd1ab1db1 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -66,32 +66,29 @@
66 * after the final transfer signalled by LBREQ or LSREQ. The DMAC 66 * after the final transfer signalled by LBREQ or LSREQ. The DMAC
67 * will then move to the next LLI entry. 67 * will then move to the next LLI entry.
68 * 68 *
69 * Only the former works sanely with scatter lists, so we only implement
70 * the DMAC flow control method. However, peripherals which use the LBREQ
71 * and LSREQ signals (eg, MMCI) are unable to use this mode, which through
72 * these hardware restrictions prevents them from using scatter DMA.
73 *
74 * Global TODO: 69 * Global TODO:
75 * - Break out common code from arch/arm/mach-s3c64xx and share 70 * - Break out common code from arch/arm/mach-s3c64xx and share
76 */ 71 */
77#include <linux/device.h>
78#include <linux/init.h>
79#include <linux/module.h>
80#include <linux/interrupt.h>
81#include <linux/slab.h>
82#include <linux/delay.h>
83#include <linux/dma-mapping.h>
84#include <linux/dmapool.h>
85#include <linux/dmaengine.h>
86#include <linux/amba/bus.h> 72#include <linux/amba/bus.h>
87#include <linux/amba/pl08x.h> 73#include <linux/amba/pl08x.h>
88#include <linux/debugfs.h> 74#include <linux/debugfs.h>
75#include <linux/delay.h>
76#include <linux/device.h>
77#include <linux/dmaengine.h>
78#include <linux/dmapool.h>
79#include <linux/dma-mapping.h>
80#include <linux/init.h>
81#include <linux/interrupt.h>
82#include <linux/module.h>
83#include <linux/pm_runtime.h>
89#include <linux/seq_file.h> 84#include <linux/seq_file.h>
90 85#include <linux/slab.h>
91#include <asm/hardware/pl080.h> 86#include <asm/hardware/pl080.h>
92 87
93#define DRIVER_NAME "pl08xdmac" 88#define DRIVER_NAME "pl08xdmac"
94 89
90static struct amba_driver pl08x_amba_driver;
91
95/** 92/**
96 * struct vendor_data - vendor-specific config parameters for PL08x derivatives 93 * struct vendor_data - vendor-specific config parameters for PL08x derivatives
97 * @channels: the number of channels available in this variant 94 * @channels: the number of channels available in this variant
@@ -126,7 +123,8 @@ struct pl08x_lli {
126 * @phy_chans: array of data for the physical channels 123 * @phy_chans: array of data for the physical channels
127 * @pool: a pool for the LLI descriptors 124 * @pool: a pool for the LLI descriptors
128 * @pool_ctr: counter of LLIs in the pool 125 * @pool_ctr: counter of LLIs in the pool
129 * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI fetches 126 * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI
127 * fetches
130 * @mem_buses: set to indicate memory transfers on AHB2. 128 * @mem_buses: set to indicate memory transfers on AHB2.
131 * @lock: a spinlock for this struct 129 * @lock: a spinlock for this struct
132 */ 130 */
@@ -149,14 +147,6 @@ struct pl08x_driver_data {
149 * PL08X specific defines 147 * PL08X specific defines
150 */ 148 */
151 149
152/*
153 * Memory boundaries: the manual for PL08x says that the controller
154 * cannot read past a 1KiB boundary, so these defines are used to
155 * create transfer LLIs that do not cross such boundaries.
156 */
157#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */
158#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT)
159
160/* Size (bytes) of each LLI buffer allocated for one transfer */ 150/* Size (bytes) of each LLI buffer allocated for one transfer */
161# define PL08X_LLI_TSFR_SIZE 0x2000 151# define PL08X_LLI_TSFR_SIZE 0x2000
162 152
@@ -272,7 +262,6 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch)
272 writel(val, ch->base + PL080_CH_CONFIG); 262 writel(val, ch->base + PL080_CH_CONFIG);
273} 263}
274 264
275
276/* 265/*
277 * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and 266 * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and
278 * clears any pending interrupt status. This should not be used for 267 * clears any pending interrupt status. This should not be used for
@@ -363,7 +352,9 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
363 if (!list_empty(&plchan->pend_list)) { 352 if (!list_empty(&plchan->pend_list)) {
364 struct pl08x_txd *txdi; 353 struct pl08x_txd *txdi;
365 list_for_each_entry(txdi, &plchan->pend_list, node) { 354 list_for_each_entry(txdi, &plchan->pend_list, node) {
366 bytes += txdi->len; 355 struct pl08x_sg *dsg;
356 list_for_each_entry(dsg, &txd->dsg_list, node)
357 bytes += dsg->len;
367 } 358 }
368 } 359 }
369 360
@@ -407,6 +398,7 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
407 return NULL; 398 return NULL;
408 } 399 }
409 400
401 pm_runtime_get_sync(&pl08x->adev->dev);
410 return ch; 402 return ch;
411} 403}
412 404
@@ -420,6 +412,8 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x,
420 /* Stop the channel and clear its interrupts */ 412 /* Stop the channel and clear its interrupts */
421 pl08x_terminate_phy_chan(pl08x, ch); 413 pl08x_terminate_phy_chan(pl08x, ch);
422 414
415 pm_runtime_put(&pl08x->adev->dev);
416
423 /* Mark it as free */ 417 /* Mark it as free */
424 ch->serving = NULL; 418 ch->serving = NULL;
425 spin_unlock_irqrestore(&ch->lock, flags); 419 spin_unlock_irqrestore(&ch->lock, flags);
@@ -499,36 +493,30 @@ struct pl08x_lli_build_data {
499}; 493};
500 494
501/* 495/*
502 * Autoselect a master bus to use for the transfer this prefers the 496 * Autoselect a master bus to use for the transfer. Slave will be the chosen as
503 * destination bus if both available if fixed address on one bus the 497 * victim in case src & dest are not similarly aligned. i.e. If after aligning
504 * other will be chosen 498 * masters address with width requirements of transfer (by sending few byte by
499 * byte data), slave is still not aligned, then its width will be reduced to
500 * BYTE.
501 * - prefers the destination bus if both available
502 * - prefers bus with fixed address (i.e. peripheral)
505 */ 503 */
506static void pl08x_choose_master_bus(struct pl08x_lli_build_data *bd, 504static void pl08x_choose_master_bus(struct pl08x_lli_build_data *bd,
507 struct pl08x_bus_data **mbus, struct pl08x_bus_data **sbus, u32 cctl) 505 struct pl08x_bus_data **mbus, struct pl08x_bus_data **sbus, u32 cctl)
508{ 506{
509 if (!(cctl & PL080_CONTROL_DST_INCR)) { 507 if (!(cctl & PL080_CONTROL_DST_INCR)) {
510 *mbus = &bd->srcbus;
511 *sbus = &bd->dstbus;
512 } else if (!(cctl & PL080_CONTROL_SRC_INCR)) {
513 *mbus = &bd->dstbus; 508 *mbus = &bd->dstbus;
514 *sbus = &bd->srcbus; 509 *sbus = &bd->srcbus;
510 } else if (!(cctl & PL080_CONTROL_SRC_INCR)) {
511 *mbus = &bd->srcbus;
512 *sbus = &bd->dstbus;
515 } else { 513 } else {
516 if (bd->dstbus.buswidth == 4) { 514 if (bd->dstbus.buswidth >= bd->srcbus.buswidth) {
517 *mbus = &bd->dstbus; 515 *mbus = &bd->dstbus;
518 *sbus = &bd->srcbus; 516 *sbus = &bd->srcbus;
519 } else if (bd->srcbus.buswidth == 4) { 517 } else {
520 *mbus = &bd->srcbus;
521 *sbus = &bd->dstbus;
522 } else if (bd->dstbus.buswidth == 2) {
523 *mbus = &bd->dstbus;
524 *sbus = &bd->srcbus;
525 } else if (bd->srcbus.buswidth == 2) {
526 *mbus = &bd->srcbus; 518 *mbus = &bd->srcbus;
527 *sbus = &bd->dstbus; 519 *sbus = &bd->dstbus;
528 } else {
529 /* bd->srcbus.buswidth == 1 */
530 *mbus = &bd->dstbus;
531 *sbus = &bd->srcbus;
532 } 520 }
533 } 521 }
534} 522}
@@ -547,7 +535,8 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd,
547 llis_va[num_llis].cctl = cctl; 535 llis_va[num_llis].cctl = cctl;
548 llis_va[num_llis].src = bd->srcbus.addr; 536 llis_va[num_llis].src = bd->srcbus.addr;
549 llis_va[num_llis].dst = bd->dstbus.addr; 537 llis_va[num_llis].dst = bd->dstbus.addr;
550 llis_va[num_llis].lli = llis_bus + (num_llis + 1) * sizeof(struct pl08x_lli); 538 llis_va[num_llis].lli = llis_bus + (num_llis + 1) *
539 sizeof(struct pl08x_lli);
551 llis_va[num_llis].lli |= bd->lli_bus; 540 llis_va[num_llis].lli |= bd->lli_bus;
552 541
553 if (cctl & PL080_CONTROL_SRC_INCR) 542 if (cctl & PL080_CONTROL_SRC_INCR)
@@ -560,16 +549,12 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd,
560 bd->remainder -= len; 549 bd->remainder -= len;
561} 550}
562 551
563/* 552static inline void prep_byte_width_lli(struct pl08x_lli_build_data *bd,
564 * Return number of bytes to fill to boundary, or len. 553 u32 *cctl, u32 len, int num_llis, size_t *total_bytes)
565 * This calculation works for any value of addr.
566 */
567static inline size_t pl08x_pre_boundary(u32 addr, size_t len)
568{ 554{
569 size_t boundary_len = PL08X_BOUNDARY_SIZE - 555 *cctl = pl08x_cctl_bits(*cctl, 1, 1, len);
570 (addr & (PL08X_BOUNDARY_SIZE - 1)); 556 pl08x_fill_lli_for_desc(bd, num_llis, len, *cctl);
571 557 (*total_bytes) += len;
572 return min(boundary_len, len);
573} 558}
574 559
575/* 560/*
@@ -583,13 +568,12 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
583 struct pl08x_bus_data *mbus, *sbus; 568 struct pl08x_bus_data *mbus, *sbus;
584 struct pl08x_lli_build_data bd; 569 struct pl08x_lli_build_data bd;
585 int num_llis = 0; 570 int num_llis = 0;
586 u32 cctl; 571 u32 cctl, early_bytes = 0;
587 size_t max_bytes_per_lli; 572 size_t max_bytes_per_lli, total_bytes;
588 size_t total_bytes = 0;
589 struct pl08x_lli *llis_va; 573 struct pl08x_lli *llis_va;
574 struct pl08x_sg *dsg;
590 575
591 txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_NOWAIT, 576 txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_NOWAIT, &txd->llis_bus);
592 &txd->llis_bus);
593 if (!txd->llis_va) { 577 if (!txd->llis_va) {
594 dev_err(&pl08x->adev->dev, "%s no memory for llis\n", __func__); 578 dev_err(&pl08x->adev->dev, "%s no memory for llis\n", __func__);
595 return 0; 579 return 0;
@@ -597,13 +581,9 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
597 581
598 pl08x->pool_ctr++; 582 pl08x->pool_ctr++;
599 583
600 /* Get the default CCTL */
601 cctl = txd->cctl;
602
603 bd.txd = txd; 584 bd.txd = txd;
604 bd.srcbus.addr = txd->src_addr;
605 bd.dstbus.addr = txd->dst_addr;
606 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0; 585 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0;
586 cctl = txd->cctl;
607 587
608 /* Find maximum width of the source bus */ 588 /* Find maximum width of the source bus */
609 bd.srcbus.maxwidth = 589 bd.srcbus.maxwidth =
@@ -615,215 +595,179 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
615 pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_DWIDTH_MASK) >> 595 pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_DWIDTH_MASK) >>
616 PL080_CONTROL_DWIDTH_SHIFT); 596 PL080_CONTROL_DWIDTH_SHIFT);
617 597
618 /* Set up the bus widths to the maximum */ 598 list_for_each_entry(dsg, &txd->dsg_list, node) {
619 bd.srcbus.buswidth = bd.srcbus.maxwidth; 599 total_bytes = 0;
620 bd.dstbus.buswidth = bd.dstbus.maxwidth; 600 cctl = txd->cctl;
621 601
622 /* 602 bd.srcbus.addr = dsg->src_addr;
623 * Bytes transferred == tsize * MIN(buswidths), not max(buswidths) 603 bd.dstbus.addr = dsg->dst_addr;
624 */ 604 bd.remainder = dsg->len;
625 max_bytes_per_lli = min(bd.srcbus.buswidth, bd.dstbus.buswidth) * 605 bd.srcbus.buswidth = bd.srcbus.maxwidth;
626 PL080_CONTROL_TRANSFER_SIZE_MASK; 606 bd.dstbus.buswidth = bd.dstbus.maxwidth;
627 607
628 /* We need to count this down to zero */ 608 pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl);
629 bd.remainder = txd->len;
630 609
631 /* 610 dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu\n",
632 * Choose bus to align to 611 bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
633 * - prefers destination bus if both available 612 bd.srcbus.buswidth,
634 * - if fixed address on one bus chooses other 613 bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
635 */ 614 bd.dstbus.buswidth,
636 pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl); 615 bd.remainder);
637 616 dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
638 dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu llimax=%zu\n", 617 mbus == &bd.srcbus ? "src" : "dst",
639 bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "", 618 sbus == &bd.srcbus ? "src" : "dst");
640 bd.srcbus.buswidth,
641 bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
642 bd.dstbus.buswidth,
643 bd.remainder, max_bytes_per_lli);
644 dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
645 mbus == &bd.srcbus ? "src" : "dst",
646 sbus == &bd.srcbus ? "src" : "dst");
647
648 if (txd->len < mbus->buswidth) {
649 /* Less than a bus width available - send as single bytes */
650 while (bd.remainder) {
651 dev_vdbg(&pl08x->adev->dev,
652 "%s single byte LLIs for a transfer of "
653 "less than a bus width (remain 0x%08x)\n",
654 __func__, bd.remainder);
655 cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
656 pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
657 total_bytes++;
658 }
659 } else {
660 /* Make one byte LLIs until master bus is aligned */
661 while ((mbus->addr) % (mbus->buswidth)) {
662 dev_vdbg(&pl08x->adev->dev,
663 "%s adjustment lli for less than bus width "
664 "(remain 0x%08x)\n",
665 __func__, bd.remainder);
666 cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
667 pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
668 total_bytes++;
669 }
670 619
671 /* 620 /*
672 * Master now aligned 621 * Zero length is only allowed if all these requirements are
673 * - if slave is not then we must set its width down 622 * met:
623 * - flow controller is peripheral.
624 * - src.addr is aligned to src.width
625 * - dst.addr is aligned to dst.width
626 *
627 * sg_len == 1 should be true, as there can be two cases here:
628 *
629 * - Memory addresses are contiguous and are not scattered.
630 * Here, Only one sg will be passed by user driver, with
631 * memory address and zero length. We pass this to controller
632 * and after the transfer it will receive the last burst
633 * request from peripheral and so transfer finishes.
634 *
635 * - Memory addresses are scattered and are not contiguous.
636 * Here, Obviously as DMA controller doesn't know when a lli's
637 * transfer gets over, it can't load next lli. So in this
638 * case, there has to be an assumption that only one lli is
639 * supported. Thus, we can't have scattered addresses.
674 */ 640 */
675 if (sbus->addr % sbus->buswidth) { 641 if (!bd.remainder) {
676 dev_dbg(&pl08x->adev->dev, 642 u32 fc = (txd->ccfg & PL080_CONFIG_FLOW_CONTROL_MASK) >>
677 "%s set down bus width to one byte\n", 643 PL080_CONFIG_FLOW_CONTROL_SHIFT;
678 __func__); 644 if (!((fc >= PL080_FLOW_SRC2DST_DST) &&
645 (fc <= PL080_FLOW_SRC2DST_SRC))) {
646 dev_err(&pl08x->adev->dev, "%s sg len can't be zero",
647 __func__);
648 return 0;
649 }
650
651 if ((bd.srcbus.addr % bd.srcbus.buswidth) ||
652 (bd.srcbus.addr % bd.srcbus.buswidth)) {
653 dev_err(&pl08x->adev->dev,
654 "%s src & dst address must be aligned to src"
655 " & dst width if peripheral is flow controller",
656 __func__);
657 return 0;
658 }
679 659
680 sbus->buswidth = 1; 660 cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth,
661 bd.dstbus.buswidth, 0);
662 pl08x_fill_lli_for_desc(&bd, num_llis++, 0, cctl);
663 break;
681 } 664 }
682 665
683 /* 666 /*
684 * Make largest possible LLIs until less than one bus 667 * Send byte by byte for following cases
685 * width left 668 * - Less than a bus width available
669 * - until master bus is aligned
686 */ 670 */
687 while (bd.remainder > (mbus->buswidth - 1)) { 671 if (bd.remainder < mbus->buswidth)
688 size_t lli_len, target_len, tsize, odd_bytes; 672 early_bytes = bd.remainder;
673 else if ((mbus->addr) % (mbus->buswidth)) {
674 early_bytes = mbus->buswidth - (mbus->addr) %
675 (mbus->buswidth);
676 if ((bd.remainder - early_bytes) < mbus->buswidth)
677 early_bytes = bd.remainder;
678 }
689 679
680 if (early_bytes) {
681 dev_vdbg(&pl08x->adev->dev,
682 "%s byte width LLIs (remain 0x%08x)\n",
683 __func__, bd.remainder);
684 prep_byte_width_lli(&bd, &cctl, early_bytes, num_llis++,
685 &total_bytes);
686 }
687
688 if (bd.remainder) {
690 /* 689 /*
691 * If enough left try to send max possible, 690 * Master now aligned
692 * otherwise try to send the remainder 691 * - if slave is not then we must set its width down
693 */ 692 */
694 target_len = min(bd.remainder, max_bytes_per_lli); 693 if (sbus->addr % sbus->buswidth) {
694 dev_dbg(&pl08x->adev->dev,
695 "%s set down bus width to one byte\n",
696 __func__);
697
698 sbus->buswidth = 1;
699 }
695 700
696 /* 701 /*
697 * Set bus lengths for incrementing buses to the 702 * Bytes transferred = tsize * src width, not
698 * number of bytes which fill to next memory boundary, 703 * MIN(buswidths)
699 * limiting on the target length calculated above.
700 */ 704 */
701 if (cctl & PL080_CONTROL_SRC_INCR) 705 max_bytes_per_lli = bd.srcbus.buswidth *
702 bd.srcbus.fill_bytes = 706 PL080_CONTROL_TRANSFER_SIZE_MASK;
703 pl08x_pre_boundary(bd.srcbus.addr, 707 dev_vdbg(&pl08x->adev->dev,
704 target_len); 708 "%s max bytes per lli = %zu\n",
705 else 709 __func__, max_bytes_per_lli);
706 bd.srcbus.fill_bytes = target_len; 710
707 711 /*
708 if (cctl & PL080_CONTROL_DST_INCR) 712 * Make largest possible LLIs until less than one bus
709 bd.dstbus.fill_bytes = 713 * width left
710 pl08x_pre_boundary(bd.dstbus.addr, 714 */
711 target_len); 715 while (bd.remainder > (mbus->buswidth - 1)) {
712 else 716 size_t lli_len, tsize, width;
713 bd.dstbus.fill_bytes = target_len;
714
715 /* Find the nearest */
716 lli_len = min(bd.srcbus.fill_bytes,
717 bd.dstbus.fill_bytes);
718
719 BUG_ON(lli_len > bd.remainder);
720
721 if (lli_len <= 0) {
722 dev_err(&pl08x->adev->dev,
723 "%s lli_len is %zu, <= 0\n",
724 __func__, lli_len);
725 return 0;
726 }
727 717
728 if (lli_len == target_len) {
729 /*
730 * Can send what we wanted.
731 * Maintain alignment
732 */
733 lli_len = (lli_len/mbus->buswidth) *
734 mbus->buswidth;
735 odd_bytes = 0;
736 } else {
737 /* 718 /*
738 * So now we know how many bytes to transfer 719 * If enough left try to send max possible,
739 * to get to the nearest boundary. The next 720 * otherwise try to send the remainder
740 * LLI will past the boundary. However, we
741 * may be working to a boundary on the slave
742 * bus. We need to ensure the master stays
743 * aligned, and that we are working in
744 * multiples of the bus widths.
745 */ 721 */
746 odd_bytes = lli_len % mbus->buswidth; 722 lli_len = min(bd.remainder, max_bytes_per_lli);
747 lli_len -= odd_bytes;
748
749 }
750 723
751 if (lli_len) {
752 /* 724 /*
753 * Check against minimum bus alignment: 725 * Check against maximum bus alignment:
754 * Calculate actual transfer size in relation 726 * Calculate actual transfer size in relation to
755 * to bus width an get a maximum remainder of 727 * bus width an get a maximum remainder of the
756 * the smallest bus width - 1 728 * highest bus width - 1
757 */ 729 */
758 /* FIXME: use round_down()? */ 730 width = max(mbus->buswidth, sbus->buswidth);
759 tsize = lli_len / min(mbus->buswidth, 731 lli_len = (lli_len / width) * width;
760 sbus->buswidth); 732 tsize = lli_len / bd.srcbus.buswidth;
761 lli_len = tsize * min(mbus->buswidth,
762 sbus->buswidth);
763
764 if (target_len != lli_len) {
765 dev_vdbg(&pl08x->adev->dev,
766 "%s can't send what we want. Desired 0x%08zx, lli of 0x%08zx bytes in txd of 0x%08zx\n",
767 __func__, target_len, lli_len, txd->len);
768 }
769
770 cctl = pl08x_cctl_bits(cctl,
771 bd.srcbus.buswidth,
772 bd.dstbus.buswidth,
773 tsize);
774 733
775 dev_vdbg(&pl08x->adev->dev, 734 dev_vdbg(&pl08x->adev->dev,
776 "%s fill lli with single lli chunk of size 0x%08zx (remainder 0x%08zx)\n", 735 "%s fill lli with single lli chunk of "
736 "size 0x%08zx (remainder 0x%08zx)\n",
777 __func__, lli_len, bd.remainder); 737 __func__, lli_len, bd.remainder);
738
739 cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth,
740 bd.dstbus.buswidth, tsize);
778 pl08x_fill_lli_for_desc(&bd, num_llis++, 741 pl08x_fill_lli_for_desc(&bd, num_llis++,
779 lli_len, cctl); 742 lli_len, cctl);
780 total_bytes += lli_len; 743 total_bytes += lli_len;
781 } 744 }
782 745
783 746 /*
784 if (odd_bytes) { 747 * Send any odd bytes
785 /* 748 */
786 * Creep past the boundary, maintaining 749 if (bd.remainder) {
787 * master alignment 750 dev_vdbg(&pl08x->adev->dev,
788 */ 751 "%s align with boundary, send odd bytes (remain %zu)\n",
789 int j; 752 __func__, bd.remainder);
790 for (j = 0; (j < mbus->buswidth) 753 prep_byte_width_lli(&bd, &cctl, bd.remainder,
791 && (bd.remainder); j++) { 754 num_llis++, &total_bytes);
792 cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
793 dev_vdbg(&pl08x->adev->dev,
794 "%s align with boundary, single byte (remain 0x%08zx)\n",
795 __func__, bd.remainder);
796 pl08x_fill_lli_for_desc(&bd,
797 num_llis++, 1, cctl);
798 total_bytes++;
799 }
800 } 755 }
801 } 756 }
802 757
803 /* 758 if (total_bytes != dsg->len) {
804 * Send any odd bytes 759 dev_err(&pl08x->adev->dev,
805 */ 760 "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n",
806 while (bd.remainder) { 761 __func__, total_bytes, dsg->len);
807 cctl = pl08x_cctl_bits(cctl, 1, 1, 1); 762 return 0;
808 dev_vdbg(&pl08x->adev->dev,
809 "%s align with boundary, single odd byte (remain %zu)\n",
810 __func__, bd.remainder);
811 pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
812 total_bytes++;
813 } 763 }
814 }
815 if (total_bytes != txd->len) {
816 dev_err(&pl08x->adev->dev,
817 "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n",
818 __func__, total_bytes, txd->len);
819 return 0;
820 }
821 764
822 if (num_llis >= MAX_NUM_TSFR_LLIS) { 765 if (num_llis >= MAX_NUM_TSFR_LLIS) {
823 dev_err(&pl08x->adev->dev, 766 dev_err(&pl08x->adev->dev,
824 "%s need to increase MAX_NUM_TSFR_LLIS from 0x%08x\n", 767 "%s need to increase MAX_NUM_TSFR_LLIS from 0x%08x\n",
825 __func__, (u32) MAX_NUM_TSFR_LLIS); 768 __func__, (u32) MAX_NUM_TSFR_LLIS);
826 return 0; 769 return 0;
770 }
827 } 771 }
828 772
829 llis_va = txd->llis_va; 773 llis_va = txd->llis_va;
@@ -856,11 +800,19 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
856static void pl08x_free_txd(struct pl08x_driver_data *pl08x, 800static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
857 struct pl08x_txd *txd) 801 struct pl08x_txd *txd)
858{ 802{
803 struct pl08x_sg *dsg, *_dsg;
804
859 /* Free the LLI */ 805 /* Free the LLI */
860 dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus); 806 if (txd->llis_va)
807 dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus);
861 808
862 pl08x->pool_ctr--; 809 pl08x->pool_ctr--;
863 810
811 list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) {
812 list_del(&dsg->node);
813 kfree(dsg);
814 }
815
864 kfree(txd); 816 kfree(txd);
865} 817}
866 818
@@ -917,9 +869,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
917 * need, but for slaves the physical signals may be muxed! 869 * need, but for slaves the physical signals may be muxed!
918 * Can the platform allow us to use this channel? 870 * Can the platform allow us to use this channel?
919 */ 871 */
920 if (plchan->slave && 872 if (plchan->slave && pl08x->pd->get_signal) {
921 ch->signal < 0 &&
922 pl08x->pd->get_signal) {
923 ret = pl08x->pd->get_signal(plchan); 873 ret = pl08x->pd->get_signal(plchan);
924 if (ret < 0) { 874 if (ret < 0) {
925 dev_dbg(&pl08x->adev->dev, 875 dev_dbg(&pl08x->adev->dev,
@@ -1008,10 +958,8 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
1008 * If slaves are relying on interrupts to signal completion this function 958 * If slaves are relying on interrupts to signal completion this function
1009 * must not be called with interrupts disabled. 959 * must not be called with interrupts disabled.
1010 */ 960 */
1011static enum dma_status 961static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
1012pl08x_dma_tx_status(struct dma_chan *chan, 962 dma_cookie_t cookie, struct dma_tx_state *txstate)
1013 dma_cookie_t cookie,
1014 struct dma_tx_state *txstate)
1015{ 963{
1016 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 964 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1017 dma_cookie_t last_used; 965 dma_cookie_t last_used;
@@ -1253,7 +1201,9 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
1253 1201
1254 num_llis = pl08x_fill_llis_for_desc(pl08x, txd); 1202 num_llis = pl08x_fill_llis_for_desc(pl08x, txd);
1255 if (!num_llis) { 1203 if (!num_llis) {
1256 kfree(txd); 1204 spin_lock_irqsave(&plchan->lock, flags);
1205 pl08x_free_txd(pl08x, txd);
1206 spin_unlock_irqrestore(&plchan->lock, flags);
1257 return -EINVAL; 1207 return -EINVAL;
1258 } 1208 }
1259 1209
@@ -1301,13 +1251,14 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
1301static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan, 1251static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan,
1302 unsigned long flags) 1252 unsigned long flags)
1303{ 1253{
1304 struct pl08x_txd *txd = kzalloc(sizeof(struct pl08x_txd), GFP_NOWAIT); 1254 struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
1305 1255
1306 if (txd) { 1256 if (txd) {
1307 dma_async_tx_descriptor_init(&txd->tx, &plchan->chan); 1257 dma_async_tx_descriptor_init(&txd->tx, &plchan->chan);
1308 txd->tx.flags = flags; 1258 txd->tx.flags = flags;
1309 txd->tx.tx_submit = pl08x_tx_submit; 1259 txd->tx.tx_submit = pl08x_tx_submit;
1310 INIT_LIST_HEAD(&txd->node); 1260 INIT_LIST_HEAD(&txd->node);
1261 INIT_LIST_HEAD(&txd->dsg_list);
1311 1262
1312 /* Always enable error and terminal interrupts */ 1263 /* Always enable error and terminal interrupts */
1313 txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | 1264 txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK |
@@ -1326,6 +1277,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1326 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1277 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1327 struct pl08x_driver_data *pl08x = plchan->host; 1278 struct pl08x_driver_data *pl08x = plchan->host;
1328 struct pl08x_txd *txd; 1279 struct pl08x_txd *txd;
1280 struct pl08x_sg *dsg;
1329 int ret; 1281 int ret;
1330 1282
1331 txd = pl08x_get_txd(plchan, flags); 1283 txd = pl08x_get_txd(plchan, flags);
@@ -1335,10 +1287,19 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1335 return NULL; 1287 return NULL;
1336 } 1288 }
1337 1289
1290 dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT);
1291 if (!dsg) {
1292 pl08x_free_txd(pl08x, txd);
1293 dev_err(&pl08x->adev->dev, "%s no memory for pl080 sg\n",
1294 __func__);
1295 return NULL;
1296 }
1297 list_add_tail(&dsg->node, &txd->dsg_list);
1298
1338 txd->direction = DMA_NONE; 1299 txd->direction = DMA_NONE;
1339 txd->src_addr = src; 1300 dsg->src_addr = src;
1340 txd->dst_addr = dest; 1301 dsg->dst_addr = dest;
1341 txd->len = len; 1302 dsg->len = len;
1342 1303
1343 /* Set platform data for m2m */ 1304 /* Set platform data for m2m */
1344 txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1305 txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
@@ -1367,19 +1328,13 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1367 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1328 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1368 struct pl08x_driver_data *pl08x = plchan->host; 1329 struct pl08x_driver_data *pl08x = plchan->host;
1369 struct pl08x_txd *txd; 1330 struct pl08x_txd *txd;
1370 int ret; 1331 struct pl08x_sg *dsg;
1371 1332 struct scatterlist *sg;
1372 /* 1333 dma_addr_t slave_addr;
1373 * Current implementation ASSUMES only one sg 1334 int ret, tmp;
1374 */
1375 if (sg_len != 1) {
1376 dev_err(&pl08x->adev->dev, "%s prepared too long sglist\n",
1377 __func__);
1378 BUG();
1379 }
1380 1335
1381 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n", 1336 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n",
1382 __func__, sgl->length, plchan->name); 1337 __func__, sgl->length, plchan->name);
1383 1338
1384 txd = pl08x_get_txd(plchan, flags); 1339 txd = pl08x_get_txd(plchan, flags);
1385 if (!txd) { 1340 if (!txd) {
@@ -1398,24 +1353,49 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1398 * channel target address dynamically at runtime. 1353 * channel target address dynamically at runtime.
1399 */ 1354 */
1400 txd->direction = direction; 1355 txd->direction = direction;
1401 txd->len = sgl->length;
1402 1356
1403 if (direction == DMA_TO_DEVICE) { 1357 if (direction == DMA_TO_DEVICE) {
1404 txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1405 txd->cctl = plchan->dst_cctl; 1358 txd->cctl = plchan->dst_cctl;
1406 txd->src_addr = sgl->dma_address; 1359 slave_addr = plchan->dst_addr;
1407 txd->dst_addr = plchan->dst_addr;
1408 } else if (direction == DMA_FROM_DEVICE) { 1360 } else if (direction == DMA_FROM_DEVICE) {
1409 txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1410 txd->cctl = plchan->src_cctl; 1361 txd->cctl = plchan->src_cctl;
1411 txd->src_addr = plchan->src_addr; 1362 slave_addr = plchan->src_addr;
1412 txd->dst_addr = sgl->dma_address;
1413 } else { 1363 } else {
1364 pl08x_free_txd(pl08x, txd);
1414 dev_err(&pl08x->adev->dev, 1365 dev_err(&pl08x->adev->dev,
1415 "%s direction unsupported\n", __func__); 1366 "%s direction unsupported\n", __func__);
1416 return NULL; 1367 return NULL;
1417 } 1368 }
1418 1369
1370 if (plchan->cd->device_fc)
1371 tmp = (direction == DMA_TO_DEVICE) ? PL080_FLOW_MEM2PER_PER :
1372 PL080_FLOW_PER2MEM_PER;
1373 else
1374 tmp = (direction == DMA_TO_DEVICE) ? PL080_FLOW_MEM2PER :
1375 PL080_FLOW_PER2MEM;
1376
1377 txd->ccfg |= tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1378
1379 for_each_sg(sgl, sg, sg_len, tmp) {
1380 dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT);
1381 if (!dsg) {
1382 pl08x_free_txd(pl08x, txd);
1383 dev_err(&pl08x->adev->dev, "%s no mem for pl080 sg\n",
1384 __func__);
1385 return NULL;
1386 }
1387 list_add_tail(&dsg->node, &txd->dsg_list);
1388
1389 dsg->len = sg_dma_len(sg);
1390 if (direction == DMA_TO_DEVICE) {
1391 dsg->src_addr = sg_phys(sg);
1392 dsg->dst_addr = slave_addr;
1393 } else {
1394 dsg->src_addr = slave_addr;
1395 dsg->dst_addr = sg_phys(sg);
1396 }
1397 }
1398
1419 ret = pl08x_prep_channel_resources(plchan, txd); 1399 ret = pl08x_prep_channel_resources(plchan, txd);
1420 if (ret) 1400 if (ret)
1421 return NULL; 1401 return NULL;
@@ -1489,9 +1469,15 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1489 1469
1490bool pl08x_filter_id(struct dma_chan *chan, void *chan_id) 1470bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
1491{ 1471{
1492 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1472 struct pl08x_dma_chan *plchan;
1493 char *name = chan_id; 1473 char *name = chan_id;
1494 1474
1475 /* Reject channels for devices not bound to this driver */
1476 if (chan->device->dev->driver != &pl08x_amba_driver.drv)
1477 return false;
1478
1479 plchan = to_pl08x_chan(chan);
1480
1495 /* Check that the channel is not taken! */ 1481 /* Check that the channel is not taken! */
1496 if (!strcmp(plchan->name, name)) 1482 if (!strcmp(plchan->name, name))
1497 return true; 1483 return true;
@@ -1507,34 +1493,34 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
1507 */ 1493 */
1508static void pl08x_ensure_on(struct pl08x_driver_data *pl08x) 1494static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
1509{ 1495{
1510 u32 val; 1496 writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG);
1511
1512 val = readl(pl08x->base + PL080_CONFIG);
1513 val &= ~(PL080_CONFIG_M2_BE | PL080_CONFIG_M1_BE | PL080_CONFIG_ENABLE);
1514 /* We implicitly clear bit 1 and that means little-endian mode */
1515 val |= PL080_CONFIG_ENABLE;
1516 writel(val, pl08x->base + PL080_CONFIG);
1517} 1497}
1518 1498
1519static void pl08x_unmap_buffers(struct pl08x_txd *txd) 1499static void pl08x_unmap_buffers(struct pl08x_txd *txd)
1520{ 1500{
1521 struct device *dev = txd->tx.chan->device->dev; 1501 struct device *dev = txd->tx.chan->device->dev;
1502 struct pl08x_sg *dsg;
1522 1503
1523 if (!(txd->tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { 1504 if (!(txd->tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
1524 if (txd->tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE) 1505 if (txd->tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
1525 dma_unmap_single(dev, txd->src_addr, txd->len, 1506 list_for_each_entry(dsg, &txd->dsg_list, node)
1526 DMA_TO_DEVICE); 1507 dma_unmap_single(dev, dsg->src_addr, dsg->len,
1527 else 1508 DMA_TO_DEVICE);
1528 dma_unmap_page(dev, txd->src_addr, txd->len, 1509 else {
1529 DMA_TO_DEVICE); 1510 list_for_each_entry(dsg, &txd->dsg_list, node)
1511 dma_unmap_page(dev, dsg->src_addr, dsg->len,
1512 DMA_TO_DEVICE);
1513 }
1530 } 1514 }
1531 if (!(txd->tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { 1515 if (!(txd->tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
1532 if (txd->tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE) 1516 if (txd->tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
1533 dma_unmap_single(dev, txd->dst_addr, txd->len, 1517 list_for_each_entry(dsg, &txd->dsg_list, node)
1534 DMA_FROM_DEVICE); 1518 dma_unmap_single(dev, dsg->dst_addr, dsg->len,
1519 DMA_FROM_DEVICE);
1535 else 1520 else
1536 dma_unmap_page(dev, txd->dst_addr, txd->len, 1521 list_for_each_entry(dsg, &txd->dsg_list, node)
1537 DMA_FROM_DEVICE); 1522 dma_unmap_page(dev, dsg->dst_addr, dsg->len,
1523 DMA_FROM_DEVICE);
1538 } 1524 }
1539} 1525}
1540 1526
@@ -1589,8 +1575,8 @@ static void pl08x_tasklet(unsigned long data)
1589 */ 1575 */
1590 list_for_each_entry(waiting, &pl08x->memcpy.channels, 1576 list_for_each_entry(waiting, &pl08x->memcpy.channels,
1591 chan.device_node) { 1577 chan.device_node) {
1592 if (waiting->state == PL08X_CHAN_WAITING && 1578 if (waiting->state == PL08X_CHAN_WAITING &&
1593 waiting->waiting != NULL) { 1579 waiting->waiting != NULL) {
1594 int ret; 1580 int ret;
1595 1581
1596 /* This should REALLY not fail now */ 1582 /* This should REALLY not fail now */
@@ -1630,38 +1616,40 @@ static void pl08x_tasklet(unsigned long data)
1630static irqreturn_t pl08x_irq(int irq, void *dev) 1616static irqreturn_t pl08x_irq(int irq, void *dev)
1631{ 1617{
1632 struct pl08x_driver_data *pl08x = dev; 1618 struct pl08x_driver_data *pl08x = dev;
1633 u32 mask = 0; 1619 u32 mask = 0, err, tc, i;
1634 u32 val; 1620
1635 int i; 1621 /* check & clear - ERR & TC interrupts */
1636 1622 err = readl(pl08x->base + PL080_ERR_STATUS);
1637 val = readl(pl08x->base + PL080_ERR_STATUS); 1623 if (err) {
1638 if (val) { 1624 dev_err(&pl08x->adev->dev, "%s error interrupt, register value 0x%08x\n",
1639 /* An error interrupt (on one or more channels) */ 1625 __func__, err);
1640 dev_err(&pl08x->adev->dev, 1626 writel(err, pl08x->base + PL080_ERR_CLEAR);
1641 "%s error interrupt, register value 0x%08x\n",
1642 __func__, val);
1643 /*
1644 * Simply clear ALL PL08X error interrupts,
1645 * regardless of channel and cause
1646 * FIXME: should be 0x00000003 on PL081 really.
1647 */
1648 writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR);
1649 } 1627 }
1650 val = readl(pl08x->base + PL080_INT_STATUS); 1628 tc = readl(pl08x->base + PL080_INT_STATUS);
1629 if (tc)
1630 writel(tc, pl08x->base + PL080_TC_CLEAR);
1631
1632 if (!err && !tc)
1633 return IRQ_NONE;
1634
1651 for (i = 0; i < pl08x->vd->channels; i++) { 1635 for (i = 0; i < pl08x->vd->channels; i++) {
1652 if ((1 << i) & val) { 1636 if (((1 << i) & err) || ((1 << i) & tc)) {
1653 /* Locate physical channel */ 1637 /* Locate physical channel */
1654 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i]; 1638 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
1655 struct pl08x_dma_chan *plchan = phychan->serving; 1639 struct pl08x_dma_chan *plchan = phychan->serving;
1656 1640
1641 if (!plchan) {
1642 dev_err(&pl08x->adev->dev,
1643 "%s Error TC interrupt on unused channel: 0x%08x\n",
1644 __func__, i);
1645 continue;
1646 }
1647
1657 /* Schedule tasklet on this channel */ 1648 /* Schedule tasklet on this channel */
1658 tasklet_schedule(&plchan->tasklet); 1649 tasklet_schedule(&plchan->tasklet);
1659
1660 mask |= (1 << i); 1650 mask |= (1 << i);
1661 } 1651 }
1662 } 1652 }
1663 /* Clear only the terminal interrupts on channels we processed */
1664 writel(mask, pl08x->base + PL080_TC_CLEAR);
1665 1653
1666 return mask ? IRQ_HANDLED : IRQ_NONE; 1654 return mask ? IRQ_HANDLED : IRQ_NONE;
1667} 1655}
@@ -1685,9 +1673,7 @@ static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan)
1685 * Make a local wrapper to hold required data 1673 * Make a local wrapper to hold required data
1686 */ 1674 */
1687static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, 1675static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1688 struct dma_device *dmadev, 1676 struct dma_device *dmadev, unsigned int channels, bool slave)
1689 unsigned int channels,
1690 bool slave)
1691{ 1677{
1692 struct pl08x_dma_chan *chan; 1678 struct pl08x_dma_chan *chan;
1693 int i; 1679 int i;
@@ -1700,7 +1686,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1700 * to cope with that situation. 1686 * to cope with that situation.
1701 */ 1687 */
1702 for (i = 0; i < channels; i++) { 1688 for (i = 0; i < channels; i++) {
1703 chan = kzalloc(sizeof(struct pl08x_dma_chan), GFP_KERNEL); 1689 chan = kzalloc(sizeof(*chan), GFP_KERNEL);
1704 if (!chan) { 1690 if (!chan) {
1705 dev_err(&pl08x->adev->dev, 1691 dev_err(&pl08x->adev->dev,
1706 "%s no memory for channel\n", __func__); 1692 "%s no memory for channel\n", __func__);
@@ -1728,7 +1714,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1728 kfree(chan); 1714 kfree(chan);
1729 continue; 1715 continue;
1730 } 1716 }
1731 dev_info(&pl08x->adev->dev, 1717 dev_dbg(&pl08x->adev->dev,
1732 "initialize virtual channel \"%s\"\n", 1718 "initialize virtual channel \"%s\"\n",
1733 chan->name); 1719 chan->name);
1734 1720
@@ -1837,9 +1823,9 @@ static const struct file_operations pl08x_debugfs_operations = {
1837static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x) 1823static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x)
1838{ 1824{
1839 /* Expose a simple debugfs interface to view all clocks */ 1825 /* Expose a simple debugfs interface to view all clocks */
1840 (void) debugfs_create_file(dev_name(&pl08x->adev->dev), S_IFREG | S_IRUGO, 1826 (void) debugfs_create_file(dev_name(&pl08x->adev->dev),
1841 NULL, pl08x, 1827 S_IFREG | S_IRUGO, NULL, pl08x,
1842 &pl08x_debugfs_operations); 1828 &pl08x_debugfs_operations);
1843} 1829}
1844 1830
1845#else 1831#else
@@ -1860,12 +1846,15 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1860 return ret; 1846 return ret;
1861 1847
1862 /* Create the driver state holder */ 1848 /* Create the driver state holder */
1863 pl08x = kzalloc(sizeof(struct pl08x_driver_data), GFP_KERNEL); 1849 pl08x = kzalloc(sizeof(*pl08x), GFP_KERNEL);
1864 if (!pl08x) { 1850 if (!pl08x) {
1865 ret = -ENOMEM; 1851 ret = -ENOMEM;
1866 goto out_no_pl08x; 1852 goto out_no_pl08x;
1867 } 1853 }
1868 1854
1855 pm_runtime_set_active(&adev->dev);
1856 pm_runtime_enable(&adev->dev);
1857
1869 /* Initialize memcpy engine */ 1858 /* Initialize memcpy engine */
1870 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask); 1859 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask);
1871 pl08x->memcpy.dev = &adev->dev; 1860 pl08x->memcpy.dev = &adev->dev;
@@ -1939,7 +1928,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1939 } 1928 }
1940 1929
1941 /* Initialize physical channels */ 1930 /* Initialize physical channels */
1942 pl08x->phy_chans = kmalloc((vd->channels * sizeof(struct pl08x_phy_chan)), 1931 pl08x->phy_chans = kmalloc((vd->channels * sizeof(*pl08x->phy_chans)),
1943 GFP_KERNEL); 1932 GFP_KERNEL);
1944 if (!pl08x->phy_chans) { 1933 if (!pl08x->phy_chans) {
1945 dev_err(&adev->dev, "%s failed to allocate " 1934 dev_err(&adev->dev, "%s failed to allocate "
@@ -1956,9 +1945,8 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1956 spin_lock_init(&ch->lock); 1945 spin_lock_init(&ch->lock);
1957 ch->serving = NULL; 1946 ch->serving = NULL;
1958 ch->signal = -1; 1947 ch->signal = -1;
1959 dev_info(&adev->dev, 1948 dev_dbg(&adev->dev, "physical channel %d is %s\n",
1960 "physical channel %d is %s\n", i, 1949 i, pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
1961 pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
1962 } 1950 }
1963 1951
1964 /* Register as many memcpy channels as there are physical channels */ 1952 /* Register as many memcpy channels as there are physical channels */
@@ -1974,8 +1962,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1974 1962
1975 /* Register slave channels */ 1963 /* Register slave channels */
1976 ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, 1964 ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave,
1977 pl08x->pd->num_slave_channels, 1965 pl08x->pd->num_slave_channels, true);
1978 true);
1979 if (ret <= 0) { 1966 if (ret <= 0) {
1980 dev_warn(&pl08x->adev->dev, 1967 dev_warn(&pl08x->adev->dev,
1981 "%s failed to enumerate slave channels - %d\n", 1968 "%s failed to enumerate slave channels - %d\n",
@@ -2005,6 +1992,8 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
2005 dev_info(&pl08x->adev->dev, "DMA: PL%03x rev%u at 0x%08llx irq %d\n", 1992 dev_info(&pl08x->adev->dev, "DMA: PL%03x rev%u at 0x%08llx irq %d\n",
2006 amba_part(adev), amba_rev(adev), 1993 amba_part(adev), amba_rev(adev),
2007 (unsigned long long)adev->res.start, adev->irq[0]); 1994 (unsigned long long)adev->res.start, adev->irq[0]);
1995
1996 pm_runtime_put(&adev->dev);
2008 return 0; 1997 return 0;
2009 1998
2010out_no_slave_reg: 1999out_no_slave_reg:
@@ -2023,6 +2012,9 @@ out_no_ioremap:
2023 dma_pool_destroy(pl08x->pool); 2012 dma_pool_destroy(pl08x->pool);
2024out_no_lli_pool: 2013out_no_lli_pool:
2025out_no_platdata: 2014out_no_platdata:
2015 pm_runtime_put(&adev->dev);
2016 pm_runtime_disable(&adev->dev);
2017
2026 kfree(pl08x); 2018 kfree(pl08x);
2027out_no_pl08x: 2019out_no_pl08x:
2028 amba_release_regions(adev); 2020 amba_release_regions(adev);
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 6a483eac7b3f..fcfa0a8b5c59 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -107,10 +107,11 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
107{ 107{
108 struct at_desc *desc, *_desc; 108 struct at_desc *desc, *_desc;
109 struct at_desc *ret = NULL; 109 struct at_desc *ret = NULL;
110 unsigned long flags;
110 unsigned int i = 0; 111 unsigned int i = 0;
111 LIST_HEAD(tmp_list); 112 LIST_HEAD(tmp_list);
112 113
113 spin_lock_bh(&atchan->lock); 114 spin_lock_irqsave(&atchan->lock, flags);
114 list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) { 115 list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
115 i++; 116 i++;
116 if (async_tx_test_ack(&desc->txd)) { 117 if (async_tx_test_ack(&desc->txd)) {
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
121 dev_dbg(chan2dev(&atchan->chan_common), 122 dev_dbg(chan2dev(&atchan->chan_common),
122 "desc %p not ACKed\n", desc); 123 "desc %p not ACKed\n", desc);
123 } 124 }
124 spin_unlock_bh(&atchan->lock); 125 spin_unlock_irqrestore(&atchan->lock, flags);
125 dev_vdbg(chan2dev(&atchan->chan_common), 126 dev_vdbg(chan2dev(&atchan->chan_common),
126 "scanned %u descriptors on freelist\n", i); 127 "scanned %u descriptors on freelist\n", i);
127 128
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
129 if (!ret) { 130 if (!ret) {
130 ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC); 131 ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC);
131 if (ret) { 132 if (ret) {
132 spin_lock_bh(&atchan->lock); 133 spin_lock_irqsave(&atchan->lock, flags);
133 atchan->descs_allocated++; 134 atchan->descs_allocated++;
134 spin_unlock_bh(&atchan->lock); 135 spin_unlock_irqrestore(&atchan->lock, flags);
135 } else { 136 } else {
136 dev_err(chan2dev(&atchan->chan_common), 137 dev_err(chan2dev(&atchan->chan_common),
137 "not enough descriptors available\n"); 138 "not enough descriptors available\n");
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
150{ 151{
151 if (desc) { 152 if (desc) {
152 struct at_desc *child; 153 struct at_desc *child;
154 unsigned long flags;
153 155
154 spin_lock_bh(&atchan->lock); 156 spin_lock_irqsave(&atchan->lock, flags);
155 list_for_each_entry(child, &desc->tx_list, desc_node) 157 list_for_each_entry(child, &desc->tx_list, desc_node)
156 dev_vdbg(chan2dev(&atchan->chan_common), 158 dev_vdbg(chan2dev(&atchan->chan_common),
157 "moving child desc %p to freelist\n", 159 "moving child desc %p to freelist\n",
@@ -160,7 +162,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
160 dev_vdbg(chan2dev(&atchan->chan_common), 162 dev_vdbg(chan2dev(&atchan->chan_common),
161 "moving desc %p to freelist\n", desc); 163 "moving desc %p to freelist\n", desc);
162 list_add(&desc->desc_node, &atchan->free_list); 164 list_add(&desc->desc_node, &atchan->free_list);
163 spin_unlock_bh(&atchan->lock); 165 spin_unlock_irqrestore(&atchan->lock, flags);
164 } 166 }
165} 167}
166 168
@@ -299,7 +301,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
299 301
300 /* for cyclic transfers, 302 /* for cyclic transfers,
301 * no need to replay callback function while stopping */ 303 * no need to replay callback function while stopping */
302 if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) { 304 if (!atc_chan_is_cyclic(atchan)) {
303 dma_async_tx_callback callback = txd->callback; 305 dma_async_tx_callback callback = txd->callback;
304 void *param = txd->callback_param; 306 void *param = txd->callback_param;
305 307
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
471static void atc_tasklet(unsigned long data) 473static void atc_tasklet(unsigned long data)
472{ 474{
473 struct at_dma_chan *atchan = (struct at_dma_chan *)data; 475 struct at_dma_chan *atchan = (struct at_dma_chan *)data;
476 unsigned long flags;
474 477
475 spin_lock(&atchan->lock); 478 spin_lock_irqsave(&atchan->lock, flags);
476 if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status)) 479 if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
477 atc_handle_error(atchan); 480 atc_handle_error(atchan);
478 else if (test_bit(ATC_IS_CYCLIC, &atchan->status)) 481 else if (atc_chan_is_cyclic(atchan))
479 atc_handle_cyclic(atchan); 482 atc_handle_cyclic(atchan);
480 else 483 else
481 atc_advance_work(atchan); 484 atc_advance_work(atchan);
482 485
483 spin_unlock(&atchan->lock); 486 spin_unlock_irqrestore(&atchan->lock, flags);
484} 487}
485 488
486static irqreturn_t at_dma_interrupt(int irq, void *dev_id) 489static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
@@ -539,8 +542,9 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
539 struct at_desc *desc = txd_to_at_desc(tx); 542 struct at_desc *desc = txd_to_at_desc(tx);
540 struct at_dma_chan *atchan = to_at_dma_chan(tx->chan); 543 struct at_dma_chan *atchan = to_at_dma_chan(tx->chan);
541 dma_cookie_t cookie; 544 dma_cookie_t cookie;
545 unsigned long flags;
542 546
543 spin_lock_bh(&atchan->lock); 547 spin_lock_irqsave(&atchan->lock, flags);
544 cookie = atc_assign_cookie(atchan, desc); 548 cookie = atc_assign_cookie(atchan, desc);
545 549
546 if (list_empty(&atchan->active_list)) { 550 if (list_empty(&atchan->active_list)) {
@@ -554,7 +558,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
554 list_add_tail(&desc->desc_node, &atchan->queue); 558 list_add_tail(&desc->desc_node, &atchan->queue);
555 } 559 }
556 560
557 spin_unlock_bh(&atchan->lock); 561 spin_unlock_irqrestore(&atchan->lock, flags);
558 562
559 return cookie; 563 return cookie;
560} 564}
@@ -927,28 +931,29 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
927 struct at_dma_chan *atchan = to_at_dma_chan(chan); 931 struct at_dma_chan *atchan = to_at_dma_chan(chan);
928 struct at_dma *atdma = to_at_dma(chan->device); 932 struct at_dma *atdma = to_at_dma(chan->device);
929 int chan_id = atchan->chan_common.chan_id; 933 int chan_id = atchan->chan_common.chan_id;
934 unsigned long flags;
930 935
931 LIST_HEAD(list); 936 LIST_HEAD(list);
932 937
933 dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd); 938 dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd);
934 939
935 if (cmd == DMA_PAUSE) { 940 if (cmd == DMA_PAUSE) {
936 spin_lock_bh(&atchan->lock); 941 spin_lock_irqsave(&atchan->lock, flags);
937 942
938 dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id)); 943 dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
939 set_bit(ATC_IS_PAUSED, &atchan->status); 944 set_bit(ATC_IS_PAUSED, &atchan->status);
940 945
941 spin_unlock_bh(&atchan->lock); 946 spin_unlock_irqrestore(&atchan->lock, flags);
942 } else if (cmd == DMA_RESUME) { 947 } else if (cmd == DMA_RESUME) {
943 if (!test_bit(ATC_IS_PAUSED, &atchan->status)) 948 if (!atc_chan_is_paused(atchan))
944 return 0; 949 return 0;
945 950
946 spin_lock_bh(&atchan->lock); 951 spin_lock_irqsave(&atchan->lock, flags);
947 952
948 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id)); 953 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
949 clear_bit(ATC_IS_PAUSED, &atchan->status); 954 clear_bit(ATC_IS_PAUSED, &atchan->status);
950 955
951 spin_unlock_bh(&atchan->lock); 956 spin_unlock_irqrestore(&atchan->lock, flags);
952 } else if (cmd == DMA_TERMINATE_ALL) { 957 } else if (cmd == DMA_TERMINATE_ALL) {
953 struct at_desc *desc, *_desc; 958 struct at_desc *desc, *_desc;
954 /* 959 /*
@@ -957,7 +962,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
957 * channel. We still have to poll the channel enable bit due 962 * channel. We still have to poll the channel enable bit due
958 * to AHB/HSB limitations. 963 * to AHB/HSB limitations.
959 */ 964 */
960 spin_lock_bh(&atchan->lock); 965 spin_lock_irqsave(&atchan->lock, flags);
961 966
962 /* disabling channel: must also remove suspend state */ 967 /* disabling channel: must also remove suspend state */
963 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask); 968 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
@@ -978,7 +983,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
978 /* if channel dedicated to cyclic operations, free it */ 983 /* if channel dedicated to cyclic operations, free it */
979 clear_bit(ATC_IS_CYCLIC, &atchan->status); 984 clear_bit(ATC_IS_CYCLIC, &atchan->status);
980 985
981 spin_unlock_bh(&atchan->lock); 986 spin_unlock_irqrestore(&atchan->lock, flags);
982 } else { 987 } else {
983 return -ENXIO; 988 return -ENXIO;
984 } 989 }
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan,
1004 struct at_dma_chan *atchan = to_at_dma_chan(chan); 1009 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1005 dma_cookie_t last_used; 1010 dma_cookie_t last_used;
1006 dma_cookie_t last_complete; 1011 dma_cookie_t last_complete;
1012 unsigned long flags;
1007 enum dma_status ret; 1013 enum dma_status ret;
1008 1014
1009 spin_lock_bh(&atchan->lock); 1015 spin_lock_irqsave(&atchan->lock, flags);
1010 1016
1011 last_complete = atchan->completed_cookie; 1017 last_complete = atchan->completed_cookie;
1012 last_used = chan->cookie; 1018 last_used = chan->cookie;
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan,
1021 ret = dma_async_is_complete(cookie, last_complete, last_used); 1027 ret = dma_async_is_complete(cookie, last_complete, last_used);
1022 } 1028 }
1023 1029
1024 spin_unlock_bh(&atchan->lock); 1030 spin_unlock_irqrestore(&atchan->lock, flags);
1025 1031
1026 if (ret != DMA_SUCCESS) 1032 if (ret != DMA_SUCCESS)
1027 dma_set_tx_state(txstate, last_complete, last_used, 1033 dma_set_tx_state(txstate, last_complete, last_used,
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan,
1029 else 1035 else
1030 dma_set_tx_state(txstate, last_complete, last_used, 0); 1036 dma_set_tx_state(txstate, last_complete, last_used, 0);
1031 1037
1032 if (test_bit(ATC_IS_PAUSED, &atchan->status)) 1038 if (atc_chan_is_paused(atchan))
1033 ret = DMA_PAUSED; 1039 ret = DMA_PAUSED;
1034 1040
1035 dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n", 1041 dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n",
@@ -1046,18 +1052,19 @@ atc_tx_status(struct dma_chan *chan,
1046static void atc_issue_pending(struct dma_chan *chan) 1052static void atc_issue_pending(struct dma_chan *chan)
1047{ 1053{
1048 struct at_dma_chan *atchan = to_at_dma_chan(chan); 1054 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1055 unsigned long flags;
1049 1056
1050 dev_vdbg(chan2dev(chan), "issue_pending\n"); 1057 dev_vdbg(chan2dev(chan), "issue_pending\n");
1051 1058
1052 /* Not needed for cyclic transfers */ 1059 /* Not needed for cyclic transfers */
1053 if (test_bit(ATC_IS_CYCLIC, &atchan->status)) 1060 if (atc_chan_is_cyclic(atchan))
1054 return; 1061 return;
1055 1062
1056 spin_lock_bh(&atchan->lock); 1063 spin_lock_irqsave(&atchan->lock, flags);
1057 if (!atc_chan_is_enabled(atchan)) { 1064 if (!atc_chan_is_enabled(atchan)) {
1058 atc_advance_work(atchan); 1065 atc_advance_work(atchan);
1059 } 1066 }
1060 spin_unlock_bh(&atchan->lock); 1067 spin_unlock_irqrestore(&atchan->lock, flags);
1061} 1068}
1062 1069
1063/** 1070/**
@@ -1073,6 +1080,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
1073 struct at_dma *atdma = to_at_dma(chan->device); 1080 struct at_dma *atdma = to_at_dma(chan->device);
1074 struct at_desc *desc; 1081 struct at_desc *desc;
1075 struct at_dma_slave *atslave; 1082 struct at_dma_slave *atslave;
1083 unsigned long flags;
1076 int i; 1084 int i;
1077 u32 cfg; 1085 u32 cfg;
1078 LIST_HEAD(tmp_list); 1086 LIST_HEAD(tmp_list);
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
1116 list_add_tail(&desc->desc_node, &tmp_list); 1124 list_add_tail(&desc->desc_node, &tmp_list);
1117 } 1125 }
1118 1126
1119 spin_lock_bh(&atchan->lock); 1127 spin_lock_irqsave(&atchan->lock, flags);
1120 atchan->descs_allocated = i; 1128 atchan->descs_allocated = i;
1121 list_splice(&tmp_list, &atchan->free_list); 1129 list_splice(&tmp_list, &atchan->free_list);
1122 atchan->completed_cookie = chan->cookie = 1; 1130 atchan->completed_cookie = chan->cookie = 1;
1123 spin_unlock_bh(&atchan->lock); 1131 spin_unlock_irqrestore(&atchan->lock, flags);
1124 1132
1125 /* channel parameters */ 1133 /* channel parameters */
1126 channel_writel(atchan, CFG, cfg); 1134 channel_writel(atchan, CFG, cfg);
@@ -1260,12 +1268,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
1260 1268
1261 /* initialize channels related values */ 1269 /* initialize channels related values */
1262 INIT_LIST_HEAD(&atdma->dma_common.channels); 1270 INIT_LIST_HEAD(&atdma->dma_common.channels);
1263 for (i = 0; i < pdata->nr_channels; i++, atdma->dma_common.chancnt++) { 1271 for (i = 0; i < pdata->nr_channels; i++) {
1264 struct at_dma_chan *atchan = &atdma->chan[i]; 1272 struct at_dma_chan *atchan = &atdma->chan[i];
1265 1273
1266 atchan->chan_common.device = &atdma->dma_common; 1274 atchan->chan_common.device = &atdma->dma_common;
1267 atchan->chan_common.cookie = atchan->completed_cookie = 1; 1275 atchan->chan_common.cookie = atchan->completed_cookie = 1;
1268 atchan->chan_common.chan_id = i;
1269 list_add_tail(&atchan->chan_common.device_node, 1276 list_add_tail(&atchan->chan_common.device_node,
1270 &atdma->dma_common.channels); 1277 &atdma->dma_common.channels);
1271 1278
@@ -1293,22 +1300,20 @@ static int __init at_dma_probe(struct platform_device *pdev)
1293 if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask)) 1300 if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
1294 atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy; 1301 atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
1295 1302
1296 if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) 1303 if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
1297 atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; 1304 atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
1298 1305 /* controller can do slave DMA: can trigger cyclic transfers */
1299 if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask)) 1306 dma_cap_set(DMA_CYCLIC, atdma->dma_common.cap_mask);
1300 atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic; 1307 atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic;
1301
1302 if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ||
1303 dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
1304 atdma->dma_common.device_control = atc_control; 1308 atdma->dma_common.device_control = atc_control;
1309 }
1305 1310
1306 dma_writel(atdma, EN, AT_DMA_ENABLE); 1311 dma_writel(atdma, EN, AT_DMA_ENABLE);
1307 1312
1308 dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n", 1313 dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
1309 dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "", 1314 dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
1310 dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", 1315 dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
1311 atdma->dma_common.chancnt); 1316 pdata->nr_channels);
1312 1317
1313 dma_async_device_register(&atdma->dma_common); 1318 dma_async_device_register(&atdma->dma_common);
1314 1319
@@ -1377,27 +1382,112 @@ static void at_dma_shutdown(struct platform_device *pdev)
1377 clk_disable(atdma->clk); 1382 clk_disable(atdma->clk);
1378} 1383}
1379 1384
1385static int at_dma_prepare(struct device *dev)
1386{
1387 struct platform_device *pdev = to_platform_device(dev);
1388 struct at_dma *atdma = platform_get_drvdata(pdev);
1389 struct dma_chan *chan, *_chan;
1390
1391 list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1392 device_node) {
1393 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1394 /* wait for transaction completion (except in cyclic case) */
1395 if (atc_chan_is_enabled(atchan) && !atc_chan_is_cyclic(atchan))
1396 return -EAGAIN;
1397 }
1398 return 0;
1399}
1400
1401static void atc_suspend_cyclic(struct at_dma_chan *atchan)
1402{
1403 struct dma_chan *chan = &atchan->chan_common;
1404
1405 /* Channel should be paused by user
1406 * do it anyway even if it is not done already */
1407 if (!atc_chan_is_paused(atchan)) {
1408 dev_warn(chan2dev(chan),
1409 "cyclic channel not paused, should be done by channel user\n");
1410 atc_control(chan, DMA_PAUSE, 0);
1411 }
1412
1413 /* now preserve additional data for cyclic operations */
1414 /* next descriptor address in the cyclic list */
1415 atchan->save_dscr = channel_readl(atchan, DSCR);
1416
1417 vdbg_dump_regs(atchan);
1418}
1419
1380static int at_dma_suspend_noirq(struct device *dev) 1420static int at_dma_suspend_noirq(struct device *dev)
1381{ 1421{
1382 struct platform_device *pdev = to_platform_device(dev); 1422 struct platform_device *pdev = to_platform_device(dev);
1383 struct at_dma *atdma = platform_get_drvdata(pdev); 1423 struct at_dma *atdma = platform_get_drvdata(pdev);
1424 struct dma_chan *chan, *_chan;
1384 1425
1385 at_dma_off(platform_get_drvdata(pdev)); 1426 /* preserve data */
1427 list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1428 device_node) {
1429 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1430
1431 if (atc_chan_is_cyclic(atchan))
1432 atc_suspend_cyclic(atchan);
1433 atchan->save_cfg = channel_readl(atchan, CFG);
1434 }
1435 atdma->save_imr = dma_readl(atdma, EBCIMR);
1436
1437 /* disable DMA controller */
1438 at_dma_off(atdma);
1386 clk_disable(atdma->clk); 1439 clk_disable(atdma->clk);
1387 return 0; 1440 return 0;
1388} 1441}
1389 1442
1443static void atc_resume_cyclic(struct at_dma_chan *atchan)
1444{
1445 struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
1446
1447 /* restore channel status for cyclic descriptors list:
1448 * next descriptor in the cyclic list at the time of suspend */
1449 channel_writel(atchan, SADDR, 0);
1450 channel_writel(atchan, DADDR, 0);
1451 channel_writel(atchan, CTRLA, 0);
1452 channel_writel(atchan, CTRLB, 0);
1453 channel_writel(atchan, DSCR, atchan->save_dscr);
1454 dma_writel(atdma, CHER, atchan->mask);
1455
1456 /* channel pause status should be removed by channel user
1457 * We cannot take the initiative to do it here */
1458
1459 vdbg_dump_regs(atchan);
1460}
1461
1390static int at_dma_resume_noirq(struct device *dev) 1462static int at_dma_resume_noirq(struct device *dev)
1391{ 1463{
1392 struct platform_device *pdev = to_platform_device(dev); 1464 struct platform_device *pdev = to_platform_device(dev);
1393 struct at_dma *atdma = platform_get_drvdata(pdev); 1465 struct at_dma *atdma = platform_get_drvdata(pdev);
1466 struct dma_chan *chan, *_chan;
1394 1467
1468 /* bring back DMA controller */
1395 clk_enable(atdma->clk); 1469 clk_enable(atdma->clk);
1396 dma_writel(atdma, EN, AT_DMA_ENABLE); 1470 dma_writel(atdma, EN, AT_DMA_ENABLE);
1471
1472 /* clear any pending interrupt */
1473 while (dma_readl(atdma, EBCISR))
1474 cpu_relax();
1475
1476 /* restore saved data */
1477 dma_writel(atdma, EBCIER, atdma->save_imr);
1478 list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1479 device_node) {
1480 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1481
1482 channel_writel(atchan, CFG, atchan->save_cfg);
1483 if (atc_chan_is_cyclic(atchan))
1484 atc_resume_cyclic(atchan);
1485 }
1397 return 0; 1486 return 0;
1398} 1487}
1399 1488
1400static const struct dev_pm_ops at_dma_dev_pm_ops = { 1489static const struct dev_pm_ops at_dma_dev_pm_ops = {
1490 .prepare = at_dma_prepare,
1401 .suspend_noirq = at_dma_suspend_noirq, 1491 .suspend_noirq = at_dma_suspend_noirq,
1402 .resume_noirq = at_dma_resume_noirq, 1492 .resume_noirq = at_dma_resume_noirq,
1403}; 1493};
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index 087dbf1dd39c..aa4c9aebab7c 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -204,6 +204,9 @@ enum atc_status {
204 * @status: transmit status information from irq/prep* functions 204 * @status: transmit status information from irq/prep* functions
205 * to tasklet (use atomic operations) 205 * to tasklet (use atomic operations)
206 * @tasklet: bottom half to finish transaction work 206 * @tasklet: bottom half to finish transaction work
207 * @save_cfg: configuration register that is saved on suspend/resume cycle
208 * @save_dscr: for cyclic operations, preserve next descriptor address in
209 * the cyclic list on suspend/resume cycle
207 * @lock: serializes enqueue/dequeue operations to descriptors lists 210 * @lock: serializes enqueue/dequeue operations to descriptors lists
208 * @completed_cookie: identifier for the most recently completed operation 211 * @completed_cookie: identifier for the most recently completed operation
209 * @active_list: list of descriptors dmaengine is being running on 212 * @active_list: list of descriptors dmaengine is being running on
@@ -218,6 +221,8 @@ struct at_dma_chan {
218 u8 mask; 221 u8 mask;
219 unsigned long status; 222 unsigned long status;
220 struct tasklet_struct tasklet; 223 struct tasklet_struct tasklet;
224 u32 save_cfg;
225 u32 save_dscr;
221 226
222 spinlock_t lock; 227 spinlock_t lock;
223 228
@@ -248,6 +253,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
248 * @chan_common: common dmaengine dma_device object members 253 * @chan_common: common dmaengine dma_device object members
249 * @ch_regs: memory mapped register base 254 * @ch_regs: memory mapped register base
250 * @clk: dma controller clock 255 * @clk: dma controller clock
256 * @save_imr: interrupt mask register that is saved on suspend/resume cycle
251 * @all_chan_mask: all channels availlable in a mask 257 * @all_chan_mask: all channels availlable in a mask
252 * @dma_desc_pool: base of DMA descriptor region (DMA address) 258 * @dma_desc_pool: base of DMA descriptor region (DMA address)
253 * @chan: channels table to store at_dma_chan structures 259 * @chan: channels table to store at_dma_chan structures
@@ -256,6 +262,7 @@ struct at_dma {
256 struct dma_device dma_common; 262 struct dma_device dma_common;
257 void __iomem *regs; 263 void __iomem *regs;
258 struct clk *clk; 264 struct clk *clk;
265 u32 save_imr;
259 266
260 u8 all_chan_mask; 267 u8 all_chan_mask;
261 268
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
355 return !!(dma_readl(atdma, CHSR) & atchan->mask); 362 return !!(dma_readl(atdma, CHSR) & atchan->mask);
356} 363}
357 364
365/**
366 * atc_chan_is_paused - test channel pause/resume status
367 * @atchan: channel we want to test status
368 */
369static inline int atc_chan_is_paused(struct at_dma_chan *atchan)
370{
371 return test_bit(ATC_IS_PAUSED, &atchan->status);
372}
373
374/**
375 * atc_chan_is_cyclic - test if given channel has cyclic property set
376 * @atchan: channel we want to test status
377 */
378static inline int atc_chan_is_cyclic(struct at_dma_chan *atchan)
379{
380 return test_bit(ATC_IS_CYCLIC, &atchan->status);
381}
358 382
359/** 383/**
360 * set_desc_eol - set end-of-link to descriptor so it will end transfer 384 * set_desc_eol - set end-of-link to descriptor so it will end transfer
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 765f5ff22304..eb1d8641cf5c 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -10,6 +10,7 @@
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <linux/dmaengine.h> 12#include <linux/dmaengine.h>
13#include <linux/freezer.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/kthread.h> 15#include <linux/kthread.h>
15#include <linux/module.h> 16#include <linux/module.h>
@@ -251,6 +252,7 @@ static int dmatest_func(void *data)
251 int i; 252 int i;
252 253
253 thread_name = current->comm; 254 thread_name = current->comm;
255 set_freezable_with_signal();
254 256
255 ret = -ENOMEM; 257 ret = -ENOMEM;
256 258
@@ -305,7 +307,8 @@ static int dmatest_func(void *data)
305 dma_addr_t dma_srcs[src_cnt]; 307 dma_addr_t dma_srcs[src_cnt];
306 dma_addr_t dma_dsts[dst_cnt]; 308 dma_addr_t dma_dsts[dst_cnt];
307 struct completion cmp; 309 struct completion cmp;
308 unsigned long tmo = msecs_to_jiffies(timeout); 310 unsigned long start, tmo, end = 0 /* compiler... */;
311 bool reload = true;
309 u8 align = 0; 312 u8 align = 0;
310 313
311 total_tests++; 314 total_tests++;
@@ -404,7 +407,17 @@ static int dmatest_func(void *data)
404 } 407 }
405 dma_async_issue_pending(chan); 408 dma_async_issue_pending(chan);
406 409
407 tmo = wait_for_completion_timeout(&cmp, tmo); 410 do {
411 start = jiffies;
412 if (reload)
413 end = start + msecs_to_jiffies(timeout);
414 else if (end <= start)
415 end = start + 1;
416 tmo = wait_for_completion_interruptible_timeout(&cmp,
417 end - start);
418 reload = try_to_freeze();
419 } while (tmo == -ERESTARTSYS);
420
408 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); 421 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
409 422
410 if (tmo == 0) { 423 if (tmo == 0) {
@@ -477,6 +490,8 @@ err_srcs:
477 pr_notice("%s: terminating after %u tests, %u failures (status %d)\n", 490 pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
478 thread_name, total_tests, failed_tests, ret); 491 thread_name, total_tests, failed_tests, ret);
479 492
493 /* terminate all transfers on specified channels */
494 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
480 if (iterations > 0) 495 if (iterations > 0)
481 while (!kthread_should_stop()) { 496 while (!kthread_should_stop()) {
482 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit); 497 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
@@ -499,6 +514,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
499 list_del(&thread->node); 514 list_del(&thread->node);
500 kfree(thread); 515 kfree(thread);
501 } 516 }
517
518 /* terminate all transfers on specified channels */
519 dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0);
520
502 kfree(dtc); 521 kfree(dtc);
503} 522}
504 523
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 4d180ca9a1d8..9bfd6d360718 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1407,12 +1407,11 @@ static int __init dw_probe(struct platform_device *pdev)
1407 dw->all_chan_mask = (1 << pdata->nr_channels) - 1; 1407 dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
1408 1408
1409 INIT_LIST_HEAD(&dw->dma.channels); 1409 INIT_LIST_HEAD(&dw->dma.channels);
1410 for (i = 0; i < pdata->nr_channels; i++, dw->dma.chancnt++) { 1410 for (i = 0; i < pdata->nr_channels; i++) {
1411 struct dw_dma_chan *dwc = &dw->chan[i]; 1411 struct dw_dma_chan *dwc = &dw->chan[i];
1412 1412
1413 dwc->chan.device = &dw->dma; 1413 dwc->chan.device = &dw->dma;
1414 dwc->chan.cookie = dwc->completed = 1; 1414 dwc->chan.cookie = dwc->completed = 1;
1415 dwc->chan.chan_id = i;
1416 if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING) 1415 if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
1417 list_add_tail(&dwc->chan.device_node, 1416 list_add_tail(&dwc->chan.device_node,
1418 &dw->dma.channels); 1417 &dw->dma.channels);
@@ -1468,7 +1467,7 @@ static int __init dw_probe(struct platform_device *pdev)
1468 dma_writel(dw, CFG, DW_CFG_DMA_EN); 1467 dma_writel(dw, CFG, DW_CFG_DMA_EN);
1469 1468
1470 printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n", 1469 printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
1471 dev_name(&pdev->dev), dw->dma.chancnt); 1470 dev_name(&pdev->dev), pdata->nr_channels);
1472 1471
1473 dma_async_device_register(&dw->dma); 1472 dma_async_device_register(&dw->dma);
1474 1473
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 5d7a49bd7c26..b47e2b803faf 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/dmaengine.h> 24#include <linux/dmaengine.h>
25#include <linux/module.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27 28
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index d99f71c356b5..d746899f36e1 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -14,6 +14,7 @@
14 * http://www.gnu.org/copyleft/gpl.html 14 * http://www.gnu.org/copyleft/gpl.html
15 */ 15 */
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 7bd7e98548cd..eab1fe71259e 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
@@ -318,6 +319,7 @@ struct sdma_engine {
318 dma_addr_t context_phys; 319 dma_addr_t context_phys;
319 struct dma_device dma_device; 320 struct dma_device dma_device;
320 struct clk *clk; 321 struct clk *clk;
322 struct mutex channel_0_lock;
321 struct sdma_script_start_addrs *script_addrs; 323 struct sdma_script_start_addrs *script_addrs;
322}; 324};
323 325
@@ -415,11 +417,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
415 dma_addr_t buf_phys; 417 dma_addr_t buf_phys;
416 int ret; 418 int ret;
417 419
420 mutex_lock(&sdma->channel_0_lock);
421
418 buf_virt = dma_alloc_coherent(NULL, 422 buf_virt = dma_alloc_coherent(NULL,
419 size, 423 size,
420 &buf_phys, GFP_KERNEL); 424 &buf_phys, GFP_KERNEL);
421 if (!buf_virt) 425 if (!buf_virt) {
422 return -ENOMEM; 426 ret = -ENOMEM;
427 goto err_out;
428 }
423 429
424 bd0->mode.command = C0_SETPM; 430 bd0->mode.command = C0_SETPM;
425 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; 431 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -433,6 +439,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
433 439
434 dma_free_coherent(NULL, size, buf_virt, buf_phys); 440 dma_free_coherent(NULL, size, buf_virt, buf_phys);
435 441
442err_out:
443 mutex_unlock(&sdma->channel_0_lock);
444
436 return ret; 445 return ret;
437} 446}
438 447
@@ -656,6 +665,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
656 dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0); 665 dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0);
657 dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1); 666 dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1);
658 667
668 mutex_lock(&sdma->channel_0_lock);
669
659 memset(context, 0, sizeof(*context)); 670 memset(context, 0, sizeof(*context));
660 context->channel_state.pc = load_address; 671 context->channel_state.pc = load_address;
661 672
@@ -676,6 +687,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
676 687
677 ret = sdma_run_channel(&sdma->channel[0]); 688 ret = sdma_run_channel(&sdma->channel[0]);
678 689
690 mutex_unlock(&sdma->channel_0_lock);
691
679 return ret; 692 return ret;
680} 693}
681 694
@@ -1131,18 +1144,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
1131 saddr_arr[i] = addr_arr[i]; 1144 saddr_arr[i] = addr_arr[i];
1132} 1145}
1133 1146
1134static int __init sdma_get_firmware(struct sdma_engine *sdma, 1147static void sdma_load_firmware(const struct firmware *fw, void *context)
1135 const char *fw_name)
1136{ 1148{
1137 const struct firmware *fw; 1149 struct sdma_engine *sdma = context;
1138 const struct sdma_firmware_header *header; 1150 const struct sdma_firmware_header *header;
1139 int ret;
1140 const struct sdma_script_start_addrs *addr; 1151 const struct sdma_script_start_addrs *addr;
1141 unsigned short *ram_code; 1152 unsigned short *ram_code;
1142 1153
1143 ret = request_firmware(&fw, fw_name, sdma->dev); 1154 if (!fw) {
1144 if (ret) 1155 dev_err(sdma->dev, "firmware not found\n");
1145 return ret; 1156 return;
1157 }
1146 1158
1147 if (fw->size < sizeof(*header)) 1159 if (fw->size < sizeof(*header))
1148 goto err_firmware; 1160 goto err_firmware;
@@ -1172,6 +1184,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
1172 1184
1173err_firmware: 1185err_firmware:
1174 release_firmware(fw); 1186 release_firmware(fw);
1187}
1188
1189static int __init sdma_get_firmware(struct sdma_engine *sdma,
1190 const char *fw_name)
1191{
1192 int ret;
1193
1194 ret = request_firmware_nowait(THIS_MODULE,
1195 FW_ACTION_HOTPLUG, fw_name, sdma->dev,
1196 GFP_KERNEL, sdma, sdma_load_firmware);
1175 1197
1176 return ret; 1198 return ret;
1177} 1199}
@@ -1269,11 +1291,14 @@ static int __init sdma_probe(struct platform_device *pdev)
1269 struct sdma_platform_data *pdata = pdev->dev.platform_data; 1291 struct sdma_platform_data *pdata = pdev->dev.platform_data;
1270 int i; 1292 int i;
1271 struct sdma_engine *sdma; 1293 struct sdma_engine *sdma;
1294 s32 *saddr_arr;
1272 1295
1273 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); 1296 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
1274 if (!sdma) 1297 if (!sdma)
1275 return -ENOMEM; 1298 return -ENOMEM;
1276 1299
1300 mutex_init(&sdma->channel_0_lock);
1301
1277 sdma->dev = &pdev->dev; 1302 sdma->dev = &pdev->dev;
1278 1303
1279 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1304 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1310,6 +1335,11 @@ static int __init sdma_probe(struct platform_device *pdev)
1310 goto err_alloc; 1335 goto err_alloc;
1311 } 1336 }
1312 1337
1338 /* initially no scripts available */
1339 saddr_arr = (s32 *)sdma->script_addrs;
1340 for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
1341 saddr_arr[i] = -EINVAL;
1342
1313 if (of_id) 1343 if (of_id)
1314 pdev->id_entry = of_id->data; 1344 pdev->id_entry = of_id->data;
1315 sdma->devtype = pdev->id_entry->driver_data; 1345 sdma->devtype = pdev->id_entry->driver_data;
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 8a3fdd87db97..9e96c43a846a 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -115,16 +115,15 @@ DMAC1 interrupt Functions*/
115 115
116/** 116/**
117 * dmac1_mask_periphral_intr - mask the periphral interrupt 117 * dmac1_mask_periphral_intr - mask the periphral interrupt
118 * @midc: dma channel for which masking is required 118 * @mid: dma device for which masking is required
119 * 119 *
120 * Masks the DMA periphral interrupt 120 * Masks the DMA periphral interrupt
121 * this is valid for DMAC1 family controllers only 121 * this is valid for DMAC1 family controllers only
122 * This controller should have periphral mask registers already mapped 122 * This controller should have periphral mask registers already mapped
123 */ 123 */
124static void dmac1_mask_periphral_intr(struct intel_mid_dma_chan *midc) 124static void dmac1_mask_periphral_intr(struct middma_device *mid)
125{ 125{
126 u32 pimr; 126 u32 pimr;
127 struct middma_device *mid = to_middma_device(midc->chan.device);
128 127
129 if (mid->pimr_mask) { 128 if (mid->pimr_mask) {
130 pimr = readl(mid->mask_reg + LNW_PERIPHRAL_MASK); 129 pimr = readl(mid->mask_reg + LNW_PERIPHRAL_MASK);
@@ -184,7 +183,6 @@ static void enable_dma_interrupt(struct intel_mid_dma_chan *midc)
184static void disable_dma_interrupt(struct intel_mid_dma_chan *midc) 183static void disable_dma_interrupt(struct intel_mid_dma_chan *midc)
185{ 184{
186 /*Check LPE PISR, make sure fwd is disabled*/ 185 /*Check LPE PISR, make sure fwd is disabled*/
187 dmac1_mask_periphral_intr(midc);
188 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_BLOCK); 186 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_BLOCK);
189 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_TFR); 187 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_TFR);
190 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_ERR); 188 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_ERR);
@@ -1114,7 +1112,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
1114 1112
1115 midch->chan.device = &dma->common; 1113 midch->chan.device = &dma->common;
1116 midch->chan.cookie = 1; 1114 midch->chan.cookie = 1;
1117 midch->chan.chan_id = i;
1118 midch->ch_id = dma->chan_base + i; 1115 midch->ch_id = dma->chan_base + i;
1119 pr_debug("MDMA:Init CH %d, ID %d\n", i, midch->ch_id); 1116 pr_debug("MDMA:Init CH %d, ID %d\n", i, midch->ch_id);
1120 1117
@@ -1150,7 +1147,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
1150 dma_cap_set(DMA_SLAVE, dma->common.cap_mask); 1147 dma_cap_set(DMA_SLAVE, dma->common.cap_mask);
1151 dma_cap_set(DMA_PRIVATE, dma->common.cap_mask); 1148 dma_cap_set(DMA_PRIVATE, dma->common.cap_mask);
1152 dma->common.dev = &pdev->dev; 1149 dma->common.dev = &pdev->dev;
1153 dma->common.chancnt = dma->max_chan;
1154 1150
1155 dma->common.device_alloc_chan_resources = 1151 dma->common.device_alloc_chan_resources =
1156 intel_mid_dma_alloc_chan_resources; 1152 intel_mid_dma_alloc_chan_resources;
@@ -1350,6 +1346,7 @@ int dma_suspend(struct pci_dev *pci, pm_message_t state)
1350 if (device->ch[i].in_use) 1346 if (device->ch[i].in_use)
1351 return -EAGAIN; 1347 return -EAGAIN;
1352 } 1348 }
1349 dmac1_mask_periphral_intr(device);
1353 device->state = SUSPENDED; 1350 device->state = SUSPENDED;
1354 pci_save_state(pci); 1351 pci_save_state(pci);
1355 pci_disable_device(pci); 1352 pci_disable_device(pci);
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 6815905a772f..ddc2a1331822 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1307,6 +1307,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
1307 ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) { 1307 ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
1308 callback = descnew->txd.callback; 1308 callback = descnew->txd.callback;
1309 callback_param = descnew->txd.callback_param; 1309 callback_param = descnew->txd.callback_param;
1310 list_del_init(&descnew->list);
1310 spin_unlock(&ichan->lock); 1311 spin_unlock(&ichan->lock);
1311 if (callback) 1312 if (callback)
1312 callback(callback_param); 1313 callback(callback_param);
@@ -1428,39 +1429,58 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1428{ 1429{
1429 struct idmac_channel *ichan = to_idmac_chan(chan); 1430 struct idmac_channel *ichan = to_idmac_chan(chan);
1430 struct idmac *idmac = to_idmac(chan->device); 1431 struct idmac *idmac = to_idmac(chan->device);
1432 struct ipu *ipu = to_ipu(idmac);
1433 struct list_head *list, *tmp;
1431 unsigned long flags; 1434 unsigned long flags;
1432 int i; 1435 int i;
1433 1436
1434 /* Only supports DMA_TERMINATE_ALL */ 1437 switch (cmd) {
1435 if (cmd != DMA_TERMINATE_ALL) 1438 case DMA_PAUSE:
1436 return -ENXIO; 1439 spin_lock_irqsave(&ipu->lock, flags);
1440 ipu_ic_disable_task(ipu, chan->chan_id);
1437 1441
1438 ipu_disable_channel(idmac, ichan, 1442 /* Return all descriptors into "prepared" state */
1439 ichan->status >= IPU_CHANNEL_ENABLED); 1443 list_for_each_safe(list, tmp, &ichan->queue)
1444 list_del_init(list);
1440 1445
1441 tasklet_disable(&to_ipu(idmac)->tasklet); 1446 ichan->sg[0] = NULL;
1447 ichan->sg[1] = NULL;
1442 1448
1443 /* ichan->queue is modified in ISR, have to spinlock */ 1449 spin_unlock_irqrestore(&ipu->lock, flags);
1444 spin_lock_irqsave(&ichan->lock, flags);
1445 list_splice_init(&ichan->queue, &ichan->free_list);
1446 1450
1447 if (ichan->desc) 1451 ichan->status = IPU_CHANNEL_INITIALIZED;
1448 for (i = 0; i < ichan->n_tx_desc; i++) { 1452 break;
1449 struct idmac_tx_desc *desc = ichan->desc + i; 1453 case DMA_TERMINATE_ALL:
1450 if (list_empty(&desc->list)) 1454 ipu_disable_channel(idmac, ichan,
1451 /* Descriptor was prepared, but not submitted */ 1455 ichan->status >= IPU_CHANNEL_ENABLED);
1452 list_add(&desc->list, &ichan->free_list);
1453 1456
1454 async_tx_clear_ack(&desc->txd); 1457 tasklet_disable(&ipu->tasklet);
1455 }
1456 1458
1457 ichan->sg[0] = NULL; 1459 /* ichan->queue is modified in ISR, have to spinlock */
1458 ichan->sg[1] = NULL; 1460 spin_lock_irqsave(&ichan->lock, flags);
1459 spin_unlock_irqrestore(&ichan->lock, flags); 1461 list_splice_init(&ichan->queue, &ichan->free_list);
1460 1462
1461 tasklet_enable(&to_ipu(idmac)->tasklet); 1463 if (ichan->desc)
1464 for (i = 0; i < ichan->n_tx_desc; i++) {
1465 struct idmac_tx_desc *desc = ichan->desc + i;
1466 if (list_empty(&desc->list))
1467 /* Descriptor was prepared, but not submitted */
1468 list_add(&desc->list, &ichan->free_list);
1462 1469
1463 ichan->status = IPU_CHANNEL_INITIALIZED; 1470 async_tx_clear_ack(&desc->txd);
1471 }
1472
1473 ichan->sg[0] = NULL;
1474 ichan->sg[1] = NULL;
1475 spin_unlock_irqrestore(&ichan->lock, flags);
1476
1477 tasklet_enable(&ipu->tasklet);
1478
1479 ichan->status = IPU_CHANNEL_INITIALIZED;
1480 break;
1481 default:
1482 return -ENOSYS;
1483 }
1464 1484
1465 return 0; 1485 return 0;
1466} 1486}
@@ -1663,7 +1683,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
1663 struct idmac_channel *ichan = ipu->channel + i; 1683 struct idmac_channel *ichan = ipu->channel + i;
1664 1684
1665 idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0); 1685 idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
1666 idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
1667 } 1686 }
1668 1687
1669 dma_async_device_unregister(&idmac->dma); 1688 dma_async_device_unregister(&idmac->dma);
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index b9bae94f2015..8ba4edc6185e 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -741,7 +741,6 @@ static int __devinit mpc_dma_probe(struct platform_device *op)
741 mchan = &mdma->channels[i]; 741 mchan = &mdma->channels[i];
742 742
743 mchan->chan.device = dma; 743 mchan->chan.device = dma;
744 mchan->chan.chan_id = i;
745 mchan->chan.cookie = 1; 744 mchan->chan.cookie = 1;
746 mchan->completed_cookie = mchan->chan.cookie; 745 mchan->completed_cookie = mchan->chan.cookie;
747 746
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index be641cbd36fc..b4588bdd98bb 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -130,6 +130,23 @@ struct mxs_dma_engine {
130 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; 130 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
131}; 131};
132 132
133static inline void mxs_dma_clkgate(struct mxs_dma_chan *mxs_chan, int enable)
134{
135 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
136 int chan_id = mxs_chan->chan.chan_id;
137 int set_clr = enable ? MXS_CLR_ADDR : MXS_SET_ADDR;
138
139 /* enable apbh channel clock */
140 if (dma_is_apbh()) {
141 if (apbh_is_old())
142 writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
143 mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
144 else
145 writel(1 << chan_id,
146 mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
147 }
148}
149
133static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan) 150static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
134{ 151{
135 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 152 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -148,38 +165,21 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
148 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 165 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
149 int chan_id = mxs_chan->chan.chan_id; 166 int chan_id = mxs_chan->chan.chan_id;
150 167
168 /* clkgate needs to be enabled before writing other registers */
169 mxs_dma_clkgate(mxs_chan, 1);
170
151 /* set cmd_addr up */ 171 /* set cmd_addr up */
152 writel(mxs_chan->ccw_phys, 172 writel(mxs_chan->ccw_phys,
153 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id)); 173 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id));
154 174
155 /* enable apbh channel clock */
156 if (dma_is_apbh()) {
157 if (apbh_is_old())
158 writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
159 mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
160 else
161 writel(1 << chan_id,
162 mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
163 }
164
165 /* write 1 to SEMA to kick off the channel */ 175 /* write 1 to SEMA to kick off the channel */
166 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id)); 176 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id));
167} 177}
168 178
169static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan) 179static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
170{ 180{
171 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
172 int chan_id = mxs_chan->chan.chan_id;
173
174 /* disable apbh channel clock */ 181 /* disable apbh channel clock */
175 if (dma_is_apbh()) { 182 mxs_dma_clkgate(mxs_chan, 0);
176 if (apbh_is_old())
177 writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
178 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
179 else
180 writel(1 << chan_id,
181 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
182 }
183 183
184 mxs_chan->status = DMA_SUCCESS; 184 mxs_chan->status = DMA_SUCCESS;
185} 185}
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
338 if (ret) 338 if (ret)
339 goto err_clk; 339 goto err_clk;
340 340
341 /* clkgate needs to be enabled for reset to finish */
342 mxs_dma_clkgate(mxs_chan, 1);
341 mxs_dma_reset_chan(mxs_chan); 343 mxs_dma_reset_chan(mxs_chan);
344 mxs_dma_clkgate(mxs_chan, 0);
342 345
343 dma_async_tx_descriptor_init(&mxs_chan->desc, chan); 346 dma_async_tx_descriptor_init(&mxs_chan->desc, chan);
344 mxs_chan->desc.tx_submit = mxs_dma_tx_submit; 347 mxs_chan->desc.tx_submit = mxs_dma_tx_submit;
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 1ac8d4b580b7..a6d0e3dbed07 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -60,7 +60,7 @@
60#define DMA_DESC_FOLLOW_WITHOUT_IRQ 0x2 60#define DMA_DESC_FOLLOW_WITHOUT_IRQ 0x2
61#define DMA_DESC_FOLLOW_WITH_IRQ 0x3 61#define DMA_DESC_FOLLOW_WITH_IRQ 0x3
62 62
63#define MAX_CHAN_NR 8 63#define MAX_CHAN_NR 12
64 64
65#define DMA_MASK_CTL0_MODE 0x33333333 65#define DMA_MASK_CTL0_MODE 0x33333333
66#define DMA_MASK_CTL2_MODE 0x00003333 66#define DMA_MASK_CTL2_MODE 0x00003333
@@ -872,8 +872,7 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
872 int i; 872 int i;
873 873
874 nr_channels = id->driver_data; 874 nr_channels = id->driver_data;
875 pd = kzalloc(sizeof(struct pch_dma)+ 875 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
876 sizeof(struct pch_dma_chan) * nr_channels, GFP_KERNEL);
877 if (!pd) 876 if (!pd)
878 return -ENOMEM; 877 return -ENOMEM;
879 878
@@ -926,7 +925,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
926 } 925 }
927 926
928 pd->dma.dev = &pdev->dev; 927 pd->dma.dev = &pdev->dev;
929 pd->dma.chancnt = nr_channels;
930 928
931 INIT_LIST_HEAD(&pd->dma.channels); 929 INIT_LIST_HEAD(&pd->dma.channels);
932 930
@@ -935,7 +933,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
935 933
936 pd_chan->chan.device = &pd->dma; 934 pd_chan->chan.device = &pd->dma;
937 pd_chan->chan.cookie = 1; 935 pd_chan->chan.cookie = 1;
938 pd_chan->chan.chan_id = i;
939 936
940 pd_chan->membase = &regs->desc[i]; 937 pd_chan->membase = &regs->desc[i];
941 938
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 00eee59e8b33..571041477ab2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -17,6 +17,8 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/amba/bus.h> 18#include <linux/amba/bus.h>
19#include <linux/amba/pl330.h> 19#include <linux/amba/pl330.h>
20#include <linux/pm_runtime.h>
21#include <linux/scatterlist.h>
20 22
21#define NR_DEFAULT_DESC 16 23#define NR_DEFAULT_DESC 16
22 24
@@ -68,6 +70,14 @@ struct dma_pl330_chan {
68 * NULL if the channel is available to be acquired. 70 * NULL if the channel is available to be acquired.
69 */ 71 */
70 void *pl330_chid; 72 void *pl330_chid;
73
74 /* For D-to-M and M-to-D channels */
75 int burst_sz; /* the peripheral fifo width */
76 int burst_len; /* the number of burst */
77 dma_addr_t fifo_addr;
78
79 /* for cyclic capability */
80 bool cyclic;
71}; 81};
72 82
73struct dma_pl330_dmac { 83struct dma_pl330_dmac {
@@ -83,6 +93,8 @@ struct dma_pl330_dmac {
83 93
84 /* Peripheral channels connected to this DMAC */ 94 /* Peripheral channels connected to this DMAC */
85 struct dma_pl330_chan *peripherals; /* keep at end */ 95 struct dma_pl330_chan *peripherals; /* keep at end */
96
97 struct clk *clk;
86}; 98};
87 99
88struct dma_pl330_desc { 100struct dma_pl330_desc {
@@ -152,6 +164,31 @@ static inline void free_desc_list(struct list_head *list)
152 spin_unlock_irqrestore(&pdmac->pool_lock, flags); 164 spin_unlock_irqrestore(&pdmac->pool_lock, flags);
153} 165}
154 166
167static inline void handle_cyclic_desc_list(struct list_head *list)
168{
169 struct dma_pl330_desc *desc;
170 struct dma_pl330_chan *pch;
171 unsigned long flags;
172
173 if (list_empty(list))
174 return;
175
176 list_for_each_entry(desc, list, node) {
177 dma_async_tx_callback callback;
178
179 /* Change status to reload it */
180 desc->status = PREP;
181 pch = desc->pchan;
182 callback = desc->txd.callback;
183 if (callback)
184 callback(desc->txd.callback_param);
185 }
186
187 spin_lock_irqsave(&pch->lock, flags);
188 list_splice_tail_init(list, &pch->work_list);
189 spin_unlock_irqrestore(&pch->lock, flags);
190}
191
155static inline void fill_queue(struct dma_pl330_chan *pch) 192static inline void fill_queue(struct dma_pl330_chan *pch)
156{ 193{
157 struct dma_pl330_desc *desc; 194 struct dma_pl330_desc *desc;
@@ -205,7 +242,10 @@ static void pl330_tasklet(unsigned long data)
205 242
206 spin_unlock_irqrestore(&pch->lock, flags); 243 spin_unlock_irqrestore(&pch->lock, flags);
207 244
208 free_desc_list(&list); 245 if (pch->cyclic)
246 handle_cyclic_desc_list(&list);
247 else
248 free_desc_list(&list);
209} 249}
210 250
211static void dma_pl330_rqcb(void *token, enum pl330_op_err err) 251static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
@@ -236,6 +276,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
236 spin_lock_irqsave(&pch->lock, flags); 276 spin_lock_irqsave(&pch->lock, flags);
237 277
238 pch->completed = chan->cookie = 1; 278 pch->completed = chan->cookie = 1;
279 pch->cyclic = false;
239 280
240 pch->pl330_chid = pl330_request_channel(&pdmac->pif); 281 pch->pl330_chid = pl330_request_channel(&pdmac->pif);
241 if (!pch->pl330_chid) { 282 if (!pch->pl330_chid) {
@@ -253,25 +294,52 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
253static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg) 294static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
254{ 295{
255 struct dma_pl330_chan *pch = to_pchan(chan); 296 struct dma_pl330_chan *pch = to_pchan(chan);
256 struct dma_pl330_desc *desc; 297 struct dma_pl330_desc *desc, *_dt;
257 unsigned long flags; 298 unsigned long flags;
299 struct dma_pl330_dmac *pdmac = pch->dmac;
300 struct dma_slave_config *slave_config;
301 LIST_HEAD(list);
258 302
259 /* Only supports DMA_TERMINATE_ALL */ 303 switch (cmd) {
260 if (cmd != DMA_TERMINATE_ALL) 304 case DMA_TERMINATE_ALL:
261 return -ENXIO; 305 spin_lock_irqsave(&pch->lock, flags);
262
263 spin_lock_irqsave(&pch->lock, flags);
264
265 /* FLUSH the PL330 Channel thread */
266 pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
267 306
268 /* Mark all desc done */ 307 /* FLUSH the PL330 Channel thread */
269 list_for_each_entry(desc, &pch->work_list, node) 308 pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
270 desc->status = DONE;
271 309
272 spin_unlock_irqrestore(&pch->lock, flags); 310 /* Mark all desc done */
311 list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
312 desc->status = DONE;
313 pch->completed = desc->txd.cookie;
314 list_move_tail(&desc->node, &list);
315 }
273 316
274 pl330_tasklet((unsigned long) pch); 317 list_splice_tail_init(&list, &pdmac->desc_pool);
318 spin_unlock_irqrestore(&pch->lock, flags);
319 break;
320 case DMA_SLAVE_CONFIG:
321 slave_config = (struct dma_slave_config *)arg;
322
323 if (slave_config->direction == DMA_TO_DEVICE) {
324 if (slave_config->dst_addr)
325 pch->fifo_addr = slave_config->dst_addr;
326 if (slave_config->dst_addr_width)
327 pch->burst_sz = __ffs(slave_config->dst_addr_width);
328 if (slave_config->dst_maxburst)
329 pch->burst_len = slave_config->dst_maxburst;
330 } else if (slave_config->direction == DMA_FROM_DEVICE) {
331 if (slave_config->src_addr)
332 pch->fifo_addr = slave_config->src_addr;
333 if (slave_config->src_addr_width)
334 pch->burst_sz = __ffs(slave_config->src_addr_width);
335 if (slave_config->src_maxburst)
336 pch->burst_len = slave_config->src_maxburst;
337 }
338 break;
339 default:
340 dev_err(pch->dmac->pif.dev, "Not supported command.\n");
341 return -ENXIO;
342 }
275 343
276 return 0; 344 return 0;
277} 345}
@@ -288,6 +356,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
288 pl330_release_channel(pch->pl330_chid); 356 pl330_release_channel(pch->pl330_chid);
289 pch->pl330_chid = NULL; 357 pch->pl330_chid = NULL;
290 358
359 if (pch->cyclic)
360 list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
361
291 spin_unlock_irqrestore(&pch->lock, flags); 362 spin_unlock_irqrestore(&pch->lock, flags);
292} 363}
293 364
@@ -453,7 +524,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
453 524
454 if (peri) { 525 if (peri) {
455 desc->req.rqtype = peri->rqtype; 526 desc->req.rqtype = peri->rqtype;
456 desc->req.peri = peri->peri_id; 527 desc->req.peri = pch->chan.chan_id;
457 } else { 528 } else {
458 desc->req.rqtype = MEMTOMEM; 529 desc->req.rqtype = MEMTOMEM;
459 desc->req.peri = 0; 530 desc->req.peri = 0;
@@ -524,6 +595,51 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
524 return burst_len; 595 return burst_len;
525} 596}
526 597
598static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
599 struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
600 size_t period_len, enum dma_data_direction direction)
601{
602 struct dma_pl330_desc *desc;
603 struct dma_pl330_chan *pch = to_pchan(chan);
604 dma_addr_t dst;
605 dma_addr_t src;
606
607 desc = pl330_get_desc(pch);
608 if (!desc) {
609 dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
610 __func__, __LINE__);
611 return NULL;
612 }
613
614 switch (direction) {
615 case DMA_TO_DEVICE:
616 desc->rqcfg.src_inc = 1;
617 desc->rqcfg.dst_inc = 0;
618 src = dma_addr;
619 dst = pch->fifo_addr;
620 break;
621 case DMA_FROM_DEVICE:
622 desc->rqcfg.src_inc = 0;
623 desc->rqcfg.dst_inc = 1;
624 src = pch->fifo_addr;
625 dst = dma_addr;
626 break;
627 default:
628 dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
629 __func__, __LINE__);
630 return NULL;
631 }
632
633 desc->rqcfg.brst_size = pch->burst_sz;
634 desc->rqcfg.brst_len = 1;
635
636 pch->cyclic = true;
637
638 fill_px(&desc->px, dst, src, period_len);
639
640 return &desc->txd;
641}
642
527static struct dma_async_tx_descriptor * 643static struct dma_async_tx_descriptor *
528pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, 644pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
529 dma_addr_t src, size_t len, unsigned long flags) 645 dma_addr_t src, size_t len, unsigned long flags)
@@ -579,7 +695,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
579 struct dma_pl330_peri *peri = chan->private; 695 struct dma_pl330_peri *peri = chan->private;
580 struct scatterlist *sg; 696 struct scatterlist *sg;
581 unsigned long flags; 697 unsigned long flags;
582 int i, burst_size; 698 int i;
583 dma_addr_t addr; 699 dma_addr_t addr;
584 700
585 if (unlikely(!pch || !sgl || !sg_len || !peri)) 701 if (unlikely(!pch || !sgl || !sg_len || !peri))
@@ -595,8 +711,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
595 return NULL; 711 return NULL;
596 } 712 }
597 713
598 addr = peri->fifo_addr; 714 addr = pch->fifo_addr;
599 burst_size = peri->burst_sz;
600 715
601 first = NULL; 716 first = NULL;
602 717
@@ -644,7 +759,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
644 sg_dma_address(sg), addr, sg_dma_len(sg)); 759 sg_dma_address(sg), addr, sg_dma_len(sg));
645 } 760 }
646 761
647 desc->rqcfg.brst_size = burst_size; 762 desc->rqcfg.brst_size = pch->burst_sz;
648 desc->rqcfg.brst_len = 1; 763 desc->rqcfg.brst_len = 1;
649 } 764 }
650 765
@@ -696,6 +811,30 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
696 goto probe_err1; 811 goto probe_err1;
697 } 812 }
698 813
814 pdmac->clk = clk_get(&adev->dev, "dma");
815 if (IS_ERR(pdmac->clk)) {
816 dev_err(&adev->dev, "Cannot get operation clock.\n");
817 ret = -EINVAL;
818 goto probe_err1;
819 }
820
821 amba_set_drvdata(adev, pdmac);
822
823#ifdef CONFIG_PM_RUNTIME
824 /* to use the runtime PM helper functions */
825 pm_runtime_enable(&adev->dev);
826
827 /* enable the power domain */
828 if (pm_runtime_get_sync(&adev->dev)) {
829 dev_err(&adev->dev, "failed to get runtime pm\n");
830 ret = -ENODEV;
831 goto probe_err1;
832 }
833#else
834 /* enable dma clk */
835 clk_enable(pdmac->clk);
836#endif
837
699 irq = adev->irq[0]; 838 irq = adev->irq[0];
700 ret = request_irq(irq, pl330_irq_handler, 0, 839 ret = request_irq(irq, pl330_irq_handler, 0,
701 dev_name(&adev->dev), pi); 840 dev_name(&adev->dev), pi);
@@ -732,6 +871,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
732 case MEMTODEV: 871 case MEMTODEV:
733 case DEVTOMEM: 872 case DEVTOMEM:
734 dma_cap_set(DMA_SLAVE, pd->cap_mask); 873 dma_cap_set(DMA_SLAVE, pd->cap_mask);
874 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
735 break; 875 break;
736 default: 876 default:
737 dev_err(&adev->dev, "DEVTODEV Not Supported\n"); 877 dev_err(&adev->dev, "DEVTODEV Not Supported\n");
@@ -747,11 +887,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
747 spin_lock_init(&pch->lock); 887 spin_lock_init(&pch->lock);
748 pch->pl330_chid = NULL; 888 pch->pl330_chid = NULL;
749 pch->chan.device = pd; 889 pch->chan.device = pd;
750 pch->chan.chan_id = i;
751 pch->dmac = pdmac; 890 pch->dmac = pdmac;
752 891
753 /* Add the channel to the DMAC list */ 892 /* Add the channel to the DMAC list */
754 pd->chancnt++;
755 list_add_tail(&pch->chan.device_node, &pd->channels); 893 list_add_tail(&pch->chan.device_node, &pd->channels);
756 } 894 }
757 895
@@ -760,6 +898,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
760 pd->device_alloc_chan_resources = pl330_alloc_chan_resources; 898 pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
761 pd->device_free_chan_resources = pl330_free_chan_resources; 899 pd->device_free_chan_resources = pl330_free_chan_resources;
762 pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy; 900 pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
901 pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
763 pd->device_tx_status = pl330_tx_status; 902 pd->device_tx_status = pl330_tx_status;
764 pd->device_prep_slave_sg = pl330_prep_slave_sg; 903 pd->device_prep_slave_sg = pl330_prep_slave_sg;
765 pd->device_control = pl330_control; 904 pd->device_control = pl330_control;
@@ -771,8 +910,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
771 goto probe_err4; 910 goto probe_err4;
772 } 911 }
773 912
774 amba_set_drvdata(adev, pdmac);
775
776 dev_info(&adev->dev, 913 dev_info(&adev->dev,
777 "Loaded driver for PL330 DMAC-%d\n", adev->periphid); 914 "Loaded driver for PL330 DMAC-%d\n", adev->periphid);
778 dev_info(&adev->dev, 915 dev_info(&adev->dev,
@@ -833,6 +970,13 @@ static int __devexit pl330_remove(struct amba_device *adev)
833 res = &adev->res; 970 res = &adev->res;
834 release_mem_region(res->start, resource_size(res)); 971 release_mem_region(res->start, resource_size(res));
835 972
973#ifdef CONFIG_PM_RUNTIME
974 pm_runtime_put(&adev->dev);
975 pm_runtime_disable(&adev->dev);
976#else
977 clk_disable(pdmac->clk);
978#endif
979
836 kfree(pdmac); 980 kfree(pdmac);
837 981
838 return 0; 982 return 0;
@@ -846,10 +990,49 @@ static struct amba_id pl330_ids[] = {
846 { 0, 0 }, 990 { 0, 0 },
847}; 991};
848 992
993#ifdef CONFIG_PM_RUNTIME
994static int pl330_runtime_suspend(struct device *dev)
995{
996 struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
997
998 if (!pdmac) {
999 dev_err(dev, "failed to get dmac\n");
1000 return -ENODEV;
1001 }
1002
1003 clk_disable(pdmac->clk);
1004
1005 return 0;
1006}
1007
1008static int pl330_runtime_resume(struct device *dev)
1009{
1010 struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
1011
1012 if (!pdmac) {
1013 dev_err(dev, "failed to get dmac\n");
1014 return -ENODEV;
1015 }
1016
1017 clk_enable(pdmac->clk);
1018
1019 return 0;
1020}
1021#else
1022#define pl330_runtime_suspend NULL
1023#define pl330_runtime_resume NULL
1024#endif /* CONFIG_PM_RUNTIME */
1025
1026static const struct dev_pm_ops pl330_pm_ops = {
1027 .runtime_suspend = pl330_runtime_suspend,
1028 .runtime_resume = pl330_runtime_resume,
1029};
1030
849static struct amba_driver pl330_driver = { 1031static struct amba_driver pl330_driver = {
850 .drv = { 1032 .drv = {
851 .owner = THIS_MODULE, 1033 .owner = THIS_MODULE,
852 .name = "dma-pl330", 1034 .name = "dma-pl330",
1035 .pm = &pl330_pm_ops,
853 }, 1036 },
854 .id_table = pl330_ids, 1037 .id_table = pl330_ids,
855 .probe = pl330_probe, 1038 .probe = pl330_probe,
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 7f49235d14b9..81809c2b46ab 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -259,14 +259,23 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
259 return 0; 259 return 0;
260} 260}
261 261
262static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan);
263
262static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) 264static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
263{ 265{
264 struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c; 266 struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c;
265 struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan); 267 struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan);
268 struct sh_dmae_slave *param = tx->chan->private;
266 dma_async_tx_callback callback = tx->callback; 269 dma_async_tx_callback callback = tx->callback;
267 dma_cookie_t cookie; 270 dma_cookie_t cookie;
271 bool power_up;
272
273 spin_lock_irq(&sh_chan->desc_lock);
268 274
269 spin_lock_bh(&sh_chan->desc_lock); 275 if (list_empty(&sh_chan->ld_queue))
276 power_up = true;
277 else
278 power_up = false;
270 279
271 cookie = sh_chan->common.cookie; 280 cookie = sh_chan->common.cookie;
272 cookie++; 281 cookie++;
@@ -302,7 +311,38 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
302 tx->cookie, &last->async_tx, sh_chan->id, 311 tx->cookie, &last->async_tx, sh_chan->id,
303 desc->hw.sar, desc->hw.tcr, desc->hw.dar); 312 desc->hw.sar, desc->hw.tcr, desc->hw.dar);
304 313
305 spin_unlock_bh(&sh_chan->desc_lock); 314 if (power_up) {
315 sh_chan->pm_state = DMAE_PM_BUSY;
316
317 pm_runtime_get(sh_chan->dev);
318
319 spin_unlock_irq(&sh_chan->desc_lock);
320
321 pm_runtime_barrier(sh_chan->dev);
322
323 spin_lock_irq(&sh_chan->desc_lock);
324
325 /* Have we been reset, while waiting? */
326 if (sh_chan->pm_state != DMAE_PM_ESTABLISHED) {
327 dev_dbg(sh_chan->dev, "Bring up channel %d\n",
328 sh_chan->id);
329 if (param) {
330 const struct sh_dmae_slave_config *cfg =
331 param->config;
332
333 dmae_set_dmars(sh_chan, cfg->mid_rid);
334 dmae_set_chcr(sh_chan, cfg->chcr);
335 } else {
336 dmae_init(sh_chan);
337 }
338
339 if (sh_chan->pm_state == DMAE_PM_PENDING)
340 sh_chan_xfer_ld_queue(sh_chan);
341 sh_chan->pm_state = DMAE_PM_ESTABLISHED;
342 }
343 }
344
345 spin_unlock_irq(&sh_chan->desc_lock);
306 346
307 return cookie; 347 return cookie;
308} 348}
@@ -346,8 +386,6 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
346 struct sh_dmae_slave *param = chan->private; 386 struct sh_dmae_slave *param = chan->private;
347 int ret; 387 int ret;
348 388
349 pm_runtime_get_sync(sh_chan->dev);
350
351 /* 389 /*
352 * This relies on the guarantee from dmaengine that alloc_chan_resources 390 * This relies on the guarantee from dmaengine that alloc_chan_resources
353 * never runs concurrently with itself or free_chan_resources. 391 * never runs concurrently with itself or free_chan_resources.
@@ -367,31 +405,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
367 } 405 }
368 406
369 param->config = cfg; 407 param->config = cfg;
370
371 dmae_set_dmars(sh_chan, cfg->mid_rid);
372 dmae_set_chcr(sh_chan, cfg->chcr);
373 } else {
374 dmae_init(sh_chan);
375 } 408 }
376 409
377 spin_lock_bh(&sh_chan->desc_lock);
378 while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) { 410 while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
379 spin_unlock_bh(&sh_chan->desc_lock);
380 desc = kzalloc(sizeof(struct sh_desc), GFP_KERNEL); 411 desc = kzalloc(sizeof(struct sh_desc), GFP_KERNEL);
381 if (!desc) { 412 if (!desc)
382 spin_lock_bh(&sh_chan->desc_lock);
383 break; 413 break;
384 }
385 dma_async_tx_descriptor_init(&desc->async_tx, 414 dma_async_tx_descriptor_init(&desc->async_tx,
386 &sh_chan->common); 415 &sh_chan->common);
387 desc->async_tx.tx_submit = sh_dmae_tx_submit; 416 desc->async_tx.tx_submit = sh_dmae_tx_submit;
388 desc->mark = DESC_IDLE; 417 desc->mark = DESC_IDLE;
389 418
390 spin_lock_bh(&sh_chan->desc_lock);
391 list_add(&desc->node, &sh_chan->ld_free); 419 list_add(&desc->node, &sh_chan->ld_free);
392 sh_chan->descs_allocated++; 420 sh_chan->descs_allocated++;
393 } 421 }
394 spin_unlock_bh(&sh_chan->desc_lock);
395 422
396 if (!sh_chan->descs_allocated) { 423 if (!sh_chan->descs_allocated) {
397 ret = -ENOMEM; 424 ret = -ENOMEM;
@@ -405,7 +432,7 @@ edescalloc:
405 clear_bit(param->slave_id, sh_dmae_slave_used); 432 clear_bit(param->slave_id, sh_dmae_slave_used);
406etestused: 433etestused:
407efindslave: 434efindslave:
408 pm_runtime_put(sh_chan->dev); 435 chan->private = NULL;
409 return ret; 436 return ret;
410} 437}
411 438
@@ -417,7 +444,6 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
417 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 444 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
418 struct sh_desc *desc, *_desc; 445 struct sh_desc *desc, *_desc;
419 LIST_HEAD(list); 446 LIST_HEAD(list);
420 int descs = sh_chan->descs_allocated;
421 447
422 /* Protect against ISR */ 448 /* Protect against ISR */
423 spin_lock_irq(&sh_chan->desc_lock); 449 spin_lock_irq(&sh_chan->desc_lock);
@@ -437,15 +463,12 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
437 chan->private = NULL; 463 chan->private = NULL;
438 } 464 }
439 465
440 spin_lock_bh(&sh_chan->desc_lock); 466 spin_lock_irq(&sh_chan->desc_lock);
441 467
442 list_splice_init(&sh_chan->ld_free, &list); 468 list_splice_init(&sh_chan->ld_free, &list);
443 sh_chan->descs_allocated = 0; 469 sh_chan->descs_allocated = 0;
444 470
445 spin_unlock_bh(&sh_chan->desc_lock); 471 spin_unlock_irq(&sh_chan->desc_lock);
446
447 if (descs > 0)
448 pm_runtime_put(sh_chan->dev);
449 472
450 list_for_each_entry_safe(desc, _desc, &list, node) 473 list_for_each_entry_safe(desc, _desc, &list, node)
451 kfree(desc); 474 kfree(desc);
@@ -534,6 +557,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c
534 struct sh_desc *first = NULL, *new = NULL /* compiler... */; 557 struct sh_desc *first = NULL, *new = NULL /* compiler... */;
535 LIST_HEAD(tx_list); 558 LIST_HEAD(tx_list);
536 int chunks = 0; 559 int chunks = 0;
560 unsigned long irq_flags;
537 int i; 561 int i;
538 562
539 if (!sg_len) 563 if (!sg_len)
@@ -544,7 +568,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c
544 (SH_DMA_TCR_MAX + 1); 568 (SH_DMA_TCR_MAX + 1);
545 569
546 /* Have to lock the whole loop to protect against concurrent release */ 570 /* Have to lock the whole loop to protect against concurrent release */
547 spin_lock_bh(&sh_chan->desc_lock); 571 spin_lock_irqsave(&sh_chan->desc_lock, irq_flags);
548 572
549 /* 573 /*
550 * Chaining: 574 * Chaining:
@@ -590,7 +614,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c
590 /* Put them back on the free list, so, they don't get lost */ 614 /* Put them back on the free list, so, they don't get lost */
591 list_splice_tail(&tx_list, &sh_chan->ld_free); 615 list_splice_tail(&tx_list, &sh_chan->ld_free);
592 616
593 spin_unlock_bh(&sh_chan->desc_lock); 617 spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
594 618
595 return &first->async_tx; 619 return &first->async_tx;
596 620
@@ -599,7 +623,7 @@ err_get_desc:
599 new->mark = DESC_IDLE; 623 new->mark = DESC_IDLE;
600 list_splice(&tx_list, &sh_chan->ld_free); 624 list_splice(&tx_list, &sh_chan->ld_free);
601 625
602 spin_unlock_bh(&sh_chan->desc_lock); 626 spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
603 627
604 return NULL; 628 return NULL;
605} 629}
@@ -661,6 +685,7 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
661 unsigned long arg) 685 unsigned long arg)
662{ 686{
663 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 687 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
688 unsigned long flags;
664 689
665 /* Only supports DMA_TERMINATE_ALL */ 690 /* Only supports DMA_TERMINATE_ALL */
666 if (cmd != DMA_TERMINATE_ALL) 691 if (cmd != DMA_TERMINATE_ALL)
@@ -669,7 +694,7 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
669 if (!chan) 694 if (!chan)
670 return -EINVAL; 695 return -EINVAL;
671 696
672 spin_lock_bh(&sh_chan->desc_lock); 697 spin_lock_irqsave(&sh_chan->desc_lock, flags);
673 dmae_halt(sh_chan); 698 dmae_halt(sh_chan);
674 699
675 if (!list_empty(&sh_chan->ld_queue)) { 700 if (!list_empty(&sh_chan->ld_queue)) {
@@ -678,9 +703,8 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
678 struct sh_desc, node); 703 struct sh_desc, node);
679 desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) << 704 desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
680 sh_chan->xmit_shift; 705 sh_chan->xmit_shift;
681
682 } 706 }
683 spin_unlock_bh(&sh_chan->desc_lock); 707 spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
684 708
685 sh_dmae_chan_ld_cleanup(sh_chan, true); 709 sh_dmae_chan_ld_cleanup(sh_chan, true);
686 710
@@ -695,8 +719,9 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
695 dma_cookie_t cookie = 0; 719 dma_cookie_t cookie = 0;
696 dma_async_tx_callback callback = NULL; 720 dma_async_tx_callback callback = NULL;
697 void *param = NULL; 721 void *param = NULL;
722 unsigned long flags;
698 723
699 spin_lock_bh(&sh_chan->desc_lock); 724 spin_lock_irqsave(&sh_chan->desc_lock, flags);
700 list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) { 725 list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) {
701 struct dma_async_tx_descriptor *tx = &desc->async_tx; 726 struct dma_async_tx_descriptor *tx = &desc->async_tx;
702 727
@@ -762,7 +787,13 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
762 async_tx_test_ack(&desc->async_tx)) || all) { 787 async_tx_test_ack(&desc->async_tx)) || all) {
763 /* Remove from ld_queue list */ 788 /* Remove from ld_queue list */
764 desc->mark = DESC_IDLE; 789 desc->mark = DESC_IDLE;
790
765 list_move(&desc->node, &sh_chan->ld_free); 791 list_move(&desc->node, &sh_chan->ld_free);
792
793 if (list_empty(&sh_chan->ld_queue)) {
794 dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
795 pm_runtime_put(sh_chan->dev);
796 }
766 } 797 }
767 } 798 }
768 799
@@ -773,7 +804,7 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all
773 */ 804 */
774 sh_chan->completed_cookie = sh_chan->common.cookie; 805 sh_chan->completed_cookie = sh_chan->common.cookie;
775 806
776 spin_unlock_bh(&sh_chan->desc_lock); 807 spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
777 808
778 if (callback) 809 if (callback)
779 callback(param); 810 callback(param);
@@ -792,14 +823,14 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
792 ; 823 ;
793} 824}
794 825
826/* Called under spin_lock_irq(&sh_chan->desc_lock) */
795static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) 827static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
796{ 828{
797 struct sh_desc *desc; 829 struct sh_desc *desc;
798 830
799 spin_lock_bh(&sh_chan->desc_lock);
800 /* DMA work check */ 831 /* DMA work check */
801 if (dmae_is_busy(sh_chan)) 832 if (dmae_is_busy(sh_chan))
802 goto sh_chan_xfer_ld_queue_end; 833 return;
803 834
804 /* Find the first not transferred descriptor */ 835 /* Find the first not transferred descriptor */
805 list_for_each_entry(desc, &sh_chan->ld_queue, node) 836 list_for_each_entry(desc, &sh_chan->ld_queue, node)
@@ -812,15 +843,18 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
812 dmae_start(sh_chan); 843 dmae_start(sh_chan);
813 break; 844 break;
814 } 845 }
815
816sh_chan_xfer_ld_queue_end:
817 spin_unlock_bh(&sh_chan->desc_lock);
818} 846}
819 847
820static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) 848static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan)
821{ 849{
822 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 850 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
823 sh_chan_xfer_ld_queue(sh_chan); 851
852 spin_lock_irq(&sh_chan->desc_lock);
853 if (sh_chan->pm_state == DMAE_PM_ESTABLISHED)
854 sh_chan_xfer_ld_queue(sh_chan);
855 else
856 sh_chan->pm_state = DMAE_PM_PENDING;
857 spin_unlock_irq(&sh_chan->desc_lock);
824} 858}
825 859
826static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, 860static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
@@ -831,6 +865,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
831 dma_cookie_t last_used; 865 dma_cookie_t last_used;
832 dma_cookie_t last_complete; 866 dma_cookie_t last_complete;
833 enum dma_status status; 867 enum dma_status status;
868 unsigned long flags;
834 869
835 sh_dmae_chan_ld_cleanup(sh_chan, false); 870 sh_dmae_chan_ld_cleanup(sh_chan, false);
836 871
@@ -841,7 +876,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
841 BUG_ON(last_complete < 0); 876 BUG_ON(last_complete < 0);
842 dma_set_tx_state(txstate, last_complete, last_used, 0); 877 dma_set_tx_state(txstate, last_complete, last_used, 0);
843 878
844 spin_lock_bh(&sh_chan->desc_lock); 879 spin_lock_irqsave(&sh_chan->desc_lock, flags);
845 880
846 status = dma_async_is_complete(cookie, last_complete, last_used); 881 status = dma_async_is_complete(cookie, last_complete, last_used);
847 882
@@ -859,7 +894,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
859 } 894 }
860 } 895 }
861 896
862 spin_unlock_bh(&sh_chan->desc_lock); 897 spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
863 898
864 return status; 899 return status;
865} 900}
@@ -912,6 +947,12 @@ static bool sh_dmae_reset(struct sh_dmae_device *shdev)
912 947
913 list_splice_init(&sh_chan->ld_queue, &dl); 948 list_splice_init(&sh_chan->ld_queue, &dl);
914 949
950 if (!list_empty(&dl)) {
951 dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
952 pm_runtime_put(sh_chan->dev);
953 }
954 sh_chan->pm_state = DMAE_PM_ESTABLISHED;
955
915 spin_unlock(&sh_chan->desc_lock); 956 spin_unlock(&sh_chan->desc_lock);
916 957
917 /* Complete all */ 958 /* Complete all */
@@ -952,7 +993,7 @@ static void dmae_do_tasklet(unsigned long data)
952 u32 sar_buf = sh_dmae_readl(sh_chan, SAR); 993 u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
953 u32 dar_buf = sh_dmae_readl(sh_chan, DAR); 994 u32 dar_buf = sh_dmae_readl(sh_chan, DAR);
954 995
955 spin_lock(&sh_chan->desc_lock); 996 spin_lock_irq(&sh_chan->desc_lock);
956 list_for_each_entry(desc, &sh_chan->ld_queue, node) { 997 list_for_each_entry(desc, &sh_chan->ld_queue, node) {
957 if (desc->mark == DESC_SUBMITTED && 998 if (desc->mark == DESC_SUBMITTED &&
958 ((desc->direction == DMA_FROM_DEVICE && 999 ((desc->direction == DMA_FROM_DEVICE &&
@@ -965,10 +1006,10 @@ static void dmae_do_tasklet(unsigned long data)
965 break; 1006 break;
966 } 1007 }
967 } 1008 }
968 spin_unlock(&sh_chan->desc_lock);
969
970 /* Next desc */ 1009 /* Next desc */
971 sh_chan_xfer_ld_queue(sh_chan); 1010 sh_chan_xfer_ld_queue(sh_chan);
1011 spin_unlock_irq(&sh_chan->desc_lock);
1012
972 sh_dmae_chan_ld_cleanup(sh_chan, false); 1013 sh_dmae_chan_ld_cleanup(sh_chan, false);
973} 1014}
974 1015
@@ -1036,7 +1077,9 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
1036 return -ENOMEM; 1077 return -ENOMEM;
1037 } 1078 }
1038 1079
1039 /* copy struct dma_device */ 1080 new_sh_chan->pm_state = DMAE_PM_ESTABLISHED;
1081
1082 /* reference struct dma_device */
1040 new_sh_chan->common.device = &shdev->common; 1083 new_sh_chan->common.device = &shdev->common;
1041 1084
1042 new_sh_chan->dev = shdev->common.dev; 1085 new_sh_chan->dev = shdev->common.dev;
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index dc56576f9fdb..2b55a276dc5b 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -23,6 +23,12 @@
23 23
24struct device; 24struct device;
25 25
26enum dmae_pm_state {
27 DMAE_PM_ESTABLISHED,
28 DMAE_PM_BUSY,
29 DMAE_PM_PENDING,
30};
31
26struct sh_dmae_chan { 32struct sh_dmae_chan {
27 dma_cookie_t completed_cookie; /* The maximum cookie completed */ 33 dma_cookie_t completed_cookie; /* The maximum cookie completed */
28 spinlock_t desc_lock; /* Descriptor operation lock */ 34 spinlock_t desc_lock; /* Descriptor operation lock */
@@ -38,6 +44,7 @@ struct sh_dmae_chan {
38 u32 __iomem *base; 44 u32 __iomem *base;
39 char dev_id[16]; /* unique name per DMAC of channel */ 45 char dev_id[16]; /* unique name per DMAC of channel */
40 int pm_error; 46 int pm_error;
47 enum dmae_pm_state pm_state;
41}; 48};
42 49
43struct sh_dmae_device { 50struct sh_dmae_device {
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index f69f90a61873..a4a398f2ef61 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -753,7 +753,7 @@ static int __devinit td_probe(struct platform_device *pdev)
753 753
754 INIT_LIST_HEAD(&td->dma.channels); 754 INIT_LIST_HEAD(&td->dma.channels);
755 755
756 for (i = 0; i < pdata->nr_channels; i++, td->dma.chancnt++) { 756 for (i = 0; i < pdata->nr_channels; i++) {
757 struct timb_dma_chan *td_chan = &td->channels[i]; 757 struct timb_dma_chan *td_chan = &td->channels[i];
758 struct timb_dma_platform_data_channel *pchan = 758 struct timb_dma_platform_data_channel *pchan =
759 pdata->channels + i; 759 pdata->channels + i;
@@ -762,12 +762,11 @@ static int __devinit td_probe(struct platform_device *pdev)
762 if ((i % 2) == pchan->rx) { 762 if ((i % 2) == pchan->rx) {
763 dev_err(&pdev->dev, "Wrong channel configuration\n"); 763 dev_err(&pdev->dev, "Wrong channel configuration\n");
764 err = -EINVAL; 764 err = -EINVAL;
765 goto err_tasklet_kill; 765 goto err_free_irq;
766 } 766 }
767 767
768 td_chan->chan.device = &td->dma; 768 td_chan->chan.device = &td->dma;
769 td_chan->chan.cookie = 1; 769 td_chan->chan.cookie = 1;
770 td_chan->chan.chan_id = i;
771 spin_lock_init(&td_chan->lock); 770 spin_lock_init(&td_chan->lock);
772 INIT_LIST_HEAD(&td_chan->active_list); 771 INIT_LIST_HEAD(&td_chan->active_list);
773 INIT_LIST_HEAD(&td_chan->queue); 772 INIT_LIST_HEAD(&td_chan->queue);
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
index a687a0d16962..a774c0ddaf5b 100644
--- a/drivers/edac/cpc925_edac.c
+++ b/drivers/edac/cpc925_edac.c
@@ -90,6 +90,7 @@ enum apimask_bits {
90 ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H | 90 ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H |
91 APIMASK_ECC_UE_L | APIMASK_ECC_CE_L), 91 APIMASK_ECC_UE_L | APIMASK_ECC_CE_L),
92}; 92};
93#define APIMASK_ADI(n) CPC925_BIT(((n)+1))
93 94
94/************************************************************ 95/************************************************************
95 * Processor Interface Exception Register (APIEXCP) 96 * Processor Interface Exception Register (APIEXCP)
@@ -581,16 +582,73 @@ static void cpc925_mc_check(struct mem_ctl_info *mci)
581} 582}
582 583
583/******************** CPU err device********************************/ 584/******************** CPU err device********************************/
585static u32 cpc925_cpu_mask_disabled(void)
586{
587 struct device_node *cpus;
588 struct device_node *cpunode = NULL;
589 static u32 mask = 0;
590
591 /* use cached value if available */
592 if (mask != 0)
593 return mask;
594
595 mask = APIMASK_ADI0 | APIMASK_ADI1;
596
597 cpus = of_find_node_by_path("/cpus");
598 if (cpus == NULL) {
599 cpc925_printk(KERN_DEBUG, "No /cpus node !\n");
600 return 0;
601 }
602
603 while ((cpunode = of_get_next_child(cpus, cpunode)) != NULL) {
604 const u32 *reg = of_get_property(cpunode, "reg", NULL);
605
606 if (strcmp(cpunode->type, "cpu")) {
607 cpc925_printk(KERN_ERR, "Not a cpu node in /cpus: %s\n", cpunode->name);
608 continue;
609 }
610
611 if (reg == NULL || *reg > 2) {
612 cpc925_printk(KERN_ERR, "Bad reg value at %s\n", cpunode->full_name);
613 continue;
614 }
615
616 mask &= ~APIMASK_ADI(*reg);
617 }
618
619 if (mask != (APIMASK_ADI0 | APIMASK_ADI1)) {
620 /* We assume that each CPU sits on it's own PI and that
621 * for present CPUs the reg property equals to the PI
622 * interface id */
623 cpc925_printk(KERN_WARNING,
624 "Assuming PI id is equal to CPU MPIC id!\n");
625 }
626
627 of_node_put(cpunode);
628 of_node_put(cpus);
629
630 return mask;
631}
632
584/* Enable CPU Errors detection */ 633/* Enable CPU Errors detection */
585static void cpc925_cpu_init(struct cpc925_dev_info *dev_info) 634static void cpc925_cpu_init(struct cpc925_dev_info *dev_info)
586{ 635{
587 u32 apimask; 636 u32 apimask;
637 u32 cpumask;
588 638
589 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET); 639 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
590 if ((apimask & CPU_MASK_ENABLE) == 0) { 640
591 apimask |= CPU_MASK_ENABLE; 641 cpumask = cpc925_cpu_mask_disabled();
592 __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET); 642 if (apimask & cpumask) {
643 cpc925_printk(KERN_WARNING, "CPU(s) not present, "
644 "but enabled in APIMASK, disabling\n");
645 apimask &= ~cpumask;
593 } 646 }
647
648 if ((apimask & CPU_MASK_ENABLE) == 0)
649 apimask |= CPU_MASK_ENABLE;
650
651 __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET);
594} 652}
595 653
596/* Disable CPU Errors detection */ 654/* Disable CPU Errors detection */
@@ -622,6 +680,9 @@ static void cpc925_cpu_check(struct edac_device_ctl_info *edac_dev)
622 if ((apiexcp & CPU_EXCP_DETECTED) == 0) 680 if ((apiexcp & CPU_EXCP_DETECTED) == 0)
623 return; 681 return;
624 682
683 if ((apiexcp & ~cpc925_cpu_mask_disabled()) == 0)
684 return;
685
625 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET); 686 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
626 cpc925_printk(KERN_INFO, "Processor Interface Fault\n" 687 cpc925_printk(KERN_INFO, "Processor Interface Fault\n"
627 "Processor Interface register dump:\n"); 688 "Processor Interface register dump:\n");
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 0de7d8770891..38400963e245 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -205,7 +205,7 @@ static struct platform_driver ppc4xx_edac_driver = {
205 .remove = ppc4xx_edac_remove, 205 .remove = ppc4xx_edac_remove,
206 .driver = { 206 .driver = {
207 .owner = THIS_MODULE, 207 .owner = THIS_MODULE,
208 .name = PPC4XX_EDAC_MODULE_NAME 208 .name = PPC4XX_EDAC_MODULE_NAME,
209 .of_match_table = ppc4xx_edac_match, 209 .of_match_table = ppc4xx_edac_match,
210 }, 210 },
211}; 211};
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index f1b7f659d3c9..e22957665808 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -151,7 +151,8 @@ edd_show_host_bus(struct edd_device *edev, char *buf)
151 p += scnprintf(p, left, "\tbase_address: %x\n", 151 p += scnprintf(p, left, "\tbase_address: %x\n",
152 info->params.interface_path.isa.base_address); 152 info->params.interface_path.isa.base_address);
153 } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) || 153 } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||
154 !strncmp(info->params.host_bus_type, "PCI", 3)) { 154 !strncmp(info->params.host_bus_type, "PCI", 3) ||
155 !strncmp(info->params.host_bus_type, "XPRS", 4)) {
155 p += scnprintf(p, left, 156 p += scnprintf(p, left,
156 "\t%02x:%02x.%d channel: %u\n", 157 "\t%02x:%02x.%d channel: %u\n",
157 info->params.interface_path.pci.bus, 158 info->params.interface_path.pci.bus,
@@ -159,7 +160,6 @@ edd_show_host_bus(struct edd_device *edev, char *buf)
159 info->params.interface_path.pci.function, 160 info->params.interface_path.pci.function,
160 info->params.interface_path.pci.channel); 161 info->params.interface_path.pci.channel);
161 } else if (!strncmp(info->params.host_bus_type, "IBND", 4) || 162 } else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||
162 !strncmp(info->params.host_bus_type, "XPRS", 4) ||
163 !strncmp(info->params.host_bus_type, "HTPT", 4)) { 163 !strncmp(info->params.host_bus_type, "HTPT", 4)) {
164 p += scnprintf(p, left, 164 p += scnprintf(p, left,
165 "\tTBD: %llx\n", 165 "\tTBD: %llx\n",
@@ -668,7 +668,7 @@ edd_get_pci_dev(struct edd_device *edev)
668{ 668{
669 struct edd_info *info = edd_dev_get_info(edev); 669 struct edd_info *info = edd_dev_get_info(edev);
670 670
671 if (edd_dev_is_type(edev, "PCI")) { 671 if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) {
672 return pci_get_bus_and_slot(info->params.interface_path.pci.bus, 672 return pci_get_bus_and_slot(info->params.interface_path.pci.bus,
673 PCI_DEVFN(info->params.interface_path.pci.slot, 673 PCI_DEVFN(info->params.interface_path.pci.slot,
674 info->params.interface_path.pci. 674 info->params.interface_path.pci.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8b3c745b1b05..8482a23887dc 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -95,14 +95,18 @@ config GPIO_EP93XX
95 depends on ARCH_EP93XX 95 depends on ARCH_EP93XX
96 select GPIO_GENERIC 96 select GPIO_GENERIC
97 97
98config GPIO_EXYNOS4
99 def_bool y
100 depends on CPU_EXYNOS4210
101
102config GPIO_MPC5200 98config GPIO_MPC5200
103 def_bool y 99 def_bool y
104 depends on PPC_MPC52xx 100 depends on PPC_MPC52xx
105 101
102config GPIO_MPC8XXX
103 bool "MPC512x/MPC8xxx GPIO support"
104 depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
105 FSL_SOC_BOOKE || PPC_86xx
106 help
107 Say Y here if you're going to use hardware that connects to the
108 MPC512x/831x/834x/837x/8572/8610 GPIOs.
109
106config GPIO_MSM_V1 110config GPIO_MSM_V1
107 tristate "Qualcomm MSM GPIO v1" 111 tristate "Qualcomm MSM GPIO v1"
108 depends on GPIOLIB && ARCH_MSM 112 depends on GPIOLIB && ARCH_MSM
@@ -131,18 +135,6 @@ config GPIO_MXS
131 select GPIO_GENERIC 135 select GPIO_GENERIC
132 select GENERIC_IRQ_CHIP 136 select GENERIC_IRQ_CHIP
133 137
134config GPIO_PLAT_SAMSUNG
135 def_bool y
136 depends on SAMSUNG_GPIOLIB_4BIT
137
138config GPIO_S5PC100
139 def_bool y
140 depends on CPU_S5PC100
141
142config GPIO_S5PV210
143 def_bool y
144 depends on CPU_S5PV210
145
146config GPIO_PL061 138config GPIO_PL061
147 bool "PrimeCell PL061 GPIO support" 139 bool "PrimeCell PL061 GPIO support"
148 depends on ARM_AMBA 140 depends on ARM_AMBA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 19c5d27b6d2e..dbcb0bcfd8da 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
16obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o 16obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
17obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o 17obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
18obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o 18obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
19obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
20obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o 19obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
21obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o 20obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
22obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o 21obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o
@@ -30,6 +29,7 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
30obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o 29obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
31obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o 30obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
32obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o 31obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
32obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
33obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o 33obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
34obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o 34obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
35obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o 35obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
@@ -42,10 +42,7 @@ obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
42obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o 42obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
43obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o 43obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o
44obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o 44obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
45 45obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
46obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
47obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
48obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
49obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o 46obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
50obj-$(CONFIG_GPIO_SCH) += gpio-sch.o 47obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
51obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o 48obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c
deleted file mode 100644
index d24b337cf1ac..000000000000
--- a/drivers/gpio/gpio-exynos4.c
+++ /dev/null
@@ -1,385 +0,0 @@
1/*
2 * EXYNOS4 - GPIOlib support
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/irq.h>
14#include <linux/io.h>
15#include <linux/gpio.h>
16
17#include <mach/map.h>
18
19#include <plat/gpio-core.h>
20#include <plat/gpio-cfg.h>
21#include <plat/gpio-cfg-helpers.h>
22
23int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
24 unsigned int off, s3c_gpio_pull_t pull)
25{
26 if (pull == S3C_GPIO_PULL_UP)
27 pull = 3;
28
29 return s3c_gpio_setpull_updown(chip, off, pull);
30}
31
32s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
33 unsigned int off)
34{
35 s3c_gpio_pull_t pull;
36
37 pull = s3c_gpio_getpull_updown(chip, off);
38 if (pull == 3)
39 pull = S3C_GPIO_PULL_UP;
40
41 return pull;
42}
43
44static struct s3c_gpio_cfg gpio_cfg = {
45 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
46 .set_pull = s3c_gpio_setpull_exynos4,
47 .get_pull = s3c_gpio_getpull_exynos4,
48};
49
50static struct s3c_gpio_cfg gpio_cfg_noint = {
51 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
52 .set_pull = s3c_gpio_setpull_exynos4,
53 .get_pull = s3c_gpio_getpull_exynos4,
54};
55
56/*
57 * Following are the gpio banks in v310.
58 *
59 * The 'config' member when left to NULL, is initialized to the default
60 * structure gpio_cfg in the init function below.
61 *
62 * The 'base' member is also initialized in the init function below.
63 * Note: The initialization of 'base' member of s3c_gpio_chip structure
64 * uses the above macro and depends on the banks being listed in order here.
65 */
66static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
67 {
68 .chip = {
69 .base = EXYNOS4_GPA0(0),
70 .ngpio = EXYNOS4_GPIO_A0_NR,
71 .label = "GPA0",
72 },
73 }, {
74 .chip = {
75 .base = EXYNOS4_GPA1(0),
76 .ngpio = EXYNOS4_GPIO_A1_NR,
77 .label = "GPA1",
78 },
79 }, {
80 .chip = {
81 .base = EXYNOS4_GPB(0),
82 .ngpio = EXYNOS4_GPIO_B_NR,
83 .label = "GPB",
84 },
85 }, {
86 .chip = {
87 .base = EXYNOS4_GPC0(0),
88 .ngpio = EXYNOS4_GPIO_C0_NR,
89 .label = "GPC0",
90 },
91 }, {
92 .chip = {
93 .base = EXYNOS4_GPC1(0),
94 .ngpio = EXYNOS4_GPIO_C1_NR,
95 .label = "GPC1",
96 },
97 }, {
98 .chip = {
99 .base = EXYNOS4_GPD0(0),
100 .ngpio = EXYNOS4_GPIO_D0_NR,
101 .label = "GPD0",
102 },
103 }, {
104 .chip = {
105 .base = EXYNOS4_GPD1(0),
106 .ngpio = EXYNOS4_GPIO_D1_NR,
107 .label = "GPD1",
108 },
109 }, {
110 .chip = {
111 .base = EXYNOS4_GPE0(0),
112 .ngpio = EXYNOS4_GPIO_E0_NR,
113 .label = "GPE0",
114 },
115 }, {
116 .chip = {
117 .base = EXYNOS4_GPE1(0),
118 .ngpio = EXYNOS4_GPIO_E1_NR,
119 .label = "GPE1",
120 },
121 }, {
122 .chip = {
123 .base = EXYNOS4_GPE2(0),
124 .ngpio = EXYNOS4_GPIO_E2_NR,
125 .label = "GPE2",
126 },
127 }, {
128 .chip = {
129 .base = EXYNOS4_GPE3(0),
130 .ngpio = EXYNOS4_GPIO_E3_NR,
131 .label = "GPE3",
132 },
133 }, {
134 .chip = {
135 .base = EXYNOS4_GPE4(0),
136 .ngpio = EXYNOS4_GPIO_E4_NR,
137 .label = "GPE4",
138 },
139 }, {
140 .chip = {
141 .base = EXYNOS4_GPF0(0),
142 .ngpio = EXYNOS4_GPIO_F0_NR,
143 .label = "GPF0",
144 },
145 }, {
146 .chip = {
147 .base = EXYNOS4_GPF1(0),
148 .ngpio = EXYNOS4_GPIO_F1_NR,
149 .label = "GPF1",
150 },
151 }, {
152 .chip = {
153 .base = EXYNOS4_GPF2(0),
154 .ngpio = EXYNOS4_GPIO_F2_NR,
155 .label = "GPF2",
156 },
157 }, {
158 .chip = {
159 .base = EXYNOS4_GPF3(0),
160 .ngpio = EXYNOS4_GPIO_F3_NR,
161 .label = "GPF3",
162 },
163 },
164};
165
166static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
167 {
168 .chip = {
169 .base = EXYNOS4_GPJ0(0),
170 .ngpio = EXYNOS4_GPIO_J0_NR,
171 .label = "GPJ0",
172 },
173 }, {
174 .chip = {
175 .base = EXYNOS4_GPJ1(0),
176 .ngpio = EXYNOS4_GPIO_J1_NR,
177 .label = "GPJ1",
178 },
179 }, {
180 .chip = {
181 .base = EXYNOS4_GPK0(0),
182 .ngpio = EXYNOS4_GPIO_K0_NR,
183 .label = "GPK0",
184 },
185 }, {
186 .chip = {
187 .base = EXYNOS4_GPK1(0),
188 .ngpio = EXYNOS4_GPIO_K1_NR,
189 .label = "GPK1",
190 },
191 }, {
192 .chip = {
193 .base = EXYNOS4_GPK2(0),
194 .ngpio = EXYNOS4_GPIO_K2_NR,
195 .label = "GPK2",
196 },
197 }, {
198 .chip = {
199 .base = EXYNOS4_GPK3(0),
200 .ngpio = EXYNOS4_GPIO_K3_NR,
201 .label = "GPK3",
202 },
203 }, {
204 .chip = {
205 .base = EXYNOS4_GPL0(0),
206 .ngpio = EXYNOS4_GPIO_L0_NR,
207 .label = "GPL0",
208 },
209 }, {
210 .chip = {
211 .base = EXYNOS4_GPL1(0),
212 .ngpio = EXYNOS4_GPIO_L1_NR,
213 .label = "GPL1",
214 },
215 }, {
216 .chip = {
217 .base = EXYNOS4_GPL2(0),
218 .ngpio = EXYNOS4_GPIO_L2_NR,
219 .label = "GPL2",
220 },
221 }, {
222 .config = &gpio_cfg_noint,
223 .chip = {
224 .base = EXYNOS4_GPY0(0),
225 .ngpio = EXYNOS4_GPIO_Y0_NR,
226 .label = "GPY0",
227 },
228 }, {
229 .config = &gpio_cfg_noint,
230 .chip = {
231 .base = EXYNOS4_GPY1(0),
232 .ngpio = EXYNOS4_GPIO_Y1_NR,
233 .label = "GPY1",
234 },
235 }, {
236 .config = &gpio_cfg_noint,
237 .chip = {
238 .base = EXYNOS4_GPY2(0),
239 .ngpio = EXYNOS4_GPIO_Y2_NR,
240 .label = "GPY2",
241 },
242 }, {
243 .config = &gpio_cfg_noint,
244 .chip = {
245 .base = EXYNOS4_GPY3(0),
246 .ngpio = EXYNOS4_GPIO_Y3_NR,
247 .label = "GPY3",
248 },
249 }, {
250 .config = &gpio_cfg_noint,
251 .chip = {
252 .base = EXYNOS4_GPY4(0),
253 .ngpio = EXYNOS4_GPIO_Y4_NR,
254 .label = "GPY4",
255 },
256 }, {
257 .config = &gpio_cfg_noint,
258 .chip = {
259 .base = EXYNOS4_GPY5(0),
260 .ngpio = EXYNOS4_GPIO_Y5_NR,
261 .label = "GPY5",
262 },
263 }, {
264 .config = &gpio_cfg_noint,
265 .chip = {
266 .base = EXYNOS4_GPY6(0),
267 .ngpio = EXYNOS4_GPIO_Y6_NR,
268 .label = "GPY6",
269 },
270 }, {
271 .base = (S5P_VA_GPIO2 + 0xC00),
272 .config = &gpio_cfg_noint,
273 .irq_base = IRQ_EINT(0),
274 .chip = {
275 .base = EXYNOS4_GPX0(0),
276 .ngpio = EXYNOS4_GPIO_X0_NR,
277 .label = "GPX0",
278 .to_irq = samsung_gpiolib_to_irq,
279 },
280 }, {
281 .base = (S5P_VA_GPIO2 + 0xC20),
282 .config = &gpio_cfg_noint,
283 .irq_base = IRQ_EINT(8),
284 .chip = {
285 .base = EXYNOS4_GPX1(0),
286 .ngpio = EXYNOS4_GPIO_X1_NR,
287 .label = "GPX1",
288 .to_irq = samsung_gpiolib_to_irq,
289 },
290 }, {
291 .base = (S5P_VA_GPIO2 + 0xC40),
292 .config = &gpio_cfg_noint,
293 .irq_base = IRQ_EINT(16),
294 .chip = {
295 .base = EXYNOS4_GPX2(0),
296 .ngpio = EXYNOS4_GPIO_X2_NR,
297 .label = "GPX2",
298 .to_irq = samsung_gpiolib_to_irq,
299 },
300 }, {
301 .base = (S5P_VA_GPIO2 + 0xC60),
302 .config = &gpio_cfg_noint,
303 .irq_base = IRQ_EINT(24),
304 .chip = {
305 .base = EXYNOS4_GPX3(0),
306 .ngpio = EXYNOS4_GPIO_X3_NR,
307 .label = "GPX3",
308 .to_irq = samsung_gpiolib_to_irq,
309 },
310 },
311};
312
313static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
314 {
315 .chip = {
316 .base = EXYNOS4_GPZ(0),
317 .ngpio = EXYNOS4_GPIO_Z_NR,
318 .label = "GPZ",
319 },
320 },
321};
322
323static __init int exynos4_gpiolib_init(void)
324{
325 struct s3c_gpio_chip *chip;
326 int i;
327 int group = 0;
328 int nr_chips;
329
330 /* GPIO part 1 */
331
332 chip = exynos4_gpio_part1_4bit;
333 nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
334
335 for (i = 0; i < nr_chips; i++, chip++) {
336 if (chip->config == NULL) {
337 chip->config = &gpio_cfg;
338 /* Assign the GPIO interrupt group */
339 chip->group = group++;
340 }
341 if (chip->base == NULL)
342 chip->base = S5P_VA_GPIO1 + (i) * 0x20;
343 }
344
345 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
346
347 /* GPIO part 2 */
348
349 chip = exynos4_gpio_part2_4bit;
350 nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
351
352 for (i = 0; i < nr_chips; i++, chip++) {
353 if (chip->config == NULL) {
354 chip->config = &gpio_cfg;
355 /* Assign the GPIO interrupt group */
356 chip->group = group++;
357 }
358 if (chip->base == NULL)
359 chip->base = S5P_VA_GPIO2 + (i) * 0x20;
360 }
361
362 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
363
364 /* GPIO part 3 */
365
366 chip = exynos4_gpio_part3_4bit;
367 nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
368
369 for (i = 0; i < nr_chips; i++, chip++) {
370 if (chip->config == NULL) {
371 chip->config = &gpio_cfg;
372 /* Assign the GPIO interrupt group */
373 chip->group = group++;
374 }
375 if (chip->base == NULL)
376 chip->base = S5P_VA_GPIO3 + (i) * 0x20;
377 }
378
379 samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
380 s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
381 s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
382
383 return 0;
384}
385core_initcall(exynos4_gpiolib_init);
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/drivers/gpio/gpio-mpc8xxx.c
index fb4963abdf55..ec3fcf0a7e12 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -146,6 +146,7 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
146static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) 146static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
147{ 147{
148 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); 148 struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
149 struct irq_chip *chip = irq_desc_get_chip(desc);
149 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; 150 struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
150 unsigned int mask; 151 unsigned int mask;
151 152
@@ -153,6 +154,7 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
153 if (mask) 154 if (mask)
154 generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, 155 generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
155 32 - ffs(mask))); 156 32 - ffs(mask)));
157 chip->irq_eoi(&desc->irq_data);
156} 158}
157 159
158static void mpc8xxx_irq_unmask(struct irq_data *d) 160static void mpc8xxx_irq_unmask(struct irq_data *d)
@@ -310,6 +312,7 @@ static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
310 { .compatible = "fsl,mpc8572-gpio", }, 312 { .compatible = "fsl,mpc8572-gpio", },
311 { .compatible = "fsl,mpc8610-gpio", }, 313 { .compatible = "fsl,mpc8610-gpio", },
312 { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, 314 { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
315 { .compatible = "fsl,pq3-gpio", },
313 { .compatible = "fsl,qoriq-gpio", }, 316 { .compatible = "fsl,qoriq-gpio", },
314 {} 317 {}
315}; 318};
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c
deleted file mode 100644
index ef67f1952a72..000000000000
--- a/drivers/gpio/gpio-plat-samsung.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/*
2 * Copyright 2008 Openmoko, Inc.
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com/
9 *
10 * SAMSUNG - GPIOlib support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kernel.h>
18#include <linux/irq.h>
19#include <linux/io.h>
20#include <linux/gpio.h>
21#include <plat/gpio-core.h>
22#include <plat/gpio-cfg.h>
23#include <plat/gpio-cfg-helpers.h>
24
25#ifndef DEBUG_GPIO
26#define gpio_dbg(x...) do { } while (0)
27#else
28#define gpio_dbg(x...) printk(KERN_DEBUG x)
29#endif
30
31/* The samsung_gpiolib_4bit routines are to control the gpio banks where
32 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
33 * following example:
34 *
35 * base + 0x00: Control register, 4 bits per gpio
36 * gpio n: 4 bits starting at (4*n)
37 * 0000 = input, 0001 = output, others mean special-function
38 * base + 0x04: Data register, 1 bit per gpio
39 * bit n: data bit n
40 *
41 * Note, since the data register is one bit per gpio and is at base + 0x4
42 * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
43 * the output.
44*/
45
46static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
47 unsigned int offset)
48{
49 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
50 void __iomem *base = ourchip->base;
51 unsigned long con;
52
53 con = __raw_readl(base + GPIOCON_OFF);
54 con &= ~(0xf << con_4bit_shift(offset));
55 __raw_writel(con, base + GPIOCON_OFF);
56
57 gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
58
59 return 0;
60}
61
62static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
63 unsigned int offset, int value)
64{
65 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
66 void __iomem *base = ourchip->base;
67 unsigned long con;
68 unsigned long dat;
69
70 con = __raw_readl(base + GPIOCON_OFF);
71 con &= ~(0xf << con_4bit_shift(offset));
72 con |= 0x1 << con_4bit_shift(offset);
73
74 dat = __raw_readl(base + GPIODAT_OFF);
75
76 if (value)
77 dat |= 1 << offset;
78 else
79 dat &= ~(1 << offset);
80
81 __raw_writel(dat, base + GPIODAT_OFF);
82 __raw_writel(con, base + GPIOCON_OFF);
83 __raw_writel(dat, base + GPIODAT_OFF);
84
85 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
86
87 return 0;
88}
89
90/* The next set of routines are for the case where the GPIO configuration
91 * registers are 4 bits per GPIO but there is more than one register (the
92 * bank has more than 8 GPIOs.
93 *
94 * This case is the similar to the 4 bit case, but the registers are as
95 * follows:
96 *
97 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
98 * gpio n: 4 bits starting at (4*n)
99 * 0000 = input, 0001 = output, others mean special-function
100 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
101 * gpio n: 4 bits starting at (4*n)
102 * 0000 = input, 0001 = output, others mean special-function
103 * base + 0x08: Data register, 1 bit per gpio
104 * bit n: data bit n
105 *
106 * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
107 * store the 'base + 0x4' address so that these routines see the data
108 * register at ourchip->base + 0x04.
109 */
110
111static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
112 unsigned int offset)
113{
114 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
115 void __iomem *base = ourchip->base;
116 void __iomem *regcon = base;
117 unsigned long con;
118
119 if (offset > 7)
120 offset -= 8;
121 else
122 regcon -= 4;
123
124 con = __raw_readl(regcon);
125 con &= ~(0xf << con_4bit_shift(offset));
126 __raw_writel(con, regcon);
127
128 gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
129
130 return 0;
131}
132
133static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
134 unsigned int offset, int value)
135{
136 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
137 void __iomem *base = ourchip->base;
138 void __iomem *regcon = base;
139 unsigned long con;
140 unsigned long dat;
141 unsigned con_offset = offset;
142
143 if (con_offset > 7)
144 con_offset -= 8;
145 else
146 regcon -= 4;
147
148 con = __raw_readl(regcon);
149 con &= ~(0xf << con_4bit_shift(con_offset));
150 con |= 0x1 << con_4bit_shift(con_offset);
151
152 dat = __raw_readl(base + GPIODAT_OFF);
153
154 if (value)
155 dat |= 1 << offset;
156 else
157 dat &= ~(1 << offset);
158
159 __raw_writel(dat, base + GPIODAT_OFF);
160 __raw_writel(con, regcon);
161 __raw_writel(dat, base + GPIODAT_OFF);
162
163 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
164
165 return 0;
166}
167
168void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
169{
170 chip->chip.direction_input = samsung_gpiolib_4bit_input;
171 chip->chip.direction_output = samsung_gpiolib_4bit_output;
172 chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
173}
174
175void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
176{
177 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
178 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
179 chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
180}
181
182void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
183 int nr_chips)
184{
185 for (; nr_chips > 0; nr_chips--, chip++) {
186 samsung_gpiolib_add_4bit(chip);
187 s3c_gpiolib_add(chip);
188 }
189}
190
191void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
192 int nr_chips)
193{
194 for (; nr_chips > 0; nr_chips--, chip++) {
195 samsung_gpiolib_add_4bit2(chip);
196 s3c_gpiolib_add(chip);
197 }
198}
199
200void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
201 int nr_chips)
202{
203 for (; nr_chips > 0; nr_chips--, chip++)
204 s3c_gpiolib_add(chip);
205}
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c
deleted file mode 100644
index 7f87b0c76e0b..000000000000
--- a/drivers/gpio/gpio-s5pc100.c
+++ /dev/null
@@ -1,354 +0,0 @@
1/*
2 * S5PC100 - GPIOlib support
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * Copyright 2009 Samsung Electronics Co
8 * Kyungmin Park <kyungmin.park@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19
20#include <mach/map.h>
21#include <mach/regs-gpio.h>
22
23#include <plat/gpio-core.h>
24#include <plat/gpio-cfg.h>
25#include <plat/gpio-cfg-helpers.h>
26
27/* S5PC100 GPIO bank summary:
28 *
29 * Bank GPIOs Style INT Type
30 * A0 8 4Bit GPIO_INT0
31 * A1 5 4Bit GPIO_INT1
32 * B 8 4Bit GPIO_INT2
33 * C 5 4Bit GPIO_INT3
34 * D 7 4Bit GPIO_INT4
35 * E0 8 4Bit GPIO_INT5
36 * E1 6 4Bit GPIO_INT6
37 * F0 8 4Bit GPIO_INT7
38 * F1 8 4Bit GPIO_INT8
39 * F2 8 4Bit GPIO_INT9
40 * F3 4 4Bit GPIO_INT10
41 * G0 8 4Bit GPIO_INT11
42 * G1 3 4Bit GPIO_INT12
43 * G2 7 4Bit GPIO_INT13
44 * G3 7 4Bit GPIO_INT14
45 * H0 8 4Bit WKUP_INT
46 * H1 8 4Bit WKUP_INT
47 * H2 8 4Bit WKUP_INT
48 * H3 8 4Bit WKUP_INT
49 * I 8 4Bit GPIO_INT15
50 * J0 8 4Bit GPIO_INT16
51 * J1 5 4Bit GPIO_INT17
52 * J2 8 4Bit GPIO_INT18
53 * J3 8 4Bit GPIO_INT19
54 * J4 4 4Bit GPIO_INT20
55 * K0 8 4Bit None
56 * K1 6 4Bit None
57 * K2 8 4Bit None
58 * K3 8 4Bit None
59 * L0 8 4Bit None
60 * L1 8 4Bit None
61 * L2 8 4Bit None
62 * L3 8 4Bit None
63 */
64
65static struct s3c_gpio_cfg gpio_cfg = {
66 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
67 .set_pull = s3c_gpio_setpull_updown,
68 .get_pull = s3c_gpio_getpull_updown,
69};
70
71static struct s3c_gpio_cfg gpio_cfg_eint = {
72 .cfg_eint = 0xf,
73 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
74 .set_pull = s3c_gpio_setpull_updown,
75 .get_pull = s3c_gpio_getpull_updown,
76};
77
78static struct s3c_gpio_cfg gpio_cfg_noint = {
79 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
80 .set_pull = s3c_gpio_setpull_updown,
81 .get_pull = s3c_gpio_getpull_updown,
82};
83
84/*
85 * GPIO bank's base address given the index of the bank in the
86 * list of all gpio banks.
87 */
88#define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
89
90/*
91 * Following are the gpio banks in S5PC100.
92 *
93 * The 'config' member when left to NULL, is initialized to the default
94 * structure gpio_cfg in the init function below.
95 *
96 * The 'base' member is also initialized in the init function below.
97 * Note: The initialization of 'base' member of s3c_gpio_chip structure
98 * uses the above macro and depends on the banks being listed in order here.
99 */
100static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
101 {
102 .chip = {
103 .base = S5PC100_GPA0(0),
104 .ngpio = S5PC100_GPIO_A0_NR,
105 .label = "GPA0",
106 },
107 }, {
108 .chip = {
109 .base = S5PC100_GPA1(0),
110 .ngpio = S5PC100_GPIO_A1_NR,
111 .label = "GPA1",
112 },
113 }, {
114 .chip = {
115 .base = S5PC100_GPB(0),
116 .ngpio = S5PC100_GPIO_B_NR,
117 .label = "GPB",
118 },
119 }, {
120 .chip = {
121 .base = S5PC100_GPC(0),
122 .ngpio = S5PC100_GPIO_C_NR,
123 .label = "GPC",
124 },
125 }, {
126 .chip = {
127 .base = S5PC100_GPD(0),
128 .ngpio = S5PC100_GPIO_D_NR,
129 .label = "GPD",
130 },
131 }, {
132 .chip = {
133 .base = S5PC100_GPE0(0),
134 .ngpio = S5PC100_GPIO_E0_NR,
135 .label = "GPE0",
136 },
137 }, {
138 .chip = {
139 .base = S5PC100_GPE1(0),
140 .ngpio = S5PC100_GPIO_E1_NR,
141 .label = "GPE1",
142 },
143 }, {
144 .chip = {
145 .base = S5PC100_GPF0(0),
146 .ngpio = S5PC100_GPIO_F0_NR,
147 .label = "GPF0",
148 },
149 }, {
150 .chip = {
151 .base = S5PC100_GPF1(0),
152 .ngpio = S5PC100_GPIO_F1_NR,
153 .label = "GPF1",
154 },
155 }, {
156 .chip = {
157 .base = S5PC100_GPF2(0),
158 .ngpio = S5PC100_GPIO_F2_NR,
159 .label = "GPF2",
160 },
161 }, {
162 .chip = {
163 .base = S5PC100_GPF3(0),
164 .ngpio = S5PC100_GPIO_F3_NR,
165 .label = "GPF3",
166 },
167 }, {
168 .chip = {
169 .base = S5PC100_GPG0(0),
170 .ngpio = S5PC100_GPIO_G0_NR,
171 .label = "GPG0",
172 },
173 }, {
174 .chip = {
175 .base = S5PC100_GPG1(0),
176 .ngpio = S5PC100_GPIO_G1_NR,
177 .label = "GPG1",
178 },
179 }, {
180 .chip = {
181 .base = S5PC100_GPG2(0),
182 .ngpio = S5PC100_GPIO_G2_NR,
183 .label = "GPG2",
184 },
185 }, {
186 .chip = {
187 .base = S5PC100_GPG3(0),
188 .ngpio = S5PC100_GPIO_G3_NR,
189 .label = "GPG3",
190 },
191 }, {
192 .chip = {
193 .base = S5PC100_GPI(0),
194 .ngpio = S5PC100_GPIO_I_NR,
195 .label = "GPI",
196 },
197 }, {
198 .chip = {
199 .base = S5PC100_GPJ0(0),
200 .ngpio = S5PC100_GPIO_J0_NR,
201 .label = "GPJ0",
202 },
203 }, {
204 .chip = {
205 .base = S5PC100_GPJ1(0),
206 .ngpio = S5PC100_GPIO_J1_NR,
207 .label = "GPJ1",
208 },
209 }, {
210 .chip = {
211 .base = S5PC100_GPJ2(0),
212 .ngpio = S5PC100_GPIO_J2_NR,
213 .label = "GPJ2",
214 },
215 }, {
216 .chip = {
217 .base = S5PC100_GPJ3(0),
218 .ngpio = S5PC100_GPIO_J3_NR,
219 .label = "GPJ3",
220 },
221 }, {
222 .chip = {
223 .base = S5PC100_GPJ4(0),
224 .ngpio = S5PC100_GPIO_J4_NR,
225 .label = "GPJ4",
226 },
227 }, {
228 .config = &gpio_cfg_noint,
229 .chip = {
230 .base = S5PC100_GPK0(0),
231 .ngpio = S5PC100_GPIO_K0_NR,
232 .label = "GPK0",
233 },
234 }, {
235 .config = &gpio_cfg_noint,
236 .chip = {
237 .base = S5PC100_GPK1(0),
238 .ngpio = S5PC100_GPIO_K1_NR,
239 .label = "GPK1",
240 },
241 }, {
242 .config = &gpio_cfg_noint,
243 .chip = {
244 .base = S5PC100_GPK2(0),
245 .ngpio = S5PC100_GPIO_K2_NR,
246 .label = "GPK2",
247 },
248 }, {
249 .config = &gpio_cfg_noint,
250 .chip = {
251 .base = S5PC100_GPK3(0),
252 .ngpio = S5PC100_GPIO_K3_NR,
253 .label = "GPK3",
254 },
255 }, {
256 .config = &gpio_cfg_noint,
257 .chip = {
258 .base = S5PC100_GPL0(0),
259 .ngpio = S5PC100_GPIO_L0_NR,
260 .label = "GPL0",
261 },
262 }, {
263 .config = &gpio_cfg_noint,
264 .chip = {
265 .base = S5PC100_GPL1(0),
266 .ngpio = S5PC100_GPIO_L1_NR,
267 .label = "GPL1",
268 },
269 }, {
270 .config = &gpio_cfg_noint,
271 .chip = {
272 .base = S5PC100_GPL2(0),
273 .ngpio = S5PC100_GPIO_L2_NR,
274 .label = "GPL2",
275 },
276 }, {
277 .config = &gpio_cfg_noint,
278 .chip = {
279 .base = S5PC100_GPL3(0),
280 .ngpio = S5PC100_GPIO_L3_NR,
281 .label = "GPL3",
282 },
283 }, {
284 .config = &gpio_cfg_noint,
285 .chip = {
286 .base = S5PC100_GPL4(0),
287 .ngpio = S5PC100_GPIO_L4_NR,
288 .label = "GPL4",
289 },
290 }, {
291 .base = (S5P_VA_GPIO + 0xC00),
292 .config = &gpio_cfg_eint,
293 .irq_base = IRQ_EINT(0),
294 .chip = {
295 .base = S5PC100_GPH0(0),
296 .ngpio = S5PC100_GPIO_H0_NR,
297 .label = "GPH0",
298 .to_irq = samsung_gpiolib_to_irq,
299 },
300 }, {
301 .base = (S5P_VA_GPIO + 0xC20),
302 .config = &gpio_cfg_eint,
303 .irq_base = IRQ_EINT(8),
304 .chip = {
305 .base = S5PC100_GPH1(0),
306 .ngpio = S5PC100_GPIO_H1_NR,
307 .label = "GPH1",
308 .to_irq = samsung_gpiolib_to_irq,
309 },
310 }, {
311 .base = (S5P_VA_GPIO + 0xC40),
312 .config = &gpio_cfg_eint,
313 .irq_base = IRQ_EINT(16),
314 .chip = {
315 .base = S5PC100_GPH2(0),
316 .ngpio = S5PC100_GPIO_H2_NR,
317 .label = "GPH2",
318 .to_irq = samsung_gpiolib_to_irq,
319 },
320 }, {
321 .base = (S5P_VA_GPIO + 0xC60),
322 .config = &gpio_cfg_eint,
323 .irq_base = IRQ_EINT(24),
324 .chip = {
325 .base = S5PC100_GPH3(0),
326 .ngpio = S5PC100_GPIO_H3_NR,
327 .label = "GPH3",
328 .to_irq = samsung_gpiolib_to_irq,
329 },
330 },
331};
332
333static __init int s5pc100_gpiolib_init(void)
334{
335 struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
336 int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
337 int gpioint_group = 0;
338 int i;
339
340 for (i = 0; i < nr_chips; i++, chip++) {
341 if (chip->config == NULL) {
342 chip->config = &gpio_cfg;
343 chip->group = gpioint_group++;
344 }
345 if (chip->base == NULL)
346 chip->base = S5PC100_BANK_BASE(i);
347 }
348
349 samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
350 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
351
352 return 0;
353}
354core_initcall(s5pc100_gpiolib_init);
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
deleted file mode 100644
index eb12f1602de9..000000000000
--- a/drivers/gpio/gpio-s5pv210.c
+++ /dev/null
@@ -1,287 +0,0 @@
1/*
2 * S5PV210 - GPIOlib support
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/irq.h>
14#include <linux/io.h>
15#include <linux/gpio.h>
16#include <plat/gpio-core.h>
17#include <plat/gpio-cfg.h>
18#include <plat/gpio-cfg-helpers.h>
19#include <mach/map.h>
20
21static struct s3c_gpio_cfg gpio_cfg = {
22 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
23 .set_pull = s3c_gpio_setpull_updown,
24 .get_pull = s3c_gpio_getpull_updown,
25};
26
27static struct s3c_gpio_cfg gpio_cfg_noint = {
28 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
29 .set_pull = s3c_gpio_setpull_updown,
30 .get_pull = s3c_gpio_getpull_updown,
31};
32
33/* GPIO bank's base address given the index of the bank in the
34 * list of all gpio banks.
35 */
36#define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
37
38/*
39 * Following are the gpio banks in v210.
40 *
41 * The 'config' member when left to NULL, is initialized to the default
42 * structure gpio_cfg in the init function below.
43 *
44 * The 'base' member is also initialized in the init function below.
45 * Note: The initialization of 'base' member of s3c_gpio_chip structure
46 * uses the above macro and depends on the banks being listed in order here.
47 */
48static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
49 {
50 .chip = {
51 .base = S5PV210_GPA0(0),
52 .ngpio = S5PV210_GPIO_A0_NR,
53 .label = "GPA0",
54 },
55 }, {
56 .chip = {
57 .base = S5PV210_GPA1(0),
58 .ngpio = S5PV210_GPIO_A1_NR,
59 .label = "GPA1",
60 },
61 }, {
62 .chip = {
63 .base = S5PV210_GPB(0),
64 .ngpio = S5PV210_GPIO_B_NR,
65 .label = "GPB",
66 },
67 }, {
68 .chip = {
69 .base = S5PV210_GPC0(0),
70 .ngpio = S5PV210_GPIO_C0_NR,
71 .label = "GPC0",
72 },
73 }, {
74 .chip = {
75 .base = S5PV210_GPC1(0),
76 .ngpio = S5PV210_GPIO_C1_NR,
77 .label = "GPC1",
78 },
79 }, {
80 .chip = {
81 .base = S5PV210_GPD0(0),
82 .ngpio = S5PV210_GPIO_D0_NR,
83 .label = "GPD0",
84 },
85 }, {
86 .chip = {
87 .base = S5PV210_GPD1(0),
88 .ngpio = S5PV210_GPIO_D1_NR,
89 .label = "GPD1",
90 },
91 }, {
92 .chip = {
93 .base = S5PV210_GPE0(0),
94 .ngpio = S5PV210_GPIO_E0_NR,
95 .label = "GPE0",
96 },
97 }, {
98 .chip = {
99 .base = S5PV210_GPE1(0),
100 .ngpio = S5PV210_GPIO_E1_NR,
101 .label = "GPE1",
102 },
103 }, {
104 .chip = {
105 .base = S5PV210_GPF0(0),
106 .ngpio = S5PV210_GPIO_F0_NR,
107 .label = "GPF0",
108 },
109 }, {
110 .chip = {
111 .base = S5PV210_GPF1(0),
112 .ngpio = S5PV210_GPIO_F1_NR,
113 .label = "GPF1",
114 },
115 }, {
116 .chip = {
117 .base = S5PV210_GPF2(0),
118 .ngpio = S5PV210_GPIO_F2_NR,
119 .label = "GPF2",
120 },
121 }, {
122 .chip = {
123 .base = S5PV210_GPF3(0),
124 .ngpio = S5PV210_GPIO_F3_NR,
125 .label = "GPF3",
126 },
127 }, {
128 .chip = {
129 .base = S5PV210_GPG0(0),
130 .ngpio = S5PV210_GPIO_G0_NR,
131 .label = "GPG0",
132 },
133 }, {
134 .chip = {
135 .base = S5PV210_GPG1(0),
136 .ngpio = S5PV210_GPIO_G1_NR,
137 .label = "GPG1",
138 },
139 }, {
140 .chip = {
141 .base = S5PV210_GPG2(0),
142 .ngpio = S5PV210_GPIO_G2_NR,
143 .label = "GPG2",
144 },
145 }, {
146 .chip = {
147 .base = S5PV210_GPG3(0),
148 .ngpio = S5PV210_GPIO_G3_NR,
149 .label = "GPG3",
150 },
151 }, {
152 .config = &gpio_cfg_noint,
153 .chip = {
154 .base = S5PV210_GPI(0),
155 .ngpio = S5PV210_GPIO_I_NR,
156 .label = "GPI",
157 },
158 }, {
159 .chip = {
160 .base = S5PV210_GPJ0(0),
161 .ngpio = S5PV210_GPIO_J0_NR,
162 .label = "GPJ0",
163 },
164 }, {
165 .chip = {
166 .base = S5PV210_GPJ1(0),
167 .ngpio = S5PV210_GPIO_J1_NR,
168 .label = "GPJ1",
169 },
170 }, {
171 .chip = {
172 .base = S5PV210_GPJ2(0),
173 .ngpio = S5PV210_GPIO_J2_NR,
174 .label = "GPJ2",
175 },
176 }, {
177 .chip = {
178 .base = S5PV210_GPJ3(0),
179 .ngpio = S5PV210_GPIO_J3_NR,
180 .label = "GPJ3",
181 },
182 }, {
183 .chip = {
184 .base = S5PV210_GPJ4(0),
185 .ngpio = S5PV210_GPIO_J4_NR,
186 .label = "GPJ4",
187 },
188 }, {
189 .config = &gpio_cfg_noint,
190 .chip = {
191 .base = S5PV210_MP01(0),
192 .ngpio = S5PV210_GPIO_MP01_NR,
193 .label = "MP01",
194 },
195 }, {
196 .config = &gpio_cfg_noint,
197 .chip = {
198 .base = S5PV210_MP02(0),
199 .ngpio = S5PV210_GPIO_MP02_NR,
200 .label = "MP02",
201 },
202 }, {
203 .config = &gpio_cfg_noint,
204 .chip = {
205 .base = S5PV210_MP03(0),
206 .ngpio = S5PV210_GPIO_MP03_NR,
207 .label = "MP03",
208 },
209 }, {
210 .config = &gpio_cfg_noint,
211 .chip = {
212 .base = S5PV210_MP04(0),
213 .ngpio = S5PV210_GPIO_MP04_NR,
214 .label = "MP04",
215 },
216 }, {
217 .config = &gpio_cfg_noint,
218 .chip = {
219 .base = S5PV210_MP05(0),
220 .ngpio = S5PV210_GPIO_MP05_NR,
221 .label = "MP05",
222 },
223 }, {
224 .base = (S5P_VA_GPIO + 0xC00),
225 .config = &gpio_cfg_noint,
226 .irq_base = IRQ_EINT(0),
227 .chip = {
228 .base = S5PV210_GPH0(0),
229 .ngpio = S5PV210_GPIO_H0_NR,
230 .label = "GPH0",
231 .to_irq = samsung_gpiolib_to_irq,
232 },
233 }, {
234 .base = (S5P_VA_GPIO + 0xC20),
235 .config = &gpio_cfg_noint,
236 .irq_base = IRQ_EINT(8),
237 .chip = {
238 .base = S5PV210_GPH1(0),
239 .ngpio = S5PV210_GPIO_H1_NR,
240 .label = "GPH1",
241 .to_irq = samsung_gpiolib_to_irq,
242 },
243 }, {
244 .base = (S5P_VA_GPIO + 0xC40),
245 .config = &gpio_cfg_noint,
246 .irq_base = IRQ_EINT(16),
247 .chip = {
248 .base = S5PV210_GPH2(0),
249 .ngpio = S5PV210_GPIO_H2_NR,
250 .label = "GPH2",
251 .to_irq = samsung_gpiolib_to_irq,
252 },
253 }, {
254 .base = (S5P_VA_GPIO + 0xC60),
255 .config = &gpio_cfg_noint,
256 .irq_base = IRQ_EINT(24),
257 .chip = {
258 .base = S5PV210_GPH3(0),
259 .ngpio = S5PV210_GPIO_H3_NR,
260 .label = "GPH3",
261 .to_irq = samsung_gpiolib_to_irq,
262 },
263 },
264};
265
266static __init int s5pv210_gpiolib_init(void)
267{
268 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
269 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
270 int gpioint_group = 0;
271 int i = 0;
272
273 for (i = 0; i < nr_chips; i++, chip++) {
274 if (chip->config == NULL) {
275 chip->config = &gpio_cfg;
276 chip->group = gpioint_group++;
277 }
278 if (chip->base == NULL)
279 chip->base = S5PV210_BANK_BASE(i);
280 }
281
282 samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
283 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
284
285 return 0;
286}
287core_initcall(s5pv210_gpiolib_init);
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
new file mode 100644
index 000000000000..866251852719
--- /dev/null
+++ b/drivers/gpio/gpio-samsung.c
@@ -0,0 +1,2712 @@
1/*
2 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * SAMSUNG - GPIOlib support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kernel.h>
18#include <linux/irq.h>
19#include <linux/io.h>
20#include <linux/gpio.h>
21#include <linux/init.h>
22#include <linux/spinlock.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/sysdev.h>
26#include <linux/ioport.h>
27
28#include <asm/irq.h>
29
30#include <mach/hardware.h>
31#include <mach/map.h>
32#include <mach/regs-clock.h>
33#include <mach/regs-gpio.h>
34
35#include <plat/cpu.h>
36#include <plat/gpio-core.h>
37#include <plat/gpio-cfg.h>
38#include <plat/gpio-cfg-helpers.h>
39#include <plat/gpio-fns.h>
40#include <plat/pm.h>
41
42#ifndef DEBUG_GPIO
43#define gpio_dbg(x...) do { } while (0)
44#else
45#define gpio_dbg(x...) printk(KERN_DEBUG x)
46#endif
47
48int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
49 unsigned int off, samsung_gpio_pull_t pull)
50{
51 void __iomem *reg = chip->base + 0x08;
52 int shift = off * 2;
53 u32 pup;
54
55 pup = __raw_readl(reg);
56 pup &= ~(3 << shift);
57 pup |= pull << shift;
58 __raw_writel(pup, reg);
59
60 return 0;
61}
62
63samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
64 unsigned int off)
65{
66 void __iomem *reg = chip->base + 0x08;
67 int shift = off * 2;
68 u32 pup = __raw_readl(reg);
69
70 pup >>= shift;
71 pup &= 0x3;
72
73 return (__force samsung_gpio_pull_t)pup;
74}
75
76int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
77 unsigned int off, samsung_gpio_pull_t pull)
78{
79 switch (pull) {
80 case S3C_GPIO_PULL_NONE:
81 pull = 0x01;
82 break;
83 case S3C_GPIO_PULL_UP:
84 pull = 0x00;
85 break;
86 case S3C_GPIO_PULL_DOWN:
87 pull = 0x02;
88 break;
89 }
90 return samsung_gpio_setpull_updown(chip, off, pull);
91}
92
93samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
94 unsigned int off)
95{
96 samsung_gpio_pull_t pull;
97
98 pull = samsung_gpio_getpull_updown(chip, off);
99
100 switch (pull) {
101 case 0x00:
102 pull = S3C_GPIO_PULL_UP;
103 break;
104 case 0x01:
105 case 0x03:
106 pull = S3C_GPIO_PULL_NONE;
107 break;
108 case 0x02:
109 pull = S3C_GPIO_PULL_DOWN;
110 break;
111 }
112
113 return pull;
114}
115
116static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
117 unsigned int off, samsung_gpio_pull_t pull,
118 samsung_gpio_pull_t updown)
119{
120 void __iomem *reg = chip->base + 0x08;
121 u32 pup = __raw_readl(reg);
122
123 if (pull == updown)
124 pup &= ~(1 << off);
125 else if (pull == S3C_GPIO_PULL_NONE)
126 pup |= (1 << off);
127 else
128 return -EINVAL;
129
130 __raw_writel(pup, reg);
131 return 0;
132}
133
134static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
135 unsigned int off,
136 samsung_gpio_pull_t updown)
137{
138 void __iomem *reg = chip->base + 0x08;
139 u32 pup = __raw_readl(reg);
140
141 pup &= (1 << off);
142 return pup ? S3C_GPIO_PULL_NONE : updown;
143}
144
145samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
146 unsigned int off)
147{
148 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
149}
150
151int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
152 unsigned int off, samsung_gpio_pull_t pull)
153{
154 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
155}
156
157samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
158 unsigned int off)
159{
160 return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
161}
162
163int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
164 unsigned int off, samsung_gpio_pull_t pull)
165{
166 return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
167}
168
169static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
170 unsigned int off, samsung_gpio_pull_t pull)
171{
172 if (pull == S3C_GPIO_PULL_UP)
173 pull = 3;
174
175 return samsung_gpio_setpull_updown(chip, off, pull);
176}
177
178static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip,
179 unsigned int off)
180{
181 samsung_gpio_pull_t pull;
182
183 pull = samsung_gpio_getpull_updown(chip, off);
184
185 if (pull == 3)
186 pull = S3C_GPIO_PULL_UP;
187
188 return pull;
189}
190
191/*
192 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
193 * @chip: The gpio chip that is being configured.
194 * @off: The offset for the GPIO being configured.
195 * @cfg: The configuration value to set.
196 *
197 * This helper deal with the GPIO cases where the control register
198 * has two bits of configuration per gpio, which have the following
199 * functions:
200 * 00 = input
201 * 01 = output
202 * 1x = special function
203 */
204
205static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
206 unsigned int off, unsigned int cfg)
207{
208 void __iomem *reg = chip->base;
209 unsigned int shift = off * 2;
210 u32 con;
211
212 if (samsung_gpio_is_cfg_special(cfg)) {
213 cfg &= 0xf;
214 if (cfg > 3)
215 return -EINVAL;
216
217 cfg <<= shift;
218 }
219
220 con = __raw_readl(reg);
221 con &= ~(0x3 << shift);
222 con |= cfg;
223 __raw_writel(con, reg);
224
225 return 0;
226}
227
228/*
229 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
230 * @chip: The gpio chip that is being configured.
231 * @off: The offset for the GPIO being configured.
232 *
233 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value whicg
234 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
235 * S3C_GPIO_SPECIAL() macro.
236 */
237
238static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
239 unsigned int off)
240{
241 u32 con;
242
243 con = __raw_readl(chip->base);
244 con >>= off * 2;
245 con &= 3;
246
247 /* this conversion works for IN and OUT as well as special mode */
248 return S3C_GPIO_SPECIAL(con);
249}
250
251/*
252 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
253 * @chip: The gpio chip that is being configured.
254 * @off: The offset for the GPIO being configured.
255 * @cfg: The configuration value to set.
256 *
257 * This helper deal with the GPIO cases where the control register has 4 bits
258 * of control per GPIO, generally in the form of:
259 * 0000 = Input
260 * 0001 = Output
261 * others = Special functions (dependent on bank)
262 *
263 * Note, since the code to deal with the case where there are two control
264 * registers instead of one, we do not have a separate set of functions for
265 * each case.
266 */
267
268static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
269 unsigned int off, unsigned int cfg)
270{
271 void __iomem *reg = chip->base;
272 unsigned int shift = (off & 7) * 4;
273 u32 con;
274
275 if (off < 8 && chip->chip.ngpio > 8)
276 reg -= 4;
277
278 if (samsung_gpio_is_cfg_special(cfg)) {
279 cfg &= 0xf;
280 cfg <<= shift;
281 }
282
283 con = __raw_readl(reg);
284 con &= ~(0xf << shift);
285 con |= cfg;
286 __raw_writel(con, reg);
287
288 return 0;
289}
290
291/*
292 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
293 * @chip: The gpio chip that is being configured.
294 * @off: The offset for the GPIO being configured.
295 *
296 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
297 * register setting into a value the software can use, such as could be passed
298 * to samsung_gpio_setcfg_4bit().
299 *
300 * @sa samsung_gpio_getcfg_2bit
301 */
302
303static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
304 unsigned int off)
305{
306 void __iomem *reg = chip->base;
307 unsigned int shift = (off & 7) * 4;
308 u32 con;
309
310 if (off < 8 && chip->chip.ngpio > 8)
311 reg -= 4;
312
313 con = __raw_readl(reg);
314 con >>= shift;
315 con &= 0xf;
316
317 /* this conversion works for IN and OUT as well as special mode */
318 return S3C_GPIO_SPECIAL(con);
319}
320
321#ifdef CONFIG_PLAT_S3C24XX
322/*
323 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
324 * @chip: The gpio chip that is being configured.
325 * @off: The offset for the GPIO being configured.
326 * @cfg: The configuration value to set.
327 *
328 * This helper deal with the GPIO cases where the control register
329 * has one bit of configuration for the gpio, where setting the bit
330 * means the pin is in special function mode and unset means output.
331 */
332
333static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
334 unsigned int off, unsigned int cfg)
335{
336 void __iomem *reg = chip->base;
337 unsigned int shift = off;
338 u32 con;
339
340 if (samsung_gpio_is_cfg_special(cfg)) {
341 cfg &= 0xf;
342
343 /* Map output to 0, and SFN2 to 1 */
344 cfg -= 1;
345 if (cfg > 1)
346 return -EINVAL;
347
348 cfg <<= shift;
349 }
350
351 con = __raw_readl(reg);
352 con &= ~(0x1 << shift);
353 con |= cfg;
354 __raw_writel(con, reg);
355
356 return 0;
357}
358
359/*
360 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
361 * @chip: The gpio chip that is being configured.
362 * @off: The offset for the GPIO being configured.
363 *
364 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
365 * GPIO configuration value.
366 *
367 * @sa samsung_gpio_getcfg_2bit
368 * @sa samsung_gpio_getcfg_4bit
369 */
370
371static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
372 unsigned int off)
373{
374 u32 con;
375
376 con = __raw_readl(chip->base);
377 con >>= off;
378 con &= 1;
379 con++;
380
381 return S3C_GPIO_SFN(con);
382}
383#endif
384
385#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
386static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
387 unsigned int off, unsigned int cfg)
388{
389 void __iomem *reg = chip->base;
390 unsigned int shift;
391 u32 con;
392
393 switch (off) {
394 case 0:
395 case 1:
396 case 2:
397 case 3:
398 case 4:
399 case 5:
400 shift = (off & 7) * 4;
401 reg -= 4;
402 break;
403 case 6:
404 shift = ((off + 1) & 7) * 4;
405 reg -= 4;
406 default:
407 shift = ((off + 1) & 7) * 4;
408 break;
409 }
410
411 if (samsung_gpio_is_cfg_special(cfg)) {
412 cfg &= 0xf;
413 cfg <<= shift;
414 }
415
416 con = __raw_readl(reg);
417 con &= ~(0xf << shift);
418 con |= cfg;
419 __raw_writel(con, reg);
420
421 return 0;
422}
423#endif
424
425static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
426 int nr_chips)
427{
428 for (; nr_chips > 0; nr_chips--, chipcfg++) {
429 if (!chipcfg->set_config)
430 chipcfg->set_config = samsung_gpio_setcfg_4bit;
431 if (!chipcfg->get_config)
432 chipcfg->get_config = samsung_gpio_getcfg_4bit;
433 if (!chipcfg->set_pull)
434 chipcfg->set_pull = samsung_gpio_setpull_updown;
435 if (!chipcfg->get_pull)
436 chipcfg->get_pull = samsung_gpio_getpull_updown;
437 }
438}
439
440struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
441 .set_config = samsung_gpio_setcfg_2bit,
442 .get_config = samsung_gpio_getcfg_2bit,
443};
444
445#ifdef CONFIG_PLAT_S3C24XX
446static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
447 .set_config = s3c24xx_gpio_setcfg_abank,
448 .get_config = s3c24xx_gpio_getcfg_abank,
449};
450#endif
451
452static struct samsung_gpio_cfg exynos4_gpio_cfg = {
453 .set_pull = exynos4_gpio_setpull,
454 .get_pull = exynos4_gpio_getpull,
455 .set_config = samsung_gpio_setcfg_4bit,
456 .get_config = samsung_gpio_getcfg_4bit,
457};
458
459#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
460static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
461 .cfg_eint = 0x3,
462 .set_config = s5p64x0_gpio_setcfg_rbank,
463 .get_config = samsung_gpio_getcfg_4bit,
464 .set_pull = samsung_gpio_setpull_updown,
465 .get_pull = samsung_gpio_getpull_updown,
466};
467#endif
468
469static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
470 {
471 .cfg_eint = 0x0,
472 }, {
473 .cfg_eint = 0x3,
474 }, {
475 .cfg_eint = 0x7,
476 }, {
477 .cfg_eint = 0xF,
478 }, {
479 .cfg_eint = 0x0,
480 .set_config = samsung_gpio_setcfg_2bit,
481 .get_config = samsung_gpio_getcfg_2bit,
482 }, {
483 .cfg_eint = 0x2,
484 .set_config = samsung_gpio_setcfg_2bit,
485 .get_config = samsung_gpio_getcfg_2bit,
486 }, {
487 .cfg_eint = 0x3,
488 .set_config = samsung_gpio_setcfg_2bit,
489 .get_config = samsung_gpio_getcfg_2bit,
490 }, {
491 .set_config = samsung_gpio_setcfg_2bit,
492 .get_config = samsung_gpio_getcfg_2bit,
493 }, {
494 .set_pull = exynos4_gpio_setpull,
495 .get_pull = exynos4_gpio_getpull,
496 }, {
497 .cfg_eint = 0x3,
498 .set_pull = exynos4_gpio_setpull,
499 .get_pull = exynos4_gpio_getpull,
500 }
501};
502
503/*
504 * Default routines for controlling GPIO, based on the original S3C24XX
505 * GPIO functions which deal with the case where each gpio bank of the
506 * chip is as following:
507 *
508 * base + 0x00: Control register, 2 bits per gpio
509 * gpio n: 2 bits starting at (2*n)
510 * 00 = input, 01 = output, others mean special-function
511 * base + 0x04: Data register, 1 bit per gpio
512 * bit n: data bit n
513*/
514
515static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
516{
517 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
518 void __iomem *base = ourchip->base;
519 unsigned long flags;
520 unsigned long con;
521
522 samsung_gpio_lock(ourchip, flags);
523
524 con = __raw_readl(base + 0x00);
525 con &= ~(3 << (offset * 2));
526
527 __raw_writel(con, base + 0x00);
528
529 samsung_gpio_unlock(ourchip, flags);
530 return 0;
531}
532
533static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
534 unsigned offset, int value)
535{
536 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
537 void __iomem *base = ourchip->base;
538 unsigned long flags;
539 unsigned long dat;
540 unsigned long con;
541
542 samsung_gpio_lock(ourchip, flags);
543
544 dat = __raw_readl(base + 0x04);
545 dat &= ~(1 << offset);
546 if (value)
547 dat |= 1 << offset;
548 __raw_writel(dat, base + 0x04);
549
550 con = __raw_readl(base + 0x00);
551 con &= ~(3 << (offset * 2));
552 con |= 1 << (offset * 2);
553
554 __raw_writel(con, base + 0x00);
555 __raw_writel(dat, base + 0x04);
556
557 samsung_gpio_unlock(ourchip, flags);
558 return 0;
559}
560
561/*
562 * The samsung_gpiolib_4bit routines are to control the gpio banks where
563 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
564 * following example:
565 *
566 * base + 0x00: Control register, 4 bits per gpio
567 * gpio n: 4 bits starting at (4*n)
568 * 0000 = input, 0001 = output, others mean special-function
569 * base + 0x04: Data register, 1 bit per gpio
570 * bit n: data bit n
571 *
572 * Note, since the data register is one bit per gpio and is at base + 0x4
573 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
574 * state of the output.
575 */
576
577static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
578 unsigned int offset)
579{
580 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
581 void __iomem *base = ourchip->base;
582 unsigned long con;
583
584 con = __raw_readl(base + GPIOCON_OFF);
585 con &= ~(0xf << con_4bit_shift(offset));
586 __raw_writel(con, base + GPIOCON_OFF);
587
588 gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
589
590 return 0;
591}
592
593static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
594 unsigned int offset, int value)
595{
596 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
597 void __iomem *base = ourchip->base;
598 unsigned long con;
599 unsigned long dat;
600
601 con = __raw_readl(base + GPIOCON_OFF);
602 con &= ~(0xf << con_4bit_shift(offset));
603 con |= 0x1 << con_4bit_shift(offset);
604
605 dat = __raw_readl(base + GPIODAT_OFF);
606
607 if (value)
608 dat |= 1 << offset;
609 else
610 dat &= ~(1 << offset);
611
612 __raw_writel(dat, base + GPIODAT_OFF);
613 __raw_writel(con, base + GPIOCON_OFF);
614 __raw_writel(dat, base + GPIODAT_OFF);
615
616 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
617
618 return 0;
619}
620
621/*
622 * The next set of routines are for the case where the GPIO configuration
623 * registers are 4 bits per GPIO but there is more than one register (the
624 * bank has more than 8 GPIOs.
625 *
626 * This case is the similar to the 4 bit case, but the registers are as
627 * follows:
628 *
629 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
630 * gpio n: 4 bits starting at (4*n)
631 * 0000 = input, 0001 = output, others mean special-function
632 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
633 * gpio n: 4 bits starting at (4*n)
634 * 0000 = input, 0001 = output, others mean special-function
635 * base + 0x08: Data register, 1 bit per gpio
636 * bit n: data bit n
637 *
638 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
639 * routines we store the 'base + 0x4' address so that these routines see
640 * the data register at ourchip->base + 0x04.
641 */
642
643static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
644 unsigned int offset)
645{
646 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
647 void __iomem *base = ourchip->base;
648 void __iomem *regcon = base;
649 unsigned long con;
650
651 if (offset > 7)
652 offset -= 8;
653 else
654 regcon -= 4;
655
656 con = __raw_readl(regcon);
657 con &= ~(0xf << con_4bit_shift(offset));
658 __raw_writel(con, regcon);
659
660 gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
661
662 return 0;
663}
664
665static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
666 unsigned int offset, int value)
667{
668 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
669 void __iomem *base = ourchip->base;
670 void __iomem *regcon = base;
671 unsigned long con;
672 unsigned long dat;
673 unsigned con_offset = offset;
674
675 if (con_offset > 7)
676 con_offset -= 8;
677 else
678 regcon -= 4;
679
680 con = __raw_readl(regcon);
681 con &= ~(0xf << con_4bit_shift(con_offset));
682 con |= 0x1 << con_4bit_shift(con_offset);
683
684 dat = __raw_readl(base + GPIODAT_OFF);
685
686 if (value)
687 dat |= 1 << offset;
688 else
689 dat &= ~(1 << offset);
690
691 __raw_writel(dat, base + GPIODAT_OFF);
692 __raw_writel(con, regcon);
693 __raw_writel(dat, base + GPIODAT_OFF);
694
695 gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
696
697 return 0;
698}
699
700#ifdef CONFIG_PLAT_S3C24XX
701/* The next set of routines are for the case of s3c24xx bank a */
702
703static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
704{
705 return -EINVAL;
706}
707
708static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
709 unsigned offset, int value)
710{
711 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
712 void __iomem *base = ourchip->base;
713 unsigned long flags;
714 unsigned long dat;
715 unsigned long con;
716
717 local_irq_save(flags);
718
719 con = __raw_readl(base + 0x00);
720 dat = __raw_readl(base + 0x04);
721
722 dat &= ~(1 << offset);
723 if (value)
724 dat |= 1 << offset;
725
726 __raw_writel(dat, base + 0x04);
727
728 con &= ~(1 << offset);
729
730 __raw_writel(con, base + 0x00);
731 __raw_writel(dat, base + 0x04);
732
733 local_irq_restore(flags);
734 return 0;
735}
736#endif
737
738/* The next set of routines are for the case of s5p64x0 bank r */
739
740static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
741 unsigned int offset)
742{
743 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
744 void __iomem *base = ourchip->base;
745 void __iomem *regcon = base;
746 unsigned long con;
747 unsigned long flags;
748
749 switch (offset) {
750 case 6:
751 offset += 1;
752 case 0:
753 case 1:
754 case 2:
755 case 3:
756 case 4:
757 case 5:
758 regcon -= 4;
759 break;
760 default:
761 offset -= 7;
762 break;
763 }
764
765 samsung_gpio_lock(ourchip, flags);
766
767 con = __raw_readl(regcon);
768 con &= ~(0xf << con_4bit_shift(offset));
769 __raw_writel(con, regcon);
770
771 samsung_gpio_unlock(ourchip, flags);
772
773 return 0;
774}
775
776static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
777 unsigned int offset, int value)
778{
779 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
780 void __iomem *base = ourchip->base;
781 void __iomem *regcon = base;
782 unsigned long con;
783 unsigned long dat;
784 unsigned long flags;
785 unsigned con_offset = offset;
786
787 switch (con_offset) {
788 case 6:
789 con_offset += 1;
790 case 0:
791 case 1:
792 case 2:
793 case 3:
794 case 4:
795 case 5:
796 regcon -= 4;
797 break;
798 default:
799 con_offset -= 7;
800 break;
801 }
802
803 samsung_gpio_lock(ourchip, flags);
804
805 con = __raw_readl(regcon);
806 con &= ~(0xf << con_4bit_shift(con_offset));
807 con |= 0x1 << con_4bit_shift(con_offset);
808
809 dat = __raw_readl(base + GPIODAT_OFF);
810 if (value)
811 dat |= 1 << offset;
812 else
813 dat &= ~(1 << offset);
814
815 __raw_writel(con, regcon);
816 __raw_writel(dat, base + GPIODAT_OFF);
817
818 samsung_gpio_unlock(ourchip, flags);
819
820 return 0;
821}
822
823static void samsung_gpiolib_set(struct gpio_chip *chip,
824 unsigned offset, int value)
825{
826 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
827 void __iomem *base = ourchip->base;
828 unsigned long flags;
829 unsigned long dat;
830
831 samsung_gpio_lock(ourchip, flags);
832
833 dat = __raw_readl(base + 0x04);
834 dat &= ~(1 << offset);
835 if (value)
836 dat |= 1 << offset;
837 __raw_writel(dat, base + 0x04);
838
839 samsung_gpio_unlock(ourchip, flags);
840}
841
842static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
843{
844 struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
845 unsigned long val;
846
847 val = __raw_readl(ourchip->base + 0x04);
848 val >>= offset;
849 val &= 1;
850
851 return val;
852}
853
854/*
855 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
856 * for use with the configuration calls, and other parts of the s3c gpiolib
857 * support code.
858 *
859 * Not all s3c support code will need this, as some configurations of cpu
860 * may only support one or two different configuration options and have an
861 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
862 * the machine support file should provide its own samsung_gpiolib_getchip()
863 * and any other necessary functions.
864 */
865
866#ifdef CONFIG_S3C_GPIO_TRACK
867struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
868
869static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
870{
871 unsigned int gpn;
872 int i;
873
874 gpn = chip->chip.base;
875 for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
876 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
877 s3c_gpios[gpn] = chip;
878 }
879}
880#endif /* CONFIG_S3C_GPIO_TRACK */
881
882/*
883 * samsung_gpiolib_add() - add the Samsung gpio_chip.
884 * @chip: The chip to register
885 *
886 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
887 * information and makes the necessary alterations for the platform and
888 * notes the information for use with the configuration systems and any
889 * other parts of the system.
890 */
891
892static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
893{
894 struct gpio_chip *gc = &chip->chip;
895 int ret;
896
897 BUG_ON(!chip->base);
898 BUG_ON(!gc->label);
899 BUG_ON(!gc->ngpio);
900
901 spin_lock_init(&chip->lock);
902
903 if (!gc->direction_input)
904 gc->direction_input = samsung_gpiolib_2bit_input;
905 if (!gc->direction_output)
906 gc->direction_output = samsung_gpiolib_2bit_output;
907 if (!gc->set)
908 gc->set = samsung_gpiolib_set;
909 if (!gc->get)
910 gc->get = samsung_gpiolib_get;
911
912#ifdef CONFIG_PM
913 if (chip->pm != NULL) {
914 if (!chip->pm->save || !chip->pm->resume)
915 printk(KERN_ERR "gpio: %s has missing PM functions\n",
916 gc->label);
917 } else
918 printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
919#endif
920
921 /* gpiochip_add() prints own failure message on error. */
922 ret = gpiochip_add(gc);
923 if (ret >= 0)
924 s3c_gpiolib_track(chip);
925}
926
927static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
928 int nr_chips, void __iomem *base)
929{
930 int i;
931 struct gpio_chip *gc = &chip->chip;
932
933 for (i = 0 ; i < nr_chips; i++, chip++) {
934 /* skip banks not present on SoC */
935 if (chip->chip.base >= S3C_GPIO_END)
936 continue;
937
938 if (!chip->config)
939 chip->config = &s3c24xx_gpiocfg_default;
940 if (!chip->pm)
941 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
942 if ((base != NULL) && (chip->base == NULL))
943 chip->base = base + ((i) * 0x10);
944
945 if (!gc->direction_input)
946 gc->direction_input = samsung_gpiolib_2bit_input;
947 if (!gc->direction_output)
948 gc->direction_output = samsung_gpiolib_2bit_output;
949
950 samsung_gpiolib_add(chip);
951 }
952}
953
954static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
955 int nr_chips, void __iomem *base,
956 unsigned int offset)
957{
958 int i;
959
960 for (i = 0 ; i < nr_chips; i++, chip++) {
961 chip->chip.direction_input = samsung_gpiolib_2bit_input;
962 chip->chip.direction_output = samsung_gpiolib_2bit_output;
963
964 if (!chip->config)
965 chip->config = &samsung_gpio_cfgs[7];
966 if (!chip->pm)
967 chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
968 if ((base != NULL) && (chip->base == NULL))
969 chip->base = base + ((i) * offset);
970
971 samsung_gpiolib_add(chip);
972 }
973}
974
975/*
976 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
977 * @chip: The gpio chip that is being configured.
978 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
979 *
980 * This helper deal with the GPIO cases where the control register has 4 bits
981 * of control per GPIO, generally in the form of:
982 * 0000 = Input
983 * 0001 = Output
984 * others = Special functions (dependent on bank)
985 *
986 * Note, since the code to deal with the case where there are two control
987 * registers instead of one, we do not have a separate set of function
988 * (samsung_gpiolib_add_4bit2_chips)for each case.
989 */
990
991static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
992 int nr_chips, void __iomem *base)
993{
994 int i;
995
996 for (i = 0 ; i < nr_chips; i++, chip++) {
997 chip->chip.direction_input = samsung_gpiolib_4bit_input;
998 chip->chip.direction_output = samsung_gpiolib_4bit_output;
999
1000 if (!chip->config)
1001 chip->config = &samsung_gpio_cfgs[2];
1002 if (!chip->pm)
1003 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1004 if ((base != NULL) && (chip->base == NULL))
1005 chip->base = base + ((i) * 0x20);
1006
1007 samsung_gpiolib_add(chip);
1008 }
1009}
1010
1011static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
1012 int nr_chips)
1013{
1014 for (; nr_chips > 0; nr_chips--, chip++) {
1015 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
1016 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
1017
1018 if (!chip->config)
1019 chip->config = &samsung_gpio_cfgs[2];
1020 if (!chip->pm)
1021 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1022
1023 samsung_gpiolib_add(chip);
1024 }
1025}
1026
1027static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
1028 int nr_chips)
1029{
1030 for (; nr_chips > 0; nr_chips--, chip++) {
1031 chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
1032 chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
1033
1034 if (!chip->pm)
1035 chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
1036
1037 samsung_gpiolib_add(chip);
1038 }
1039}
1040
1041int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
1042{
1043 struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
1044
1045 return samsung_chip->irq_base + offset;
1046}
1047
1048#ifdef CONFIG_PLAT_S3C24XX
1049static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
1050{
1051 if (offset < 4)
1052 return IRQ_EINT0 + offset;
1053
1054 if (offset < 8)
1055 return IRQ_EINT4 + offset - 4;
1056
1057 return -EINVAL;
1058}
1059#endif
1060
1061#ifdef CONFIG_PLAT_S3C64XX
1062static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
1063{
1064 return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
1065}
1066
1067static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
1068{
1069 return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
1070}
1071#endif
1072
1073struct samsung_gpio_chip s3c24xx_gpios[] = {
1074#ifdef CONFIG_PLAT_S3C24XX
1075 {
1076 .config = &s3c24xx_gpiocfg_banka,
1077 .chip = {
1078 .base = S3C2410_GPA(0),
1079 .owner = THIS_MODULE,
1080 .label = "GPIOA",
1081 .ngpio = 24,
1082 .direction_input = s3c24xx_gpiolib_banka_input,
1083 .direction_output = s3c24xx_gpiolib_banka_output,
1084 },
1085 }, {
1086 .chip = {
1087 .base = S3C2410_GPB(0),
1088 .owner = THIS_MODULE,
1089 .label = "GPIOB",
1090 .ngpio = 16,
1091 },
1092 }, {
1093 .chip = {
1094 .base = S3C2410_GPC(0),
1095 .owner = THIS_MODULE,
1096 .label = "GPIOC",
1097 .ngpio = 16,
1098 },
1099 }, {
1100 .chip = {
1101 .base = S3C2410_GPD(0),
1102 .owner = THIS_MODULE,
1103 .label = "GPIOD",
1104 .ngpio = 16,
1105 },
1106 }, {
1107 .chip = {
1108 .base = S3C2410_GPE(0),
1109 .label = "GPIOE",
1110 .owner = THIS_MODULE,
1111 .ngpio = 16,
1112 },
1113 }, {
1114 .chip = {
1115 .base = S3C2410_GPF(0),
1116 .owner = THIS_MODULE,
1117 .label = "GPIOF",
1118 .ngpio = 8,
1119 .to_irq = s3c24xx_gpiolib_fbank_to_irq,
1120 },
1121 }, {
1122 .irq_base = IRQ_EINT8,
1123 .chip = {
1124 .base = S3C2410_GPG(0),
1125 .owner = THIS_MODULE,
1126 .label = "GPIOG",
1127 .ngpio = 16,
1128 .to_irq = samsung_gpiolib_to_irq,
1129 },
1130 }, {
1131 .chip = {
1132 .base = S3C2410_GPH(0),
1133 .owner = THIS_MODULE,
1134 .label = "GPIOH",
1135 .ngpio = 11,
1136 },
1137 },
1138 /* GPIOS for the S3C2443 and later devices. */
1139 {
1140 .base = S3C2440_GPJCON,
1141 .chip = {
1142 .base = S3C2410_GPJ(0),
1143 .owner = THIS_MODULE,
1144 .label = "GPIOJ",
1145 .ngpio = 16,
1146 },
1147 }, {
1148 .base = S3C2443_GPKCON,
1149 .chip = {
1150 .base = S3C2410_GPK(0),
1151 .owner = THIS_MODULE,
1152 .label = "GPIOK",
1153 .ngpio = 16,
1154 },
1155 }, {
1156 .base = S3C2443_GPLCON,
1157 .chip = {
1158 .base = S3C2410_GPL(0),
1159 .owner = THIS_MODULE,
1160 .label = "GPIOL",
1161 .ngpio = 15,
1162 },
1163 }, {
1164 .base = S3C2443_GPMCON,
1165 .chip = {
1166 .base = S3C2410_GPM(0),
1167 .owner = THIS_MODULE,
1168 .label = "GPIOM",
1169 .ngpio = 2,
1170 },
1171 },
1172#endif
1173};
1174
1175/*
1176 * GPIO bank summary:
1177 *
1178 * Bank GPIOs Style SlpCon ExtInt Group
1179 * A 8 4Bit Yes 1
1180 * B 7 4Bit Yes 1
1181 * C 8 4Bit Yes 2
1182 * D 5 4Bit Yes 3
1183 * E 5 4Bit Yes None
1184 * F 16 2Bit Yes 4 [1]
1185 * G 7 4Bit Yes 5
1186 * H 10 4Bit[2] Yes 6
1187 * I 16 2Bit Yes None
1188 * J 12 2Bit Yes None
1189 * K 16 4Bit[2] No None
1190 * L 15 4Bit[2] No None
1191 * M 6 4Bit No IRQ_EINT
1192 * N 16 2Bit No IRQ_EINT
1193 * O 16 2Bit Yes 7
1194 * P 15 2Bit Yes 8
1195 * Q 9 2Bit Yes 9
1196 *
1197 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1198 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1199 */
1200
1201static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1202#ifdef CONFIG_PLAT_S3C64XX
1203 {
1204 .chip = {
1205 .base = S3C64XX_GPA(0),
1206 .ngpio = S3C64XX_GPIO_A_NR,
1207 .label = "GPA",
1208 },
1209 }, {
1210 .chip = {
1211 .base = S3C64XX_GPB(0),
1212 .ngpio = S3C64XX_GPIO_B_NR,
1213 .label = "GPB",
1214 },
1215 }, {
1216 .chip = {
1217 .base = S3C64XX_GPC(0),
1218 .ngpio = S3C64XX_GPIO_C_NR,
1219 .label = "GPC",
1220 },
1221 }, {
1222 .chip = {
1223 .base = S3C64XX_GPD(0),
1224 .ngpio = S3C64XX_GPIO_D_NR,
1225 .label = "GPD",
1226 },
1227 }, {
1228 .config = &samsung_gpio_cfgs[0],
1229 .chip = {
1230 .base = S3C64XX_GPE(0),
1231 .ngpio = S3C64XX_GPIO_E_NR,
1232 .label = "GPE",
1233 },
1234 }, {
1235 .base = S3C64XX_GPG_BASE,
1236 .chip = {
1237 .base = S3C64XX_GPG(0),
1238 .ngpio = S3C64XX_GPIO_G_NR,
1239 .label = "GPG",
1240 },
1241 }, {
1242 .base = S3C64XX_GPM_BASE,
1243 .config = &samsung_gpio_cfgs[1],
1244 .chip = {
1245 .base = S3C64XX_GPM(0),
1246 .ngpio = S3C64XX_GPIO_M_NR,
1247 .label = "GPM",
1248 .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1249 },
1250 },
1251#endif
1252};
1253
1254static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1255#ifdef CONFIG_PLAT_S3C64XX
1256 {
1257 .base = S3C64XX_GPH_BASE + 0x4,
1258 .chip = {
1259 .base = S3C64XX_GPH(0),
1260 .ngpio = S3C64XX_GPIO_H_NR,
1261 .label = "GPH",
1262 },
1263 }, {
1264 .base = S3C64XX_GPK_BASE + 0x4,
1265 .config = &samsung_gpio_cfgs[0],
1266 .chip = {
1267 .base = S3C64XX_GPK(0),
1268 .ngpio = S3C64XX_GPIO_K_NR,
1269 .label = "GPK",
1270 },
1271 }, {
1272 .base = S3C64XX_GPL_BASE + 0x4,
1273 .config = &samsung_gpio_cfgs[1],
1274 .chip = {
1275 .base = S3C64XX_GPL(0),
1276 .ngpio = S3C64XX_GPIO_L_NR,
1277 .label = "GPL",
1278 .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1279 },
1280 },
1281#endif
1282};
1283
1284static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1285#ifdef CONFIG_PLAT_S3C64XX
1286 {
1287 .base = S3C64XX_GPF_BASE,
1288 .config = &samsung_gpio_cfgs[6],
1289 .chip = {
1290 .base = S3C64XX_GPF(0),
1291 .ngpio = S3C64XX_GPIO_F_NR,
1292 .label = "GPF",
1293 },
1294 }, {
1295 .config = &samsung_gpio_cfgs[7],
1296 .chip = {
1297 .base = S3C64XX_GPI(0),
1298 .ngpio = S3C64XX_GPIO_I_NR,
1299 .label = "GPI",
1300 },
1301 }, {
1302 .config = &samsung_gpio_cfgs[7],
1303 .chip = {
1304 .base = S3C64XX_GPJ(0),
1305 .ngpio = S3C64XX_GPIO_J_NR,
1306 .label = "GPJ",
1307 },
1308 }, {
1309 .config = &samsung_gpio_cfgs[6],
1310 .chip = {
1311 .base = S3C64XX_GPO(0),
1312 .ngpio = S3C64XX_GPIO_O_NR,
1313 .label = "GPO",
1314 },
1315 }, {
1316 .config = &samsung_gpio_cfgs[6],
1317 .chip = {
1318 .base = S3C64XX_GPP(0),
1319 .ngpio = S3C64XX_GPIO_P_NR,
1320 .label = "GPP",
1321 },
1322 }, {
1323 .config = &samsung_gpio_cfgs[6],
1324 .chip = {
1325 .base = S3C64XX_GPQ(0),
1326 .ngpio = S3C64XX_GPIO_Q_NR,
1327 .label = "GPQ",
1328 },
1329 }, {
1330 .base = S3C64XX_GPN_BASE,
1331 .irq_base = IRQ_EINT(0),
1332 .config = &samsung_gpio_cfgs[5],
1333 .chip = {
1334 .base = S3C64XX_GPN(0),
1335 .ngpio = S3C64XX_GPIO_N_NR,
1336 .label = "GPN",
1337 .to_irq = samsung_gpiolib_to_irq,
1338 },
1339 },
1340#endif
1341};
1342
1343/*
1344 * S5P6440 GPIO bank summary:
1345 *
1346 * Bank GPIOs Style SlpCon ExtInt Group
1347 * A 6 4Bit Yes 1
1348 * B 7 4Bit Yes 1
1349 * C 8 4Bit Yes 2
1350 * F 2 2Bit Yes 4 [1]
1351 * G 7 4Bit Yes 5
1352 * H 10 4Bit[2] Yes 6
1353 * I 16 2Bit Yes None
1354 * J 12 2Bit Yes None
1355 * N 16 2Bit No IRQ_EINT
1356 * P 8 2Bit Yes 8
1357 * R 15 4Bit[2] Yes 8
1358 */
1359
1360static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
1361#ifdef CONFIG_CPU_S5P6440
1362 {
1363 .chip = {
1364 .base = S5P6440_GPA(0),
1365 .ngpio = S5P6440_GPIO_A_NR,
1366 .label = "GPA",
1367 },
1368 }, {
1369 .chip = {
1370 .base = S5P6440_GPB(0),
1371 .ngpio = S5P6440_GPIO_B_NR,
1372 .label = "GPB",
1373 },
1374 }, {
1375 .chip = {
1376 .base = S5P6440_GPC(0),
1377 .ngpio = S5P6440_GPIO_C_NR,
1378 .label = "GPC",
1379 },
1380 }, {
1381 .base = S5P64X0_GPG_BASE,
1382 .chip = {
1383 .base = S5P6440_GPG(0),
1384 .ngpio = S5P6440_GPIO_G_NR,
1385 .label = "GPG",
1386 },
1387 },
1388#endif
1389};
1390
1391static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
1392#ifdef CONFIG_CPU_S5P6440
1393 {
1394 .base = S5P64X0_GPH_BASE + 0x4,
1395 .chip = {
1396 .base = S5P6440_GPH(0),
1397 .ngpio = S5P6440_GPIO_H_NR,
1398 .label = "GPH",
1399 },
1400 },
1401#endif
1402};
1403
1404static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
1405#ifdef CONFIG_CPU_S5P6440
1406 {
1407 .base = S5P64X0_GPR_BASE + 0x4,
1408 .config = &s5p64x0_gpio_cfg_rbank,
1409 .chip = {
1410 .base = S5P6440_GPR(0),
1411 .ngpio = S5P6440_GPIO_R_NR,
1412 .label = "GPR",
1413 },
1414 },
1415#endif
1416};
1417
1418static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
1419#ifdef CONFIG_CPU_S5P6440
1420 {
1421 .base = S5P64X0_GPF_BASE,
1422 .config = &samsung_gpio_cfgs[6],
1423 .chip = {
1424 .base = S5P6440_GPF(0),
1425 .ngpio = S5P6440_GPIO_F_NR,
1426 .label = "GPF",
1427 },
1428 }, {
1429 .base = S5P64X0_GPI_BASE,
1430 .config = &samsung_gpio_cfgs[4],
1431 .chip = {
1432 .base = S5P6440_GPI(0),
1433 .ngpio = S5P6440_GPIO_I_NR,
1434 .label = "GPI",
1435 },
1436 }, {
1437 .base = S5P64X0_GPJ_BASE,
1438 .config = &samsung_gpio_cfgs[4],
1439 .chip = {
1440 .base = S5P6440_GPJ(0),
1441 .ngpio = S5P6440_GPIO_J_NR,
1442 .label = "GPJ",
1443 },
1444 }, {
1445 .base = S5P64X0_GPN_BASE,
1446 .config = &samsung_gpio_cfgs[5],
1447 .chip = {
1448 .base = S5P6440_GPN(0),
1449 .ngpio = S5P6440_GPIO_N_NR,
1450 .label = "GPN",
1451 },
1452 }, {
1453 .base = S5P64X0_GPP_BASE,
1454 .config = &samsung_gpio_cfgs[6],
1455 .chip = {
1456 .base = S5P6440_GPP(0),
1457 .ngpio = S5P6440_GPIO_P_NR,
1458 .label = "GPP",
1459 },
1460 },
1461#endif
1462};
1463
1464/*
1465 * S5P6450 GPIO bank summary:
1466 *
1467 * Bank GPIOs Style SlpCon ExtInt Group
1468 * A 6 4Bit Yes 1
1469 * B 7 4Bit Yes 1
1470 * C 8 4Bit Yes 2
1471 * D 8 4Bit Yes None
1472 * F 2 2Bit Yes None
1473 * G 14 4Bit[2] Yes 5
1474 * H 10 4Bit[2] Yes 6
1475 * I 16 2Bit Yes None
1476 * J 12 2Bit Yes None
1477 * K 5 4Bit Yes None
1478 * N 16 2Bit No IRQ_EINT
1479 * P 11 2Bit Yes 8
1480 * Q 14 2Bit Yes None
1481 * R 15 4Bit[2] Yes None
1482 * S 8 2Bit Yes None
1483 *
1484 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1485 * [2] BANK has two control registers, GPxCON0 and GPxCON1
1486 */
1487
1488static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
1489#ifdef CONFIG_CPU_S5P6450
1490 {
1491 .chip = {
1492 .base = S5P6450_GPA(0),
1493 .ngpio = S5P6450_GPIO_A_NR,
1494 .label = "GPA",
1495 },
1496 }, {
1497 .chip = {
1498 .base = S5P6450_GPB(0),
1499 .ngpio = S5P6450_GPIO_B_NR,
1500 .label = "GPB",
1501 },
1502 }, {
1503 .chip = {
1504 .base = S5P6450_GPC(0),
1505 .ngpio = S5P6450_GPIO_C_NR,
1506 .label = "GPC",
1507 },
1508 }, {
1509 .chip = {
1510 .base = S5P6450_GPD(0),
1511 .ngpio = S5P6450_GPIO_D_NR,
1512 .label = "GPD",
1513 },
1514 }, {
1515 .base = S5P6450_GPK_BASE,
1516 .chip = {
1517 .base = S5P6450_GPK(0),
1518 .ngpio = S5P6450_GPIO_K_NR,
1519 .label = "GPK",
1520 },
1521 },
1522#endif
1523};
1524
1525static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
1526#ifdef CONFIG_CPU_S5P6450
1527 {
1528 .base = S5P64X0_GPG_BASE + 0x4,
1529 .chip = {
1530 .base = S5P6450_GPG(0),
1531 .ngpio = S5P6450_GPIO_G_NR,
1532 .label = "GPG",
1533 },
1534 }, {
1535 .base = S5P64X0_GPH_BASE + 0x4,
1536 .chip = {
1537 .base = S5P6450_GPH(0),
1538 .ngpio = S5P6450_GPIO_H_NR,
1539 .label = "GPH",
1540 },
1541 },
1542#endif
1543};
1544
1545static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
1546#ifdef CONFIG_CPU_S5P6450
1547 {
1548 .base = S5P64X0_GPR_BASE + 0x4,
1549 .config = &s5p64x0_gpio_cfg_rbank,
1550 .chip = {
1551 .base = S5P6450_GPR(0),
1552 .ngpio = S5P6450_GPIO_R_NR,
1553 .label = "GPR",
1554 },
1555 },
1556#endif
1557};
1558
1559static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
1560#ifdef CONFIG_CPU_S5P6450
1561 {
1562 .base = S5P64X0_GPF_BASE,
1563 .config = &samsung_gpio_cfgs[6],
1564 .chip = {
1565 .base = S5P6450_GPF(0),
1566 .ngpio = S5P6450_GPIO_F_NR,
1567 .label = "GPF",
1568 },
1569 }, {
1570 .base = S5P64X0_GPI_BASE,
1571 .config = &samsung_gpio_cfgs[4],
1572 .chip = {
1573 .base = S5P6450_GPI(0),
1574 .ngpio = S5P6450_GPIO_I_NR,
1575 .label = "GPI",
1576 },
1577 }, {
1578 .base = S5P64X0_GPJ_BASE,
1579 .config = &samsung_gpio_cfgs[4],
1580 .chip = {
1581 .base = S5P6450_GPJ(0),
1582 .ngpio = S5P6450_GPIO_J_NR,
1583 .label = "GPJ",
1584 },
1585 }, {
1586 .base = S5P64X0_GPN_BASE,
1587 .config = &samsung_gpio_cfgs[5],
1588 .chip = {
1589 .base = S5P6450_GPN(0),
1590 .ngpio = S5P6450_GPIO_N_NR,
1591 .label = "GPN",
1592 },
1593 }, {
1594 .base = S5P64X0_GPP_BASE,
1595 .config = &samsung_gpio_cfgs[6],
1596 .chip = {
1597 .base = S5P6450_GPP(0),
1598 .ngpio = S5P6450_GPIO_P_NR,
1599 .label = "GPP",
1600 },
1601 }, {
1602 .base = S5P6450_GPQ_BASE,
1603 .config = &samsung_gpio_cfgs[5],
1604 .chip = {
1605 .base = S5P6450_GPQ(0),
1606 .ngpio = S5P6450_GPIO_Q_NR,
1607 .label = "GPQ",
1608 },
1609 }, {
1610 .base = S5P6450_GPS_BASE,
1611 .config = &samsung_gpio_cfgs[6],
1612 .chip = {
1613 .base = S5P6450_GPS(0),
1614 .ngpio = S5P6450_GPIO_S_NR,
1615 .label = "GPS",
1616 },
1617 },
1618#endif
1619};
1620
1621/*
1622 * S5PC100 GPIO bank summary:
1623 *
1624 * Bank GPIOs Style INT Type
1625 * A0 8 4Bit GPIO_INT0
1626 * A1 5 4Bit GPIO_INT1
1627 * B 8 4Bit GPIO_INT2
1628 * C 5 4Bit GPIO_INT3
1629 * D 7 4Bit GPIO_INT4
1630 * E0 8 4Bit GPIO_INT5
1631 * E1 6 4Bit GPIO_INT6
1632 * F0 8 4Bit GPIO_INT7
1633 * F1 8 4Bit GPIO_INT8
1634 * F2 8 4Bit GPIO_INT9
1635 * F3 4 4Bit GPIO_INT10
1636 * G0 8 4Bit GPIO_INT11
1637 * G1 3 4Bit GPIO_INT12
1638 * G2 7 4Bit GPIO_INT13
1639 * G3 7 4Bit GPIO_INT14
1640 * H0 8 4Bit WKUP_INT
1641 * H1 8 4Bit WKUP_INT
1642 * H2 8 4Bit WKUP_INT
1643 * H3 8 4Bit WKUP_INT
1644 * I 8 4Bit GPIO_INT15
1645 * J0 8 4Bit GPIO_INT16
1646 * J1 5 4Bit GPIO_INT17
1647 * J2 8 4Bit GPIO_INT18
1648 * J3 8 4Bit GPIO_INT19
1649 * J4 4 4Bit GPIO_INT20
1650 * K0 8 4Bit None
1651 * K1 6 4Bit None
1652 * K2 8 4Bit None
1653 * K3 8 4Bit None
1654 * L0 8 4Bit None
1655 * L1 8 4Bit None
1656 * L2 8 4Bit None
1657 * L3 8 4Bit None
1658 */
1659
1660static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
1661#ifdef CONFIG_CPU_S5PC100
1662 {
1663 .chip = {
1664 .base = S5PC100_GPA0(0),
1665 .ngpio = S5PC100_GPIO_A0_NR,
1666 .label = "GPA0",
1667 },
1668 }, {
1669 .chip = {
1670 .base = S5PC100_GPA1(0),
1671 .ngpio = S5PC100_GPIO_A1_NR,
1672 .label = "GPA1",
1673 },
1674 }, {
1675 .chip = {
1676 .base = S5PC100_GPB(0),
1677 .ngpio = S5PC100_GPIO_B_NR,
1678 .label = "GPB",
1679 },
1680 }, {
1681 .chip = {
1682 .base = S5PC100_GPC(0),
1683 .ngpio = S5PC100_GPIO_C_NR,
1684 .label = "GPC",
1685 },
1686 }, {
1687 .chip = {
1688 .base = S5PC100_GPD(0),
1689 .ngpio = S5PC100_GPIO_D_NR,
1690 .label = "GPD",
1691 },
1692 }, {
1693 .chip = {
1694 .base = S5PC100_GPE0(0),
1695 .ngpio = S5PC100_GPIO_E0_NR,
1696 .label = "GPE0",
1697 },
1698 }, {
1699 .chip = {
1700 .base = S5PC100_GPE1(0),
1701 .ngpio = S5PC100_GPIO_E1_NR,
1702 .label = "GPE1",
1703 },
1704 }, {
1705 .chip = {
1706 .base = S5PC100_GPF0(0),
1707 .ngpio = S5PC100_GPIO_F0_NR,
1708 .label = "GPF0",
1709 },
1710 }, {
1711 .chip = {
1712 .base = S5PC100_GPF1(0),
1713 .ngpio = S5PC100_GPIO_F1_NR,
1714 .label = "GPF1",
1715 },
1716 }, {
1717 .chip = {
1718 .base = S5PC100_GPF2(0),
1719 .ngpio = S5PC100_GPIO_F2_NR,
1720 .label = "GPF2",
1721 },
1722 }, {
1723 .chip = {
1724 .base = S5PC100_GPF3(0),
1725 .ngpio = S5PC100_GPIO_F3_NR,
1726 .label = "GPF3",
1727 },
1728 }, {
1729 .chip = {
1730 .base = S5PC100_GPG0(0),
1731 .ngpio = S5PC100_GPIO_G0_NR,
1732 .label = "GPG0",
1733 },
1734 }, {
1735 .chip = {
1736 .base = S5PC100_GPG1(0),
1737 .ngpio = S5PC100_GPIO_G1_NR,
1738 .label = "GPG1",
1739 },
1740 }, {
1741 .chip = {
1742 .base = S5PC100_GPG2(0),
1743 .ngpio = S5PC100_GPIO_G2_NR,
1744 .label = "GPG2",
1745 },
1746 }, {
1747 .chip = {
1748 .base = S5PC100_GPG3(0),
1749 .ngpio = S5PC100_GPIO_G3_NR,
1750 .label = "GPG3",
1751 },
1752 }, {
1753 .chip = {
1754 .base = S5PC100_GPI(0),
1755 .ngpio = S5PC100_GPIO_I_NR,
1756 .label = "GPI",
1757 },
1758 }, {
1759 .chip = {
1760 .base = S5PC100_GPJ0(0),
1761 .ngpio = S5PC100_GPIO_J0_NR,
1762 .label = "GPJ0",
1763 },
1764 }, {
1765 .chip = {
1766 .base = S5PC100_GPJ1(0),
1767 .ngpio = S5PC100_GPIO_J1_NR,
1768 .label = "GPJ1",
1769 },
1770 }, {
1771 .chip = {
1772 .base = S5PC100_GPJ2(0),
1773 .ngpio = S5PC100_GPIO_J2_NR,
1774 .label = "GPJ2",
1775 },
1776 }, {
1777 .chip = {
1778 .base = S5PC100_GPJ3(0),
1779 .ngpio = S5PC100_GPIO_J3_NR,
1780 .label = "GPJ3",
1781 },
1782 }, {
1783 .chip = {
1784 .base = S5PC100_GPJ4(0),
1785 .ngpio = S5PC100_GPIO_J4_NR,
1786 .label = "GPJ4",
1787 },
1788 }, {
1789 .chip = {
1790 .base = S5PC100_GPK0(0),
1791 .ngpio = S5PC100_GPIO_K0_NR,
1792 .label = "GPK0",
1793 },
1794 }, {
1795 .chip = {
1796 .base = S5PC100_GPK1(0),
1797 .ngpio = S5PC100_GPIO_K1_NR,
1798 .label = "GPK1",
1799 },
1800 }, {
1801 .chip = {
1802 .base = S5PC100_GPK2(0),
1803 .ngpio = S5PC100_GPIO_K2_NR,
1804 .label = "GPK2",
1805 },
1806 }, {
1807 .chip = {
1808 .base = S5PC100_GPK3(0),
1809 .ngpio = S5PC100_GPIO_K3_NR,
1810 .label = "GPK3",
1811 },
1812 }, {
1813 .chip = {
1814 .base = S5PC100_GPL0(0),
1815 .ngpio = S5PC100_GPIO_L0_NR,
1816 .label = "GPL0",
1817 },
1818 }, {
1819 .chip = {
1820 .base = S5PC100_GPL1(0),
1821 .ngpio = S5PC100_GPIO_L1_NR,
1822 .label = "GPL1",
1823 },
1824 }, {
1825 .chip = {
1826 .base = S5PC100_GPL2(0),
1827 .ngpio = S5PC100_GPIO_L2_NR,
1828 .label = "GPL2",
1829 },
1830 }, {
1831 .chip = {
1832 .base = S5PC100_GPL3(0),
1833 .ngpio = S5PC100_GPIO_L3_NR,
1834 .label = "GPL3",
1835 },
1836 }, {
1837 .chip = {
1838 .base = S5PC100_GPL4(0),
1839 .ngpio = S5PC100_GPIO_L4_NR,
1840 .label = "GPL4",
1841 },
1842 }, {
1843 .base = (S5P_VA_GPIO + 0xC00),
1844 .irq_base = IRQ_EINT(0),
1845 .chip = {
1846 .base = S5PC100_GPH0(0),
1847 .ngpio = S5PC100_GPIO_H0_NR,
1848 .label = "GPH0",
1849 .to_irq = samsung_gpiolib_to_irq,
1850 },
1851 }, {
1852 .base = (S5P_VA_GPIO + 0xC20),
1853 .irq_base = IRQ_EINT(8),
1854 .chip = {
1855 .base = S5PC100_GPH1(0),
1856 .ngpio = S5PC100_GPIO_H1_NR,
1857 .label = "GPH1",
1858 .to_irq = samsung_gpiolib_to_irq,
1859 },
1860 }, {
1861 .base = (S5P_VA_GPIO + 0xC40),
1862 .irq_base = IRQ_EINT(16),
1863 .chip = {
1864 .base = S5PC100_GPH2(0),
1865 .ngpio = S5PC100_GPIO_H2_NR,
1866 .label = "GPH2",
1867 .to_irq = samsung_gpiolib_to_irq,
1868 },
1869 }, {
1870 .base = (S5P_VA_GPIO + 0xC60),
1871 .irq_base = IRQ_EINT(24),
1872 .chip = {
1873 .base = S5PC100_GPH3(0),
1874 .ngpio = S5PC100_GPIO_H3_NR,
1875 .label = "GPH3",
1876 .to_irq = samsung_gpiolib_to_irq,
1877 },
1878 },
1879#endif
1880};
1881
1882/*
1883 * Followings are the gpio banks in S5PV210/S5PC110
1884 *
1885 * The 'config' member when left to NULL, is initialized to the default
1886 * structure samsung_gpio_cfgs[3] in the init function below.
1887 *
1888 * The 'base' member is also initialized in the init function below.
1889 * Note: The initialization of 'base' member of samsung_gpio_chip structure
1890 * uses the above macro and depends on the banks being listed in order here.
1891 */
1892
1893static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
1894#ifdef CONFIG_CPU_S5PV210
1895 {
1896 .chip = {
1897 .base = S5PV210_GPA0(0),
1898 .ngpio = S5PV210_GPIO_A0_NR,
1899 .label = "GPA0",
1900 },
1901 }, {
1902 .chip = {
1903 .base = S5PV210_GPA1(0),
1904 .ngpio = S5PV210_GPIO_A1_NR,
1905 .label = "GPA1",
1906 },
1907 }, {
1908 .chip = {
1909 .base = S5PV210_GPB(0),
1910 .ngpio = S5PV210_GPIO_B_NR,
1911 .label = "GPB",
1912 },
1913 }, {
1914 .chip = {
1915 .base = S5PV210_GPC0(0),
1916 .ngpio = S5PV210_GPIO_C0_NR,
1917 .label = "GPC0",
1918 },
1919 }, {
1920 .chip = {
1921 .base = S5PV210_GPC1(0),
1922 .ngpio = S5PV210_GPIO_C1_NR,
1923 .label = "GPC1",
1924 },
1925 }, {
1926 .chip = {
1927 .base = S5PV210_GPD0(0),
1928 .ngpio = S5PV210_GPIO_D0_NR,
1929 .label = "GPD0",
1930 },
1931 }, {
1932 .chip = {
1933 .base = S5PV210_GPD1(0),
1934 .ngpio = S5PV210_GPIO_D1_NR,
1935 .label = "GPD1",
1936 },
1937 }, {
1938 .chip = {
1939 .base = S5PV210_GPE0(0),
1940 .ngpio = S5PV210_GPIO_E0_NR,
1941 .label = "GPE0",
1942 },
1943 }, {
1944 .chip = {
1945 .base = S5PV210_GPE1(0),
1946 .ngpio = S5PV210_GPIO_E1_NR,
1947 .label = "GPE1",
1948 },
1949 }, {
1950 .chip = {
1951 .base = S5PV210_GPF0(0),
1952 .ngpio = S5PV210_GPIO_F0_NR,
1953 .label = "GPF0",
1954 },
1955 }, {
1956 .chip = {
1957 .base = S5PV210_GPF1(0),
1958 .ngpio = S5PV210_GPIO_F1_NR,
1959 .label = "GPF1",
1960 },
1961 }, {
1962 .chip = {
1963 .base = S5PV210_GPF2(0),
1964 .ngpio = S5PV210_GPIO_F2_NR,
1965 .label = "GPF2",
1966 },
1967 }, {
1968 .chip = {
1969 .base = S5PV210_GPF3(0),
1970 .ngpio = S5PV210_GPIO_F3_NR,
1971 .label = "GPF3",
1972 },
1973 }, {
1974 .chip = {
1975 .base = S5PV210_GPG0(0),
1976 .ngpio = S5PV210_GPIO_G0_NR,
1977 .label = "GPG0",
1978 },
1979 }, {
1980 .chip = {
1981 .base = S5PV210_GPG1(0),
1982 .ngpio = S5PV210_GPIO_G1_NR,
1983 .label = "GPG1",
1984 },
1985 }, {
1986 .chip = {
1987 .base = S5PV210_GPG2(0),
1988 .ngpio = S5PV210_GPIO_G2_NR,
1989 .label = "GPG2",
1990 },
1991 }, {
1992 .chip = {
1993 .base = S5PV210_GPG3(0),
1994 .ngpio = S5PV210_GPIO_G3_NR,
1995 .label = "GPG3",
1996 },
1997 }, {
1998 .chip = {
1999 .base = S5PV210_GPI(0),
2000 .ngpio = S5PV210_GPIO_I_NR,
2001 .label = "GPI",
2002 },
2003 }, {
2004 .chip = {
2005 .base = S5PV210_GPJ0(0),
2006 .ngpio = S5PV210_GPIO_J0_NR,
2007 .label = "GPJ0",
2008 },
2009 }, {
2010 .chip = {
2011 .base = S5PV210_GPJ1(0),
2012 .ngpio = S5PV210_GPIO_J1_NR,
2013 .label = "GPJ1",
2014 },
2015 }, {
2016 .chip = {
2017 .base = S5PV210_GPJ2(0),
2018 .ngpio = S5PV210_GPIO_J2_NR,
2019 .label = "GPJ2",
2020 },
2021 }, {
2022 .chip = {
2023 .base = S5PV210_GPJ3(0),
2024 .ngpio = S5PV210_GPIO_J3_NR,
2025 .label = "GPJ3",
2026 },
2027 }, {
2028 .chip = {
2029 .base = S5PV210_GPJ4(0),
2030 .ngpio = S5PV210_GPIO_J4_NR,
2031 .label = "GPJ4",
2032 },
2033 }, {
2034 .chip = {
2035 .base = S5PV210_MP01(0),
2036 .ngpio = S5PV210_GPIO_MP01_NR,
2037 .label = "MP01",
2038 },
2039 }, {
2040 .chip = {
2041 .base = S5PV210_MP02(0),
2042 .ngpio = S5PV210_GPIO_MP02_NR,
2043 .label = "MP02",
2044 },
2045 }, {
2046 .chip = {
2047 .base = S5PV210_MP03(0),
2048 .ngpio = S5PV210_GPIO_MP03_NR,
2049 .label = "MP03",
2050 },
2051 }, {
2052 .chip = {
2053 .base = S5PV210_MP04(0),
2054 .ngpio = S5PV210_GPIO_MP04_NR,
2055 .label = "MP04",
2056 },
2057 }, {
2058 .chip = {
2059 .base = S5PV210_MP05(0),
2060 .ngpio = S5PV210_GPIO_MP05_NR,
2061 .label = "MP05",
2062 },
2063 }, {
2064 .base = (S5P_VA_GPIO + 0xC00),
2065 .irq_base = IRQ_EINT(0),
2066 .chip = {
2067 .base = S5PV210_GPH0(0),
2068 .ngpio = S5PV210_GPIO_H0_NR,
2069 .label = "GPH0",
2070 .to_irq = samsung_gpiolib_to_irq,
2071 },
2072 }, {
2073 .base = (S5P_VA_GPIO + 0xC20),
2074 .irq_base = IRQ_EINT(8),
2075 .chip = {
2076 .base = S5PV210_GPH1(0),
2077 .ngpio = S5PV210_GPIO_H1_NR,
2078 .label = "GPH1",
2079 .to_irq = samsung_gpiolib_to_irq,
2080 },
2081 }, {
2082 .base = (S5P_VA_GPIO + 0xC40),
2083 .irq_base = IRQ_EINT(16),
2084 .chip = {
2085 .base = S5PV210_GPH2(0),
2086 .ngpio = S5PV210_GPIO_H2_NR,
2087 .label = "GPH2",
2088 .to_irq = samsung_gpiolib_to_irq,
2089 },
2090 }, {
2091 .base = (S5P_VA_GPIO + 0xC60),
2092 .irq_base = IRQ_EINT(24),
2093 .chip = {
2094 .base = S5PV210_GPH3(0),
2095 .ngpio = S5PV210_GPIO_H3_NR,
2096 .label = "GPH3",
2097 .to_irq = samsung_gpiolib_to_irq,
2098 },
2099 },
2100#endif
2101};
2102
2103/*
2104 * Followings are the gpio banks in EXYNOS4210
2105 *
2106 * The 'config' member when left to NULL, is initialized to the default
2107 * structure samsung_gpio_cfgs[3] in the init function below.
2108 *
2109 * The 'base' member is also initialized in the init function below.
2110 * Note: The initialization of 'base' member of samsung_gpio_chip structure
2111 * uses the above macro and depends on the banks being listed in order here.
2112 */
2113
2114static struct samsung_gpio_chip exynos4_gpios_1[] = {
2115#ifdef CONFIG_ARCH_EXYNOS4
2116 {
2117 .chip = {
2118 .base = EXYNOS4_GPA0(0),
2119 .ngpio = EXYNOS4_GPIO_A0_NR,
2120 .label = "GPA0",
2121 },
2122 }, {
2123 .chip = {
2124 .base = EXYNOS4_GPA1(0),
2125 .ngpio = EXYNOS4_GPIO_A1_NR,
2126 .label = "GPA1",
2127 },
2128 }, {
2129 .chip = {
2130 .base = EXYNOS4_GPB(0),
2131 .ngpio = EXYNOS4_GPIO_B_NR,
2132 .label = "GPB",
2133 },
2134 }, {
2135 .chip = {
2136 .base = EXYNOS4_GPC0(0),
2137 .ngpio = EXYNOS4_GPIO_C0_NR,
2138 .label = "GPC0",
2139 },
2140 }, {
2141 .chip = {
2142 .base = EXYNOS4_GPC1(0),
2143 .ngpio = EXYNOS4_GPIO_C1_NR,
2144 .label = "GPC1",
2145 },
2146 }, {
2147 .chip = {
2148 .base = EXYNOS4_GPD0(0),
2149 .ngpio = EXYNOS4_GPIO_D0_NR,
2150 .label = "GPD0",
2151 },
2152 }, {
2153 .chip = {
2154 .base = EXYNOS4_GPD1(0),
2155 .ngpio = EXYNOS4_GPIO_D1_NR,
2156 .label = "GPD1",
2157 },
2158 }, {
2159 .chip = {
2160 .base = EXYNOS4_GPE0(0),
2161 .ngpio = EXYNOS4_GPIO_E0_NR,
2162 .label = "GPE0",
2163 },
2164 }, {
2165 .chip = {
2166 .base = EXYNOS4_GPE1(0),
2167 .ngpio = EXYNOS4_GPIO_E1_NR,
2168 .label = "GPE1",
2169 },
2170 }, {
2171 .chip = {
2172 .base = EXYNOS4_GPE2(0),
2173 .ngpio = EXYNOS4_GPIO_E2_NR,
2174 .label = "GPE2",
2175 },
2176 }, {
2177 .chip = {
2178 .base = EXYNOS4_GPE3(0),
2179 .ngpio = EXYNOS4_GPIO_E3_NR,
2180 .label = "GPE3",
2181 },
2182 }, {
2183 .chip = {
2184 .base = EXYNOS4_GPE4(0),
2185 .ngpio = EXYNOS4_GPIO_E4_NR,
2186 .label = "GPE4",
2187 },
2188 }, {
2189 .chip = {
2190 .base = EXYNOS4_GPF0(0),
2191 .ngpio = EXYNOS4_GPIO_F0_NR,
2192 .label = "GPF0",
2193 },
2194 }, {
2195 .chip = {
2196 .base = EXYNOS4_GPF1(0),
2197 .ngpio = EXYNOS4_GPIO_F1_NR,
2198 .label = "GPF1",
2199 },
2200 }, {
2201 .chip = {
2202 .base = EXYNOS4_GPF2(0),
2203 .ngpio = EXYNOS4_GPIO_F2_NR,
2204 .label = "GPF2",
2205 },
2206 }, {
2207 .chip = {
2208 .base = EXYNOS4_GPF3(0),
2209 .ngpio = EXYNOS4_GPIO_F3_NR,
2210 .label = "GPF3",
2211 },
2212 },
2213#endif
2214};
2215
2216static struct samsung_gpio_chip exynos4_gpios_2[] = {
2217#ifdef CONFIG_ARCH_EXYNOS4
2218 {
2219 .chip = {
2220 .base = EXYNOS4_GPJ0(0),
2221 .ngpio = EXYNOS4_GPIO_J0_NR,
2222 .label = "GPJ0",
2223 },
2224 }, {
2225 .chip = {
2226 .base = EXYNOS4_GPJ1(0),
2227 .ngpio = EXYNOS4_GPIO_J1_NR,
2228 .label = "GPJ1",
2229 },
2230 }, {
2231 .chip = {
2232 .base = EXYNOS4_GPK0(0),
2233 .ngpio = EXYNOS4_GPIO_K0_NR,
2234 .label = "GPK0",
2235 },
2236 }, {
2237 .chip = {
2238 .base = EXYNOS4_GPK1(0),
2239 .ngpio = EXYNOS4_GPIO_K1_NR,
2240 .label = "GPK1",
2241 },
2242 }, {
2243 .chip = {
2244 .base = EXYNOS4_GPK2(0),
2245 .ngpio = EXYNOS4_GPIO_K2_NR,
2246 .label = "GPK2",
2247 },
2248 }, {
2249 .chip = {
2250 .base = EXYNOS4_GPK3(0),
2251 .ngpio = EXYNOS4_GPIO_K3_NR,
2252 .label = "GPK3",
2253 },
2254 }, {
2255 .chip = {
2256 .base = EXYNOS4_GPL0(0),
2257 .ngpio = EXYNOS4_GPIO_L0_NR,
2258 .label = "GPL0",
2259 },
2260 }, {
2261 .chip = {
2262 .base = EXYNOS4_GPL1(0),
2263 .ngpio = EXYNOS4_GPIO_L1_NR,
2264 .label = "GPL1",
2265 },
2266 }, {
2267 .chip = {
2268 .base = EXYNOS4_GPL2(0),
2269 .ngpio = EXYNOS4_GPIO_L2_NR,
2270 .label = "GPL2",
2271 },
2272 }, {
2273 .config = &samsung_gpio_cfgs[8],
2274 .chip = {
2275 .base = EXYNOS4_GPY0(0),
2276 .ngpio = EXYNOS4_GPIO_Y0_NR,
2277 .label = "GPY0",
2278 },
2279 }, {
2280 .config = &samsung_gpio_cfgs[8],
2281 .chip = {
2282 .base = EXYNOS4_GPY1(0),
2283 .ngpio = EXYNOS4_GPIO_Y1_NR,
2284 .label = "GPY1",
2285 },
2286 }, {
2287 .config = &samsung_gpio_cfgs[8],
2288 .chip = {
2289 .base = EXYNOS4_GPY2(0),
2290 .ngpio = EXYNOS4_GPIO_Y2_NR,
2291 .label = "GPY2",
2292 },
2293 }, {
2294 .config = &samsung_gpio_cfgs[8],
2295 .chip = {
2296 .base = EXYNOS4_GPY3(0),
2297 .ngpio = EXYNOS4_GPIO_Y3_NR,
2298 .label = "GPY3",
2299 },
2300 }, {
2301 .config = &samsung_gpio_cfgs[8],
2302 .chip = {
2303 .base = EXYNOS4_GPY4(0),
2304 .ngpio = EXYNOS4_GPIO_Y4_NR,
2305 .label = "GPY4",
2306 },
2307 }, {
2308 .config = &samsung_gpio_cfgs[8],
2309 .chip = {
2310 .base = EXYNOS4_GPY5(0),
2311 .ngpio = EXYNOS4_GPIO_Y5_NR,
2312 .label = "GPY5",
2313 },
2314 }, {
2315 .config = &samsung_gpio_cfgs[8],
2316 .chip = {
2317 .base = EXYNOS4_GPY6(0),
2318 .ngpio = EXYNOS4_GPIO_Y6_NR,
2319 .label = "GPY6",
2320 },
2321 }, {
2322 .base = (S5P_VA_GPIO2 + 0xC00),
2323 .config = &samsung_gpio_cfgs[9],
2324 .irq_base = IRQ_EINT(0),
2325 .chip = {
2326 .base = EXYNOS4_GPX0(0),
2327 .ngpio = EXYNOS4_GPIO_X0_NR,
2328 .label = "GPX0",
2329 .to_irq = samsung_gpiolib_to_irq,
2330 },
2331 }, {
2332 .base = (S5P_VA_GPIO2 + 0xC20),
2333 .config = &samsung_gpio_cfgs[9],
2334 .irq_base = IRQ_EINT(8),
2335 .chip = {
2336 .base = EXYNOS4_GPX1(0),
2337 .ngpio = EXYNOS4_GPIO_X1_NR,
2338 .label = "GPX1",
2339 .to_irq = samsung_gpiolib_to_irq,
2340 },
2341 }, {
2342 .base = (S5P_VA_GPIO2 + 0xC40),
2343 .config = &samsung_gpio_cfgs[9],
2344 .irq_base = IRQ_EINT(16),
2345 .chip = {
2346 .base = EXYNOS4_GPX2(0),
2347 .ngpio = EXYNOS4_GPIO_X2_NR,
2348 .label = "GPX2",
2349 .to_irq = samsung_gpiolib_to_irq,
2350 },
2351 }, {
2352 .base = (S5P_VA_GPIO2 + 0xC60),
2353 .config = &samsung_gpio_cfgs[9],
2354 .irq_base = IRQ_EINT(24),
2355 .chip = {
2356 .base = EXYNOS4_GPX3(0),
2357 .ngpio = EXYNOS4_GPIO_X3_NR,
2358 .label = "GPX3",
2359 .to_irq = samsung_gpiolib_to_irq,
2360 },
2361 },
2362#endif
2363};
2364
2365static struct samsung_gpio_chip exynos4_gpios_3[] = {
2366#ifdef CONFIG_ARCH_EXYNOS4
2367 {
2368 .chip = {
2369 .base = EXYNOS4_GPZ(0),
2370 .ngpio = EXYNOS4_GPIO_Z_NR,
2371 .label = "GPZ",
2372 },
2373 },
2374#endif
2375};
2376
2377/* TODO: cleanup soc_is_* */
2378static __init int samsung_gpiolib_init(void)
2379{
2380 struct samsung_gpio_chip *chip;
2381 int i, nr_chips;
2382 int group = 0;
2383
2384 samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
2385
2386 if (soc_is_s3c24xx()) {
2387 s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
2388 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
2389 } else if (soc_is_s3c64xx()) {
2390 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
2391 ARRAY_SIZE(s3c64xx_gpios_2bit),
2392 S3C64XX_VA_GPIO + 0xE0, 0x20);
2393 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
2394 ARRAY_SIZE(s3c64xx_gpios_4bit),
2395 S3C64XX_VA_GPIO);
2396 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
2397 ARRAY_SIZE(s3c64xx_gpios_4bit2));
2398 } else if (soc_is_s5p6440()) {
2399 samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
2400 ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
2401 samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
2402 ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
2403 samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
2404 ARRAY_SIZE(s5p6440_gpios_4bit2));
2405 s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
2406 ARRAY_SIZE(s5p6440_gpios_rbank));
2407 } else if (soc_is_s5p6450()) {
2408 samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
2409 ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
2410 samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
2411 ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
2412 samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
2413 ARRAY_SIZE(s5p6450_gpios_4bit2));
2414 s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
2415 ARRAY_SIZE(s5p6450_gpios_rbank));
2416 } else if (soc_is_s5pc100()) {
2417 group = 0;
2418 chip = s5pc100_gpios_4bit;
2419 nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
2420
2421 for (i = 0; i < nr_chips; i++, chip++) {
2422 if (!chip->config) {
2423 chip->config = &samsung_gpio_cfgs[3];
2424 chip->group = group++;
2425 }
2426 }
2427 samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
2428#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
2429 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2430#endif
2431 } else if (soc_is_s5pv210()) {
2432 group = 0;
2433 chip = s5pv210_gpios_4bit;
2434 nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
2435
2436 for (i = 0; i < nr_chips; i++, chip++) {
2437 if (!chip->config) {
2438 chip->config = &samsung_gpio_cfgs[3];
2439 chip->group = group++;
2440 }
2441 }
2442 samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
2443#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
2444 s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
2445#endif
2446 } else if (soc_is_exynos4210()) {
2447 group = 0;
2448
2449 /* gpio part1 */
2450 chip = exynos4_gpios_1;
2451 nr_chips = ARRAY_SIZE(exynos4_gpios_1);
2452
2453 for (i = 0; i < nr_chips; i++, chip++) {
2454 if (!chip->config) {
2455 chip->config = &exynos4_gpio_cfg;
2456 chip->group = group++;
2457 }
2458 }
2459 samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
2460
2461 /* gpio part2 */
2462 chip = exynos4_gpios_2;
2463 nr_chips = ARRAY_SIZE(exynos4_gpios_2);
2464
2465 for (i = 0; i < nr_chips; i++, chip++) {
2466 if (!chip->config) {
2467 chip->config = &exynos4_gpio_cfg;
2468 chip->group = group++;
2469 }
2470 }
2471 samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
2472
2473 /* gpio part3 */
2474 chip = exynos4_gpios_3;
2475 nr_chips = ARRAY_SIZE(exynos4_gpios_3);
2476
2477 for (i = 0; i < nr_chips; i++, chip++) {
2478 if (!chip->config) {
2479 chip->config = &exynos4_gpio_cfg;
2480 chip->group = group++;
2481 }
2482 }
2483 samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
2484
2485#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
2486 s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
2487 s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
2488#endif
2489 } else {
2490 WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
2491 return -ENODEV;
2492 }
2493
2494 return 0;
2495}
2496core_initcall(samsung_gpiolib_init);
2497
2498int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
2499{
2500 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2501 unsigned long flags;
2502 int offset;
2503 int ret;
2504
2505 if (!chip)
2506 return -EINVAL;
2507
2508 offset = pin - chip->chip.base;
2509
2510 samsung_gpio_lock(chip, flags);
2511 ret = samsung_gpio_do_setcfg(chip, offset, config);
2512 samsung_gpio_unlock(chip, flags);
2513
2514 return ret;
2515}
2516EXPORT_SYMBOL(s3c_gpio_cfgpin);
2517
2518int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
2519 unsigned int cfg)
2520{
2521 int ret;
2522
2523 for (; nr > 0; nr--, start++) {
2524 ret = s3c_gpio_cfgpin(start, cfg);
2525 if (ret != 0)
2526 return ret;
2527 }
2528
2529 return 0;
2530}
2531EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
2532
2533int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
2534 unsigned int cfg, samsung_gpio_pull_t pull)
2535{
2536 int ret;
2537
2538 for (; nr > 0; nr--, start++) {
2539 s3c_gpio_setpull(start, pull);
2540 ret = s3c_gpio_cfgpin(start, cfg);
2541 if (ret != 0)
2542 return ret;
2543 }
2544
2545 return 0;
2546}
2547EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
2548
2549unsigned s3c_gpio_getcfg(unsigned int pin)
2550{
2551 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2552 unsigned long flags;
2553 unsigned ret = 0;
2554 int offset;
2555
2556 if (chip) {
2557 offset = pin - chip->chip.base;
2558
2559 samsung_gpio_lock(chip, flags);
2560 ret = samsung_gpio_do_getcfg(chip, offset);
2561 samsung_gpio_unlock(chip, flags);
2562 }
2563
2564 return ret;
2565}
2566EXPORT_SYMBOL(s3c_gpio_getcfg);
2567
2568int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
2569{
2570 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2571 unsigned long flags;
2572 int offset, ret;
2573
2574 if (!chip)
2575 return -EINVAL;
2576
2577 offset = pin - chip->chip.base;
2578
2579 samsung_gpio_lock(chip, flags);
2580 ret = samsung_gpio_do_setpull(chip, offset, pull);
2581 samsung_gpio_unlock(chip, flags);
2582
2583 return ret;
2584}
2585EXPORT_SYMBOL(s3c_gpio_setpull);
2586
2587samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
2588{
2589 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2590 unsigned long flags;
2591 int offset;
2592 u32 pup = 0;
2593
2594 if (chip) {
2595 offset = pin - chip->chip.base;
2596
2597 samsung_gpio_lock(chip, flags);
2598 pup = samsung_gpio_do_getpull(chip, offset);
2599 samsung_gpio_unlock(chip, flags);
2600 }
2601
2602 return (__force samsung_gpio_pull_t)pup;
2603}
2604EXPORT_SYMBOL(s3c_gpio_getpull);
2605
2606/* gpiolib wrappers until these are totally eliminated */
2607
2608void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
2609{
2610 int ret;
2611
2612 WARN_ON(to); /* should be none of these left */
2613
2614 if (!to) {
2615 /* if pull is enabled, try first with up, and if that
2616 * fails, try using down */
2617
2618 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
2619 if (ret)
2620 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
2621 } else {
2622 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
2623 }
2624}
2625EXPORT_SYMBOL(s3c2410_gpio_pullup);
2626
2627void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
2628{
2629 /* do this via gpiolib until all users removed */
2630
2631 gpio_request(pin, "temporary");
2632 gpio_set_value(pin, to);
2633 gpio_free(pin);
2634}
2635EXPORT_SYMBOL(s3c2410_gpio_setpin);
2636
2637unsigned int s3c2410_gpio_getpin(unsigned int pin)
2638{
2639 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2640 unsigned long offs = pin - chip->chip.base;
2641
2642 return __raw_readl(chip->base + 0x04) & (1 << offs);
2643}
2644EXPORT_SYMBOL(s3c2410_gpio_getpin);
2645
2646#ifdef CONFIG_S5P_GPIO_DRVSTR
2647s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
2648{
2649 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2650 unsigned int off;
2651 void __iomem *reg;
2652 int shift;
2653 u32 drvstr;
2654
2655 if (!chip)
2656 return -EINVAL;
2657
2658 off = pin - chip->chip.base;
2659 shift = off * 2;
2660 reg = chip->base + 0x0C;
2661
2662 drvstr = __raw_readl(reg);
2663 drvstr = drvstr >> shift;
2664 drvstr &= 0x3;
2665
2666 return (__force s5p_gpio_drvstr_t)drvstr;
2667}
2668EXPORT_SYMBOL(s5p_gpio_get_drvstr);
2669
2670int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
2671{
2672 struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
2673 unsigned int off;
2674 void __iomem *reg;
2675 int shift;
2676 u32 tmp;
2677
2678 if (!chip)
2679 return -EINVAL;
2680
2681 off = pin - chip->chip.base;
2682 shift = off * 2;
2683 reg = chip->base + 0x0C;
2684
2685 tmp = __raw_readl(reg);
2686 tmp &= ~(0x3 << shift);
2687 tmp |= drvstr << shift;
2688
2689 __raw_writel(tmp, reg);
2690
2691 return 0;
2692}
2693EXPORT_SYMBOL(s5p_gpio_set_drvstr);
2694#endif /* CONFIG_S5P_GPIO_DRVSTR */
2695
2696#ifdef CONFIG_PLAT_S3C24XX
2697unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
2698{
2699 unsigned long flags;
2700 unsigned long misccr;
2701
2702 local_irq_save(flags);
2703 misccr = __raw_readl(S3C24XX_MISCCR);
2704 misccr &= ~clear;
2705 misccr ^= change;
2706 __raw_writel(misccr, S3C24XX_MISCCR);
2707 local_irq_restore(flags);
2708
2709 return misccr;
2710}
2711EXPORT_SYMBOL(s3c2410_modify_misccr);
2712#endif
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 9b347acf1559..9ec854ae118b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -335,6 +335,7 @@ config SENSORS_I5K_AMB
335 335
336config SENSORS_F71805F 336config SENSORS_F71805F
337 tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" 337 tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG"
338 depends on !PPC
338 help 339 help
339 If you say yes here you get support for hardware monitoring 340 If you say yes here you get support for hardware monitoring
340 features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG 341 features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG
@@ -345,6 +346,7 @@ config SENSORS_F71805F
345 346
346config SENSORS_F71882FG 347config SENSORS_F71882FG
347 tristate "Fintek F71882FG and compatibles" 348 tristate "Fintek F71882FG and compatibles"
349 depends on !PPC
348 help 350 help
349 If you say yes here you get support for hardware monitoring 351 If you say yes here you get support for hardware monitoring
350 features of many Fintek Super-I/O (LPC) chips. The currently 352 features of many Fintek Super-I/O (LPC) chips. The currently
@@ -468,6 +470,7 @@ config SENSORS_IBMPEX
468 470
469config SENSORS_IT87 471config SENSORS_IT87
470 tristate "ITE IT87xx and compatibles" 472 tristate "ITE IT87xx and compatibles"
473 depends on !PPC
471 select HWMON_VID 474 select HWMON_VID
472 help 475 help
473 If you say yes here you get support for ITE IT8705F, IT8712F, 476 If you say yes here you get support for ITE IT8705F, IT8712F,
@@ -824,6 +827,7 @@ config SENSORS_NTC_THERMISTOR
824 827
825config SENSORS_PC87360 828config SENSORS_PC87360
826 tristate "National Semiconductor PC87360 family" 829 tristate "National Semiconductor PC87360 family"
830 depends on !PPC
827 select HWMON_VID 831 select HWMON_VID
828 help 832 help
829 If you say yes here you get access to the hardware monitoring 833 If you say yes here you get access to the hardware monitoring
@@ -837,6 +841,7 @@ config SENSORS_PC87360
837 841
838config SENSORS_PC87427 842config SENSORS_PC87427
839 tristate "National Semiconductor PC87427" 843 tristate "National Semiconductor PC87427"
844 depends on !PPC
840 help 845 help
841 If you say yes here you get access to the hardware monitoring 846 If you say yes here you get access to the hardware monitoring
842 functions of the National Semiconductor PC87427 Super-I/O chip. 847 functions of the National Semiconductor PC87427 Super-I/O chip.
@@ -928,7 +933,7 @@ config SENSORS_SMM665
928 933
929config SENSORS_DME1737 934config SENSORS_DME1737
930 tristate "SMSC DME1737, SCH311x and compatibles" 935 tristate "SMSC DME1737, SCH311x and compatibles"
931 depends on I2C && EXPERIMENTAL 936 depends on I2C && EXPERIMENTAL && !PPC
932 select HWMON_VID 937 select HWMON_VID
933 help 938 help
934 If you say yes here you get support for the hardware monitoring 939 If you say yes here you get support for the hardware monitoring
@@ -970,6 +975,7 @@ config SENSORS_EMC6W201
970 975
971config SENSORS_SMSC47M1 976config SENSORS_SMSC47M1
972 tristate "SMSC LPC47M10x and compatibles" 977 tristate "SMSC LPC47M10x and compatibles"
978 depends on !PPC
973 help 979 help
974 If you say yes here you get support for the integrated fan 980 If you say yes here you get support for the integrated fan
975 monitoring and control capabilities of the SMSC LPC47B27x, 981 monitoring and control capabilities of the SMSC LPC47B27x,
@@ -1003,7 +1009,7 @@ config SENSORS_SMSC47M192
1003 1009
1004config SENSORS_SMSC47B397 1010config SENSORS_SMSC47B397
1005 tristate "SMSC LPC47B397-NC" 1011 tristate "SMSC LPC47B397-NC"
1006 depends on EXPERIMENTAL 1012 depends on EXPERIMENTAL && !PPC
1007 help 1013 help
1008 If you say yes here you get support for the SMSC LPC47B397-NC 1014 If you say yes here you get support for the SMSC LPC47B397-NC
1009 sensor chip. 1015 sensor chip.
@@ -1017,6 +1023,7 @@ config SENSORS_SCH56XX_COMMON
1017 1023
1018config SENSORS_SCH5627 1024config SENSORS_SCH5627
1019 tristate "SMSC SCH5627" 1025 tristate "SMSC SCH5627"
1026 depends on !PPC
1020 select SENSORS_SCH56XX_COMMON 1027 select SENSORS_SCH56XX_COMMON
1021 help 1028 help
1022 If you say yes here you get support for the hardware monitoring 1029 If you say yes here you get support for the hardware monitoring
@@ -1027,6 +1034,7 @@ config SENSORS_SCH5627
1027 1034
1028config SENSORS_SCH5636 1035config SENSORS_SCH5636
1029 tristate "SMSC SCH5636" 1036 tristate "SMSC SCH5636"
1037 depends on !PPC
1030 select SENSORS_SCH56XX_COMMON 1038 select SENSORS_SCH56XX_COMMON
1031 help 1039 help
1032 SMSC SCH5636 Super I/O chips include an embedded microcontroller for 1040 SMSC SCH5636 Super I/O chips include an embedded microcontroller for
@@ -1150,6 +1158,7 @@ config SENSORS_VIA686A
1150 1158
1151config SENSORS_VT1211 1159config SENSORS_VT1211
1152 tristate "VIA VT1211" 1160 tristate "VIA VT1211"
1161 depends on !PPC
1153 select HWMON_VID 1162 select HWMON_VID
1154 help 1163 help
1155 If you say yes here then you get support for hardware monitoring 1164 If you say yes here then you get support for hardware monitoring
@@ -1262,6 +1271,7 @@ config SENSORS_W83L786NG
1262 1271
1263config SENSORS_W83627HF 1272config SENSORS_W83627HF
1264 tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" 1273 tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
1274 depends on !PPC
1265 select HWMON_VID 1275 select HWMON_VID
1266 help 1276 help
1267 If you say yes here you get support for the Winbond W836X7 series 1277 If you say yes here you get support for the Winbond W836X7 series
@@ -1272,7 +1282,8 @@ config SENSORS_W83627HF
1272 will be called w83627hf. 1282 will be called w83627hf.
1273 1283
1274config SENSORS_W83627EHF 1284config SENSORS_W83627EHF
1275 tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F" 1285 tristate "Winbond W83627EHF/EHG/DHG/UHG, W83667HG, NCT6775F, NCT6776F"
1286 depends on !PPC
1276 select HWMON_VID 1287 select HWMON_VID
1277 help 1288 help
1278 If you say yes here you get support for the hardware 1289 If you say yes here you get support for the hardware
@@ -1281,7 +1292,8 @@ config SENSORS_W83627EHF
1281 This driver also supports the W83627EHG, which is the lead-free 1292 This driver also supports the W83627EHG, which is the lead-free
1282 version of the W83627EHF, and the W83627DHG, which is a similar 1293 version of the W83627EHF, and the W83627DHG, which is a similar
1283 chip suited for specific Intel processors that use PECI such as 1294 chip suited for specific Intel processors that use PECI such as
1284 the Core 2 Duo. 1295 the Core 2 Duo. And also the W83627UHG, which is a stripped down
1296 version of the W83627DHG (as far as hardware monitoring goes.)
1285 1297
1286 This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F 1298 This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F
1287 (also known as W83667HG-I), and NCT6776F. 1299 (also known as W83667HG-I), and NCT6776F.
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index d46c0c758ddf..df29a7fff9e7 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -58,10 +58,9 @@ static inline int ad7414_temp_from_reg(s16 reg)
58 58
59static inline int ad7414_read(struct i2c_client *client, u8 reg) 59static inline int ad7414_read(struct i2c_client *client, u8 reg)
60{ 60{
61 if (reg == AD7414_REG_TEMP) { 61 if (reg == AD7414_REG_TEMP)
62 int value = i2c_smbus_read_word_data(client, reg); 62 return i2c_smbus_read_word_swapped(client, reg);
63 return (value < 0) ? value : swab16(value); 63 else
64 } else
65 return i2c_smbus_read_byte_data(client, reg); 64 return i2c_smbus_read_byte_data(client, reg);
66} 65}
67 66
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index ffc781fec185..8cb718ce8237 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -76,20 +76,6 @@ static struct i2c_driver ad7418_driver = {
76 .id_table = ad7418_id, 76 .id_table = ad7418_id,
77}; 77};
78 78
79/* All registers are word-sized, except for the configuration registers.
80 * AD7418 uses a high-byte first convention. Do NOT use those functions to
81 * access the configuration registers CONF and CONF2, as they are byte-sized.
82 */
83static inline int ad7418_read(struct i2c_client *client, u8 reg)
84{
85 return swab16(i2c_smbus_read_word_data(client, reg));
86}
87
88static inline int ad7418_write(struct i2c_client *client, u8 reg, u16 value)
89{
90 return i2c_smbus_write_word_data(client, reg, swab16(value));
91}
92
93static void ad7418_init_client(struct i2c_client *client) 79static void ad7418_init_client(struct i2c_client *client)
94{ 80{
95 struct ad7418_data *data = i2c_get_clientdata(client); 81 struct ad7418_data *data = i2c_get_clientdata(client);
@@ -128,7 +114,9 @@ static struct ad7418_data *ad7418_update_device(struct device *dev)
128 udelay(30); 114 udelay(30);
129 115
130 for (i = 0; i < 3; i++) { 116 for (i = 0; i < 3; i++) {
131 data->temp[i] = ad7418_read(client, AD7418_REG_TEMP[i]); 117 data->temp[i] =
118 i2c_smbus_read_word_swapped(client,
119 AD7418_REG_TEMP[i]);
132 } 120 }
133 121
134 for (i = 0, ch = 4; i < data->adc_max; i++, ch--) { 122 for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
@@ -138,11 +126,12 @@ static struct ad7418_data *ad7418_update_device(struct device *dev)
138 126
139 udelay(15); 127 udelay(15);
140 data->in[data->adc_max - 1 - i] = 128 data->in[data->adc_max - 1 - i] =
141 ad7418_read(client, AD7418_REG_ADC); 129 i2c_smbus_read_word_swapped(client,
130 AD7418_REG_ADC);
142 } 131 }
143 132
144 /* restore old configuration value */ 133 /* restore old configuration value */
145 ad7418_write(client, AD7418_REG_CONF, cfg); 134 i2c_smbus_write_word_swapped(client, AD7418_REG_CONF, cfg);
146 135
147 data->last_updated = jiffies; 136 data->last_updated = jiffies;
148 data->valid = 1; 137 data->valid = 1;
@@ -182,7 +171,9 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
182 171
183 mutex_lock(&data->lock); 172 mutex_lock(&data->lock);
184 data->temp[attr->index] = LM75_TEMP_TO_REG(temp); 173 data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
185 ad7418_write(client, AD7418_REG_TEMP[attr->index], data->temp[attr->index]); 174 i2c_smbus_write_word_swapped(client,
175 AD7418_REG_TEMP[attr->index],
176 data->temp[attr->index]);
186 mutex_unlock(&data->lock); 177 mutex_unlock(&data->lock);
187 return count; 178 return count;
188} 179}
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index e9beeda4cbe5..eedca3cf9968 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -59,19 +59,6 @@ struct ads1015_data {
59 struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; 59 struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
60}; 60};
61 61
62static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg)
63{
64 s32 data = i2c_smbus_read_word_data(client, reg);
65
66 return (data < 0) ? data : swab16(data);
67}
68
69static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg,
70 u16 val)
71{
72 return i2c_smbus_write_word_data(client, reg, swab16(val));
73}
74
75static int ads1015_read_value(struct i2c_client *client, unsigned int channel, 62static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
76 int *value) 63 int *value)
77{ 64{
@@ -87,7 +74,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
87 mutex_lock(&data->update_lock); 74 mutex_lock(&data->update_lock);
88 75
89 /* get channel parameters */ 76 /* get channel parameters */
90 res = ads1015_read_reg(client, ADS1015_CONFIG); 77 res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
91 if (res < 0) 78 if (res < 0)
92 goto err_unlock; 79 goto err_unlock;
93 config = res; 80 config = res;
@@ -101,13 +88,13 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
101 config |= (pga & 0x0007) << 9; 88 config |= (pga & 0x0007) << 9;
102 config |= (data_rate & 0x0007) << 5; 89 config |= (data_rate & 0x0007) << 5;
103 90
104 res = ads1015_write_reg(client, ADS1015_CONFIG, config); 91 res = i2c_smbus_write_word_swapped(client, ADS1015_CONFIG, config);
105 if (res < 0) 92 if (res < 0)
106 goto err_unlock; 93 goto err_unlock;
107 94
108 /* wait until conversion finished */ 95 /* wait until conversion finished */
109 msleep(conversion_time_ms); 96 msleep(conversion_time_ms);
110 res = ads1015_read_reg(client, ADS1015_CONFIG); 97 res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
111 if (res < 0) 98 if (res < 0)
112 goto err_unlock; 99 goto err_unlock;
113 config = res; 100 config = res;
@@ -117,7 +104,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
117 goto err_unlock; 104 goto err_unlock;
118 } 105 }
119 106
120 res = ads1015_read_reg(client, ADS1015_CONVERSION); 107 res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
121 if (res < 0) 108 if (res < 0)
122 goto err_unlock; 109 goto err_unlock;
123 conversion = res; 110 conversion = res;
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index c42c5a69a664..cfcc3b6fb6bf 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -74,13 +74,6 @@ static int ads7828_detect(struct i2c_client *client,
74static int ads7828_probe(struct i2c_client *client, 74static int ads7828_probe(struct i2c_client *client,
75 const struct i2c_device_id *id); 75 const struct i2c_device_id *id);
76 76
77/* The ADS7828 returns the 12-bit sample in two bytes,
78 these are read as a word then byte-swapped */
79static u16 ads7828_read_value(struct i2c_client *client, u8 reg)
80{
81 return swab16(i2c_smbus_read_word_data(client, reg));
82}
83
84static inline u8 channel_cmd_byte(int ch) 77static inline u8 channel_cmd_byte(int ch)
85{ 78{
86 /* cmd byte C2,C1,C0 - see datasheet */ 79 /* cmd byte C2,C1,C0 - see datasheet */
@@ -104,7 +97,8 @@ static struct ads7828_data *ads7828_update_device(struct device *dev)
104 97
105 for (ch = 0; ch < ADS7828_NCH; ch++) { 98 for (ch = 0; ch < ADS7828_NCH; ch++) {
106 u8 cmd = channel_cmd_byte(ch); 99 u8 cmd = channel_cmd_byte(ch);
107 data->adc_input[ch] = ads7828_read_value(client, cmd); 100 data->adc_input[ch] =
101 i2c_smbus_read_word_swapped(client, cmd);
108 } 102 }
109 data->last_updated = jiffies; 103 data->last_updated = jiffies;
110 data->valid = 1; 104 data->valid = 1;
@@ -203,7 +197,7 @@ static int ads7828_detect(struct i2c_client *client,
203 for (ch = 0; ch < ADS7828_NCH; ch++) { 197 for (ch = 0; ch < ADS7828_NCH; ch++) {
204 u16 in_data; 198 u16 in_data;
205 u8 cmd = channel_cmd_byte(ch); 199 u8 cmd = channel_cmd_byte(ch);
206 in_data = ads7828_read_value(client, cmd); 200 in_data = i2c_smbus_read_word_swapped(client, cmd);
207 if (in_data & 0xF000) { 201 if (in_data & 0xF000) {
208 pr_debug("%s : Doesn't look like an ads7828 device\n", 202 pr_debug("%s : Doesn't look like an ads7828 device\n",
209 __func__); 203 __func__);
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index c02a052d3085..d7bd1f3f2a31 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -829,17 +829,17 @@ static int asb100_read_value(struct i2c_client *client, u16 reg)
829 /* convert from ISA to LM75 I2C addresses */ 829 /* convert from ISA to LM75 I2C addresses */
830 switch (reg & 0xff) { 830 switch (reg & 0xff) {
831 case 0x50: /* TEMP */ 831 case 0x50: /* TEMP */
832 res = swab16(i2c_smbus_read_word_data(cl, 0)); 832 res = i2c_smbus_read_word_swapped(cl, 0);
833 break; 833 break;
834 case 0x52: /* CONFIG */ 834 case 0x52: /* CONFIG */
835 res = i2c_smbus_read_byte_data(cl, 1); 835 res = i2c_smbus_read_byte_data(cl, 1);
836 break; 836 break;
837 case 0x53: /* HYST */ 837 case 0x53: /* HYST */
838 res = swab16(i2c_smbus_read_word_data(cl, 2)); 838 res = i2c_smbus_read_word_swapped(cl, 2);
839 break; 839 break;
840 case 0x55: /* MAX */ 840 case 0x55: /* MAX */
841 default: 841 default:
842 res = swab16(i2c_smbus_read_word_data(cl, 3)); 842 res = i2c_smbus_read_word_swapped(cl, 3);
843 break; 843 break;
844 } 844 }
845 } 845 }
@@ -877,10 +877,10 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
877 i2c_smbus_write_byte_data(cl, 1, value & 0xff); 877 i2c_smbus_write_byte_data(cl, 1, value & 0xff);
878 break; 878 break;
879 case 0x53: /* HYST */ 879 case 0x53: /* HYST */
880 i2c_smbus_write_word_data(cl, 2, swab16(value)); 880 i2c_smbus_write_word_swapped(cl, 2, value);
881 break; 881 break;
882 case 0x55: /* MAX */ 882 case 0x55: /* MAX */
883 i2c_smbus_write_word_data(cl, 3, swab16(value)); 883 i2c_smbus_write_word_swapped(cl, 3, value);
884 break; 884 break;
885 } 885 }
886 } 886 }
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index ce18c046f728..104b3767516c 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -60,14 +60,13 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
60#ifdef CONFIG_SMP 60#ifdef CONFIG_SMP
61#define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id 61#define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id
62#define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id 62#define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id
63#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
64#define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu)) 63#define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu))
65#else 64#else
66#define TO_PHYS_ID(cpu) (cpu) 65#define TO_PHYS_ID(cpu) (cpu)
67#define TO_CORE_ID(cpu) (cpu) 66#define TO_CORE_ID(cpu) (cpu)
68#define TO_ATTR_NO(cpu) (cpu)
69#define for_each_sibling(i, cpu) for (i = 0; false; ) 67#define for_each_sibling(i, cpu) for (i = 0; false; )
70#endif 68#endif
69#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
71 70
72/* 71/*
73 * Per-Core Temperature Data 72 * Per-Core Temperature Data
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index e11363467a8d..ef1ac996752e 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -80,24 +80,6 @@ struct ds1621_data {
80 u8 conf; /* Register encoding, combined */ 80 u8 conf; /* Register encoding, combined */
81}; 81};
82 82
83/* Temperature registers are word-sized.
84 DS1621 uses a high-byte first convention, which is exactly opposite to
85 the SMBus standard. */
86static int ds1621_read_temp(struct i2c_client *client, u8 reg)
87{
88 int ret;
89
90 ret = i2c_smbus_read_word_data(client, reg);
91 if (ret < 0)
92 return ret;
93 return swab16(ret);
94}
95
96static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
97{
98 return i2c_smbus_write_word_data(client, reg, swab16(value));
99}
100
101static void ds1621_init_client(struct i2c_client *client) 83static void ds1621_init_client(struct i2c_client *client)
102{ 84{
103 u8 conf, new_conf; 85 u8 conf, new_conf;
@@ -136,7 +118,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
136 data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); 118 data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
137 119
138 for (i = 0; i < ARRAY_SIZE(data->temp); i++) 120 for (i = 0; i < ARRAY_SIZE(data->temp); i++)
139 data->temp[i] = ds1621_read_temp(client, 121 data->temp[i] = i2c_smbus_read_word_swapped(client,
140 DS1621_REG_TEMP[i]); 122 DS1621_REG_TEMP[i]);
141 123
142 /* reset alarms if necessary */ 124 /* reset alarms if necessary */
@@ -177,8 +159,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
177 159
178 mutex_lock(&data->update_lock); 160 mutex_lock(&data->update_lock);
179 data->temp[attr->index] = val; 161 data->temp[attr->index] = val;
180 ds1621_write_temp(client, DS1621_REG_TEMP[attr->index], 162 i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index],
181 data->temp[attr->index]); 163 data->temp[attr->index]);
182 mutex_unlock(&data->update_lock); 164 mutex_unlock(&data->update_lock);
183 return count; 165 return count;
184} 166}
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
index 4f7c3fc40a89..225ae4f36583 100644
--- a/drivers/hwmon/ds620.c
+++ b/drivers/hwmon/ds620.c
@@ -75,33 +75,13 @@ struct ds620_data {
75 s16 temp[3]; /* Register values, word */ 75 s16 temp[3]; /* Register values, word */
76}; 76};
77 77
78/*
79 * Temperature registers are word-sized.
80 * DS620 uses a high-byte first convention, which is exactly opposite to
81 * the SMBus standard.
82 */
83static int ds620_read_temp(struct i2c_client *client, u8 reg)
84{
85 int ret;
86
87 ret = i2c_smbus_read_word_data(client, reg);
88 if (ret < 0)
89 return ret;
90 return swab16(ret);
91}
92
93static int ds620_write_temp(struct i2c_client *client, u8 reg, u16 value)
94{
95 return i2c_smbus_write_word_data(client, reg, swab16(value));
96}
97
98static void ds620_init_client(struct i2c_client *client) 78static void ds620_init_client(struct i2c_client *client)
99{ 79{
100 struct ds620_platform_data *ds620_info = client->dev.platform_data; 80 struct ds620_platform_data *ds620_info = client->dev.platform_data;
101 u16 conf, new_conf; 81 u16 conf, new_conf;
102 82
103 new_conf = conf = 83 new_conf = conf =
104 swab16(i2c_smbus_read_word_data(client, DS620_REG_CONF)); 84 i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
105 85
106 /* switch to continuous conversion mode */ 86 /* switch to continuous conversion mode */
107 new_conf &= ~DS620_REG_CONFIG_1SHOT; 87 new_conf &= ~DS620_REG_CONFIG_1SHOT;
@@ -118,8 +98,7 @@ static void ds620_init_client(struct i2c_client *client)
118 new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; 98 new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0;
119 99
120 if (conf != new_conf) 100 if (conf != new_conf)
121 i2c_smbus_write_word_data(client, DS620_REG_CONF, 101 i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf);
122 swab16(new_conf));
123 102
124 /* start conversion */ 103 /* start conversion */
125 i2c_smbus_write_byte(client, DS620_COM_START); 104 i2c_smbus_write_byte(client, DS620_COM_START);
@@ -141,8 +120,8 @@ static struct ds620_data *ds620_update_client(struct device *dev)
141 dev_dbg(&client->dev, "Starting ds620 update\n"); 120 dev_dbg(&client->dev, "Starting ds620 update\n");
142 121
143 for (i = 0; i < ARRAY_SIZE(data->temp); i++) { 122 for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
144 res = ds620_read_temp(client, 123 res = i2c_smbus_read_word_swapped(client,
145 DS620_REG_TEMP[i]); 124 DS620_REG_TEMP[i]);
146 if (res < 0) { 125 if (res < 0) {
147 ret = ERR_PTR(res); 126 ret = ERR_PTR(res);
148 goto abort; 127 goto abort;
@@ -191,8 +170,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
191 170
192 mutex_lock(&data->update_lock); 171 mutex_lock(&data->update_lock);
193 data->temp[attr->index] = val; 172 data->temp[attr->index] = val;
194 ds620_write_temp(client, DS620_REG_TEMP[attr->index], 173 i2c_smbus_write_word_swapped(client, DS620_REG_TEMP[attr->index],
195 data->temp[attr->index]); 174 data->temp[attr->index]);
196 mutex_unlock(&data->update_lock); 175 mutex_unlock(&data->update_lock);
197 return count; 176 return count;
198} 177}
@@ -210,16 +189,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
210 return PTR_ERR(data); 189 return PTR_ERR(data);
211 190
212 /* reset alarms if necessary */ 191 /* reset alarms if necessary */
213 res = i2c_smbus_read_word_data(client, DS620_REG_CONF); 192 res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
214 if (res < 0) 193 if (res < 0)
215 return res; 194 return res;
216 195
217 conf = swab16(res); 196 new_conf = conf = res;
218 new_conf = conf;
219 new_conf &= ~attr->index; 197 new_conf &= ~attr->index;
220 if (conf != new_conf) { 198 if (conf != new_conf) {
221 res = i2c_smbus_write_word_data(client, DS620_REG_CONF, 199 res = i2c_smbus_write_word_swapped(client, DS620_REG_CONF,
222 swab16(new_conf)); 200 new_conf);
223 if (res < 0) 201 if (res < 0)
224 return res; 202 return res;
225 } 203 }
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index e7ae5743e181..a13e2da97e30 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -591,7 +591,7 @@ static int gl518_remove(struct i2c_client *client)
591static int gl518_read_value(struct i2c_client *client, u8 reg) 591static int gl518_read_value(struct i2c_client *client, u8 reg)
592{ 592{
593 if ((reg >= 0x07) && (reg <= 0x0c)) 593 if ((reg >= 0x07) && (reg <= 0x0c))
594 return swab16(i2c_smbus_read_word_data(client, reg)); 594 return i2c_smbus_read_word_swapped(client, reg);
595 else 595 else
596 return i2c_smbus_read_byte_data(client, reg); 596 return i2c_smbus_read_byte_data(client, reg);
597} 597}
@@ -599,7 +599,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg)
599static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) 599static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
600{ 600{
601 if ((reg >= 0x07) && (reg <= 0x0c)) 601 if ((reg >= 0x07) && (reg <= 0x0c))
602 return i2c_smbus_write_word_data(client, reg, swab16(value)); 602 return i2c_smbus_write_word_swapped(client, reg, value);
603 else 603 else
604 return i2c_smbus_write_byte_data(client, reg, value); 604 return i2c_smbus_write_byte_data(client, reg, value);
605} 605}
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index 131ea8625f08..cd6085bbfba7 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -821,7 +821,7 @@ static int gl520_remove(struct i2c_client *client)
821static int gl520_read_value(struct i2c_client *client, u8 reg) 821static int gl520_read_value(struct i2c_client *client, u8 reg)
822{ 822{
823 if ((reg >= 0x07) && (reg <= 0x0c)) 823 if ((reg >= 0x07) && (reg <= 0x0c))
824 return swab16(i2c_smbus_read_word_data(client, reg)); 824 return i2c_smbus_read_word_swapped(client, reg);
825 else 825 else
826 return i2c_smbus_read_byte_data(client, reg); 826 return i2c_smbus_read_byte_data(client, reg);
827} 827}
@@ -829,7 +829,7 @@ static int gl520_read_value(struct i2c_client *client, u8 reg)
829static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value) 829static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
830{ 830{
831 if ((reg >= 0x07) && (reg <= 0x0c)) 831 if ((reg >= 0x07) && (reg <= 0x0c))
832 return i2c_smbus_write_word_data(client, reg, swab16(value)); 832 return i2c_smbus_write_word_swapped(client, reg, value);
833 else 833 else
834 return i2c_smbus_write_byte_data(client, reg, value); 834 return i2c_smbus_write_byte_data(client, reg, value);
835} 835}
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 783d0c17b762..6a967d7dbdee 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -147,8 +147,9 @@ struct aem_data {
147 int id; 147 int id;
148 struct aem_ipmi_data ipmi; 148 struct aem_ipmi_data ipmi;
149 149
150 /* Function to update sensors */ 150 /* Function and buffer to update sensors */
151 void (*update)(struct aem_data *data); 151 void (*update)(struct aem_data *data);
152 struct aem_read_sensor_resp *rs_resp;
152 153
153 /* 154 /*
154 * AEM 1.x sensors: 155 * AEM 1.x sensors:
@@ -245,8 +246,6 @@ static void aem_bmc_gone(int iface);
245static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); 246static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
246 247
247static void aem_remove_sensors(struct aem_data *data); 248static void aem_remove_sensors(struct aem_data *data);
248static int aem_init_aem1(struct aem_ipmi_data *probe);
249static int aem_init_aem2(struct aem_ipmi_data *probe);
250static int aem1_find_sensors(struct aem_data *data); 249static int aem1_find_sensors(struct aem_data *data);
251static int aem2_find_sensors(struct aem_data *data); 250static int aem2_find_sensors(struct aem_data *data);
252static void update_aem1_sensors(struct aem_data *data); 251static void update_aem1_sensors(struct aem_data *data);
@@ -357,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
357 356
358/* Sensor support functions */ 357/* Sensor support functions */
359 358
360/* Read a sensor value */ 359/* Read a sensor value; must be called with data->lock held */
361static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, 360static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
362 void *buf, size_t size) 361 void *buf, size_t size)
363{ 362{
364 int rs_size, res; 363 int rs_size, res;
365 struct aem_read_sensor_req rs_req; 364 struct aem_read_sensor_req rs_req;
366 struct aem_read_sensor_resp *rs_resp; 365 /* Use preallocated rx buffer */
366 struct aem_read_sensor_resp *rs_resp = data->rs_resp;
367 struct aem_ipmi_data *ipmi = &data->ipmi; 367 struct aem_ipmi_data *ipmi = &data->ipmi;
368 368
369 /* AEM registers are 1, 2, 4 or 8 bytes */ 369 /* AEM registers are 1, 2, 4 or 8 bytes */
@@ -389,10 +389,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
389 ipmi->tx_message.data_len = sizeof(rs_req); 389 ipmi->tx_message.data_len = sizeof(rs_req);
390 390
391 rs_size = sizeof(*rs_resp) + size; 391 rs_size = sizeof(*rs_resp) + size;
392 rs_resp = kzalloc(rs_size, GFP_KERNEL);
393 if (!rs_resp)
394 return -ENOMEM;
395
396 ipmi->rx_msg_data = rs_resp; 392 ipmi->rx_msg_data = rs_resp;
397 ipmi->rx_msg_len = rs_size; 393 ipmi->rx_msg_len = rs_size;
398 394
@@ -435,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
435 res = 0; 431 res = 0;
436 432
437out: 433out:
438 kfree(rs_resp);
439 return res; 434 return res;
440} 435}
441 436
@@ -493,6 +488,7 @@ static void aem_delete(struct aem_data *data)
493{ 488{
494 list_del(&data->list); 489 list_del(&data->list);
495 aem_remove_sensors(data); 490 aem_remove_sensors(data);
491 kfree(data->rs_resp);
496 hwmon_device_unregister(data->hwmon_dev); 492 hwmon_device_unregister(data->hwmon_dev);
497 ipmi_destroy_user(data->ipmi.user); 493 ipmi_destroy_user(data->ipmi.user);
498 platform_set_drvdata(data->pdev, NULL); 494 platform_set_drvdata(data->pdev, NULL);
@@ -570,24 +566,31 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
570 platform_set_drvdata(data->pdev, data); 566 platform_set_drvdata(data->pdev, data);
571 567
572 /* Set up IPMI interface */ 568 /* Set up IPMI interface */
573 if (aem_init_ipmi_data(&data->ipmi, probe->interface, 569 res = aem_init_ipmi_data(&data->ipmi, probe->interface,
574 probe->bmc_device)) 570 probe->bmc_device);
571 if (res)
575 goto ipmi_err; 572 goto ipmi_err;
576 573
577 /* Register with hwmon */ 574 /* Register with hwmon */
578 data->hwmon_dev = hwmon_device_register(&data->pdev->dev); 575 data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
579
580 if (IS_ERR(data->hwmon_dev)) { 576 if (IS_ERR(data->hwmon_dev)) {
581 dev_err(&data->pdev->dev, "Unable to register hwmon " 577 dev_err(&data->pdev->dev, "Unable to register hwmon "
582 "device for IPMI interface %d\n", 578 "device for IPMI interface %d\n",
583 probe->interface); 579 probe->interface);
580 res = PTR_ERR(data->hwmon_dev);
584 goto hwmon_reg_err; 581 goto hwmon_reg_err;
585 } 582 }
586 583
587 data->update = update_aem1_sensors; 584 data->update = update_aem1_sensors;
585 data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
586 if (!data->rs_resp) {
587 res = -ENOMEM;
588 goto alloc_resp_err;
589 }
588 590
589 /* Find sensors */ 591 /* Find sensors */
590 if (aem1_find_sensors(data)) 592 res = aem1_find_sensors(data);
593 if (res)
591 goto sensor_err; 594 goto sensor_err;
592 595
593 /* Add to our list of AEM devices */ 596 /* Add to our list of AEM devices */
@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
599 return 0; 602 return 0;
600 603
601sensor_err: 604sensor_err:
605 kfree(data->rs_resp);
606alloc_resp_err:
602 hwmon_device_unregister(data->hwmon_dev); 607 hwmon_device_unregister(data->hwmon_dev);
603hwmon_reg_err: 608hwmon_reg_err:
604 ipmi_destroy_user(data->ipmi.user); 609 ipmi_destroy_user(data->ipmi.user);
@@ -614,7 +619,7 @@ id_err:
614} 619}
615 620
616/* Find and initialize all AEM1 instances */ 621/* Find and initialize all AEM1 instances */
617static int aem_init_aem1(struct aem_ipmi_data *probe) 622static void aem_init_aem1(struct aem_ipmi_data *probe)
618{ 623{
619 int num, i, err; 624 int num, i, err;
620 625
@@ -625,11 +630,8 @@ static int aem_init_aem1(struct aem_ipmi_data *probe)
625 dev_err(probe->bmc_device, 630 dev_err(probe->bmc_device,
626 "Error %d initializing AEM1 0x%X\n", 631 "Error %d initializing AEM1 0x%X\n",
627 err, i); 632 err, i);
628 return err;
629 } 633 }
630 } 634 }
631
632 return 0;
633} 635}
634 636
635/* Probe functions for AEM2 devices */ 637/* Probe functions for AEM2 devices */
@@ -704,24 +706,31 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
704 platform_set_drvdata(data->pdev, data); 706 platform_set_drvdata(data->pdev, data);
705 707
706 /* Set up IPMI interface */ 708 /* Set up IPMI interface */
707 if (aem_init_ipmi_data(&data->ipmi, probe->interface, 709 res = aem_init_ipmi_data(&data->ipmi, probe->interface,
708 probe->bmc_device)) 710 probe->bmc_device);
711 if (res)
709 goto ipmi_err; 712 goto ipmi_err;
710 713
711 /* Register with hwmon */ 714 /* Register with hwmon */
712 data->hwmon_dev = hwmon_device_register(&data->pdev->dev); 715 data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
713
714 if (IS_ERR(data->hwmon_dev)) { 716 if (IS_ERR(data->hwmon_dev)) {
715 dev_err(&data->pdev->dev, "Unable to register hwmon " 717 dev_err(&data->pdev->dev, "Unable to register hwmon "
716 "device for IPMI interface %d\n", 718 "device for IPMI interface %d\n",
717 probe->interface); 719 probe->interface);
720 res = PTR_ERR(data->hwmon_dev);
718 goto hwmon_reg_err; 721 goto hwmon_reg_err;
719 } 722 }
720 723
721 data->update = update_aem2_sensors; 724 data->update = update_aem2_sensors;
725 data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
726 if (!data->rs_resp) {
727 res = -ENOMEM;
728 goto alloc_resp_err;
729 }
722 730
723 /* Find sensors */ 731 /* Find sensors */
724 if (aem2_find_sensors(data)) 732 res = aem2_find_sensors(data);
733 if (res)
725 goto sensor_err; 734 goto sensor_err;
726 735
727 /* Add to our list of AEM devices */ 736 /* Add to our list of AEM devices */
@@ -733,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
733 return 0; 742 return 0;
734 743
735sensor_err: 744sensor_err:
745 kfree(data->rs_resp);
746alloc_resp_err:
736 hwmon_device_unregister(data->hwmon_dev); 747 hwmon_device_unregister(data->hwmon_dev);
737hwmon_reg_err: 748hwmon_reg_err:
738 ipmi_destroy_user(data->ipmi.user); 749 ipmi_destroy_user(data->ipmi.user);
@@ -748,7 +759,7 @@ id_err:
748} 759}
749 760
750/* Find and initialize all AEM2 instances */ 761/* Find and initialize all AEM2 instances */
751static int aem_init_aem2(struct aem_ipmi_data *probe) 762static void aem_init_aem2(struct aem_ipmi_data *probe)
752{ 763{
753 struct aem_find_instance_resp fi_resp; 764 struct aem_find_instance_resp fi_resp;
754 int err; 765 int err;
@@ -767,12 +778,9 @@ static int aem_init_aem2(struct aem_ipmi_data *probe)
767 dev_err(probe->bmc_device, 778 dev_err(probe->bmc_device,
768 "Error %d initializing AEM2 0x%X\n", 779 "Error %d initializing AEM2 0x%X\n",
769 err, fi_resp.module_handle); 780 err, fi_resp.module_handle);
770 return err;
771 } 781 }
772 i++; 782 i++;
773 } 783 }
774
775 return 0;
776} 784}
777 785
778/* Probe a BMC for AEM firmware instances */ 786/* Probe a BMC for AEM firmware instances */
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 02cebb74e206..2d3d72805ff4 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -154,8 +154,6 @@ static int jc42_probe(struct i2c_client *client,
154 const struct i2c_device_id *id); 154 const struct i2c_device_id *id);
155static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info); 155static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info);
156static int jc42_remove(struct i2c_client *client); 156static int jc42_remove(struct i2c_client *client);
157static int jc42_read_value(struct i2c_client *client, u8 reg);
158static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value);
159 157
160static struct jc42_data *jc42_update_device(struct device *dev); 158static struct jc42_data *jc42_update_device(struct device *dev);
161 159
@@ -187,7 +185,7 @@ static int jc42_suspend(struct device *dev)
187 struct jc42_data *data = i2c_get_clientdata(client); 185 struct jc42_data *data = i2c_get_clientdata(client);
188 186
189 data->config |= JC42_CFG_SHUTDOWN; 187 data->config |= JC42_CFG_SHUTDOWN;
190 jc42_write_value(client, JC42_REG_CONFIG, data->config); 188 i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
191 return 0; 189 return 0;
192} 190}
193 191
@@ -197,7 +195,7 @@ static int jc42_resume(struct device *dev)
197 struct jc42_data *data = i2c_get_clientdata(client); 195 struct jc42_data *data = i2c_get_clientdata(client);
198 196
199 data->config &= ~JC42_CFG_SHUTDOWN; 197 data->config &= ~JC42_CFG_SHUTDOWN;
200 jc42_write_value(client, JC42_REG_CONFIG, data->config); 198 i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
201 return 0; 199 return 0;
202} 200}
203 201
@@ -315,7 +313,7 @@ static ssize_t set_##value(struct device *dev, \
315 return -EINVAL; \ 313 return -EINVAL; \
316 mutex_lock(&data->update_lock); \ 314 mutex_lock(&data->update_lock); \
317 data->value = jc42_temp_to_reg(val, data->extended); \ 315 data->value = jc42_temp_to_reg(val, data->extended); \
318 err = jc42_write_value(client, reg, data->value); \ 316 err = i2c_smbus_write_word_swapped(client, reg, data->value); \
319 if (err < 0) \ 317 if (err < 0) \
320 ret = err; \ 318 ret = err; \
321 mutex_unlock(&data->update_lock); \ 319 mutex_unlock(&data->update_lock); \
@@ -357,7 +355,8 @@ static ssize_t set_temp_crit_hyst(struct device *dev,
357 data->config = (data->config 355 data->config = (data->config
358 & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT)) 356 & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT))
359 | (hyst << JC42_CFG_HYST_SHIFT); 357 | (hyst << JC42_CFG_HYST_SHIFT);
360 err = jc42_write_value(client, JC42_REG_CONFIG, data->config); 358 err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG,
359 data->config);
361 if (err < 0) 360 if (err < 0)
362 ret = err; 361 ret = err;
363 mutex_unlock(&data->update_lock); 362 mutex_unlock(&data->update_lock);
@@ -452,10 +451,10 @@ static int jc42_detect(struct i2c_client *new_client,
452 I2C_FUNC_SMBUS_WORD_DATA)) 451 I2C_FUNC_SMBUS_WORD_DATA))
453 return -ENODEV; 452 return -ENODEV;
454 453
455 cap = jc42_read_value(new_client, JC42_REG_CAP); 454 cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP);
456 config = jc42_read_value(new_client, JC42_REG_CONFIG); 455 config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG);
457 manid = jc42_read_value(new_client, JC42_REG_MANID); 456 manid = i2c_smbus_read_word_swapped(new_client, JC42_REG_MANID);
458 devid = jc42_read_value(new_client, JC42_REG_DEVICEID); 457 devid = i2c_smbus_read_word_swapped(new_client, JC42_REG_DEVICEID);
459 458
460 if (cap < 0 || config < 0 || manid < 0 || devid < 0) 459 if (cap < 0 || config < 0 || manid < 0 || devid < 0)
461 return -ENODEV; 460 return -ENODEV;
@@ -489,14 +488,14 @@ static int jc42_probe(struct i2c_client *new_client,
489 i2c_set_clientdata(new_client, data); 488 i2c_set_clientdata(new_client, data);
490 mutex_init(&data->update_lock); 489 mutex_init(&data->update_lock);
491 490
492 cap = jc42_read_value(new_client, JC42_REG_CAP); 491 cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP);
493 if (cap < 0) { 492 if (cap < 0) {
494 err = -EINVAL; 493 err = -EINVAL;
495 goto exit_free; 494 goto exit_free;
496 } 495 }
497 data->extended = !!(cap & JC42_CAP_RANGE); 496 data->extended = !!(cap & JC42_CAP_RANGE);
498 497
499 config = jc42_read_value(new_client, JC42_REG_CONFIG); 498 config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG);
500 if (config < 0) { 499 if (config < 0) {
501 err = -EINVAL; 500 err = -EINVAL;
502 goto exit_free; 501 goto exit_free;
@@ -504,7 +503,8 @@ static int jc42_probe(struct i2c_client *new_client,
504 data->orig_config = config; 503 data->orig_config = config;
505 if (config & JC42_CFG_SHUTDOWN) { 504 if (config & JC42_CFG_SHUTDOWN) {
506 config &= ~JC42_CFG_SHUTDOWN; 505 config &= ~JC42_CFG_SHUTDOWN;
507 jc42_write_value(new_client, JC42_REG_CONFIG, config); 506 i2c_smbus_write_word_swapped(new_client, JC42_REG_CONFIG,
507 config);
508 } 508 }
509 data->config = config; 509 data->config = config;
510 510
@@ -535,25 +535,12 @@ static int jc42_remove(struct i2c_client *client)
535 hwmon_device_unregister(data->hwmon_dev); 535 hwmon_device_unregister(data->hwmon_dev);
536 sysfs_remove_group(&client->dev.kobj, &jc42_group); 536 sysfs_remove_group(&client->dev.kobj, &jc42_group);
537 if (data->config != data->orig_config) 537 if (data->config != data->orig_config)
538 jc42_write_value(client, JC42_REG_CONFIG, data->orig_config); 538 i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG,
539 data->orig_config);
539 kfree(data); 540 kfree(data);
540 return 0; 541 return 0;
541} 542}
542 543
543/* All registers are word-sized. */
544static int jc42_read_value(struct i2c_client *client, u8 reg)
545{
546 int ret = i2c_smbus_read_word_data(client, reg);
547 if (ret < 0)
548 return ret;
549 return swab16(ret);
550}
551
552static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value)
553{
554 return i2c_smbus_write_word_data(client, reg, swab16(value));
555}
556
557static struct jc42_data *jc42_update_device(struct device *dev) 544static struct jc42_data *jc42_update_device(struct device *dev)
558{ 545{
559 struct i2c_client *client = to_i2c_client(dev); 546 struct i2c_client *client = to_i2c_client(dev);
@@ -564,28 +551,29 @@ static struct jc42_data *jc42_update_device(struct device *dev)
564 mutex_lock(&data->update_lock); 551 mutex_lock(&data->update_lock);
565 552
566 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 553 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
567 val = jc42_read_value(client, JC42_REG_TEMP); 554 val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP);
568 if (val < 0) { 555 if (val < 0) {
569 ret = ERR_PTR(val); 556 ret = ERR_PTR(val);
570 goto abort; 557 goto abort;
571 } 558 }
572 data->temp_input = val; 559 data->temp_input = val;
573 560
574 val = jc42_read_value(client, JC42_REG_TEMP_CRITICAL); 561 val = i2c_smbus_read_word_swapped(client,
562 JC42_REG_TEMP_CRITICAL);
575 if (val < 0) { 563 if (val < 0) {
576 ret = ERR_PTR(val); 564 ret = ERR_PTR(val);
577 goto abort; 565 goto abort;
578 } 566 }
579 data->temp_crit = val; 567 data->temp_crit = val;
580 568
581 val = jc42_read_value(client, JC42_REG_TEMP_LOWER); 569 val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_LOWER);
582 if (val < 0) { 570 if (val < 0) {
583 ret = ERR_PTR(val); 571 ret = ERR_PTR(val);
584 goto abort; 572 goto abort;
585 } 573 }
586 data->temp_min = val; 574 data->temp_min = val;
587 575
588 val = jc42_read_value(client, JC42_REG_TEMP_UPPER); 576 val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_UPPER);
589 if (val < 0) { 577 if (val < 0) {
590 ret = ERR_PTR(val); 578 ret = ERR_PTR(val);
591 goto abort; 579 goto abort;
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index 29b9030d42c3..9e64d96620d3 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -34,7 +34,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
34#define LM73_REG_CTRL 0x04 34#define LM73_REG_CTRL 0x04
35#define LM73_REG_ID 0x07 35#define LM73_REG_ID 0x07
36 36
37#define LM73_ID 0x9001 /* or 0x190 after a swab16() */ 37#define LM73_ID 0x9001 /* 0x0190, byte-swapped */
38#define DRVNAME "lm73" 38#define DRVNAME "lm73"
39#define LM73_TEMP_MIN (-40) 39#define LM73_TEMP_MIN (-40)
40#define LM73_TEMP_MAX 150 40#define LM73_TEMP_MAX 150
@@ -57,7 +57,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
57 /* Write value */ 57 /* Write value */
58 value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4), 58 value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
59 (LM73_TEMP_MAX*4)) << 5; 59 (LM73_TEMP_MAX*4)) << 5;
60 i2c_smbus_write_word_data(client, attr->index, swab16(value)); 60 i2c_smbus_write_word_swapped(client, attr->index, value);
61 return count; 61 return count;
62} 62}
63 63
@@ -68,8 +68,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da,
68 struct i2c_client *client = to_i2c_client(dev); 68 struct i2c_client *client = to_i2c_client(dev);
69 /* use integer division instead of equivalent right shift to 69 /* use integer division instead of equivalent right shift to
70 guarantee arithmetic shift and preserve the sign */ 70 guarantee arithmetic shift and preserve the sign */
71 int temp = ((s16) (swab16(i2c_smbus_read_word_data(client, 71 int temp = ((s16) (i2c_smbus_read_word_swapped(client,
72 attr->index)))*250) / 32; 72 attr->index))*250) / 32;
73 return sprintf(buf, "%d\n", temp); 73 return sprintf(buf, "%d\n", temp);
74} 74}
75 75
@@ -150,17 +150,31 @@ static int lm73_detect(struct i2c_client *new_client,
150 struct i2c_board_info *info) 150 struct i2c_board_info *info)
151{ 151{
152 struct i2c_adapter *adapter = new_client->adapter; 152 struct i2c_adapter *adapter = new_client->adapter;
153 u16 id; 153 int id, ctrl, conf;
154 u8 ctrl;
155 154
156 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
157 I2C_FUNC_SMBUS_WORD_DATA)) 156 I2C_FUNC_SMBUS_WORD_DATA))
158 return -ENODEV; 157 return -ENODEV;
159 158
159 /*
160 * Do as much detection as possible with byte reads first, as word
161 * reads can confuse other devices.
162 */
163 ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
164 if (ctrl < 0 || (ctrl & 0x10))
165 return -ENODEV;
166
167 conf = i2c_smbus_read_byte_data(new_client, LM73_REG_CONF);
168 if (conf < 0 || (conf & 0x0c))
169 return -ENODEV;
170
171 id = i2c_smbus_read_byte_data(new_client, LM73_REG_ID);
172 if (id < 0 || id != (LM73_ID & 0xff))
173 return -ENODEV;
174
160 /* Check device ID */ 175 /* Check device ID */
161 id = i2c_smbus_read_word_data(new_client, LM73_REG_ID); 176 id = i2c_smbus_read_word_data(new_client, LM73_REG_ID);
162 ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL); 177 if (id < 0 || id != LM73_ID)
163 if ((id != LM73_ID) || (ctrl & 0x10))
164 return -ENODEV; 178 return -ENODEV;
165 179
166 strlcpy(info->type, "lm73", I2C_NAME_SIZE); 180 strlcpy(info->type, "lm73", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 90126a2a1e44..1888dd0fc05f 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -384,13 +384,10 @@ static struct i2c_driver lm75_driver = {
384 */ 384 */
385static int lm75_read_value(struct i2c_client *client, u8 reg) 385static int lm75_read_value(struct i2c_client *client, u8 reg)
386{ 386{
387 int value;
388
389 if (reg == LM75_REG_CONF) 387 if (reg == LM75_REG_CONF)
390 return i2c_smbus_read_byte_data(client, reg); 388 return i2c_smbus_read_byte_data(client, reg);
391 389 else
392 value = i2c_smbus_read_word_data(client, reg); 390 return i2c_smbus_read_word_swapped(client, reg);
393 return (value < 0) ? value : swab16(value);
394} 391}
395 392
396static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) 393static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
@@ -398,7 +395,7 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
398 if (reg == LM75_REG_CONF) 395 if (reg == LM75_REG_CONF)
399 return i2c_smbus_write_byte_data(client, reg, value); 396 return i2c_smbus_write_byte_data(client, reg, value);
400 else 397 else
401 return i2c_smbus_write_word_data(client, reg, swab16(value)); 398 return i2c_smbus_write_word_swapped(client, reg, value);
402} 399}
403 400
404static struct lm75_data *lm75_update_device(struct device *dev) 401static struct lm75_data *lm75_update_device(struct device *dev)
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index b28a297be50c..8dfc6782d596 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -365,7 +365,7 @@ static u16 lm77_read_value(struct i2c_client *client, u8 reg)
365 if (reg == LM77_REG_CONF) 365 if (reg == LM77_REG_CONF)
366 return i2c_smbus_read_byte_data(client, reg); 366 return i2c_smbus_read_byte_data(client, reg);
367 else 367 else
368 return swab16(i2c_smbus_read_word_data(client, reg)); 368 return i2c_smbus_read_word_swapped(client, reg);
369} 369}
370 370
371static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) 371static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
@@ -373,7 +373,7 @@ static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
373 if (reg == LM77_REG_CONF) 373 if (reg == LM77_REG_CONF)
374 return i2c_smbus_write_byte_data(client, reg, value); 374 return i2c_smbus_write_byte_data(client, reg, value);
375 else 375 else
376 return i2c_smbus_write_word_data(client, reg, swab16(value)); 376 return i2c_smbus_write_word_swapped(client, reg, value);
377} 377}
378 378
379static void lm77_init_client(struct i2c_client *client) 379static void lm77_init_client(struct i2c_client *client)
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 90ddb8774210..615bc4f4e530 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1105,41 +1105,37 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
1105 */ 1105 */
1106 1106
1107/* Return 0 if detection is successful, -ENODEV otherwise */ 1107/* Return 0 if detection is successful, -ENODEV otherwise */
1108static int lm90_detect(struct i2c_client *new_client, 1108static int lm90_detect(struct i2c_client *client,
1109 struct i2c_board_info *info) 1109 struct i2c_board_info *info)
1110{ 1110{
1111 struct i2c_adapter *adapter = new_client->adapter; 1111 struct i2c_adapter *adapter = client->adapter;
1112 int address = new_client->addr; 1112 int address = client->addr;
1113 const char *name = NULL; 1113 const char *name = NULL;
1114 int man_id, chip_id, reg_config1, reg_config2, reg_convrate; 1114 int man_id, chip_id, config1, config2, convrate;
1115 1115
1116 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1116 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1117 return -ENODEV; 1117 return -ENODEV;
1118 1118
1119 /* detection and identification */ 1119 /* detection and identification */
1120 if ((man_id = i2c_smbus_read_byte_data(new_client, 1120 man_id = i2c_smbus_read_byte_data(client, LM90_REG_R_MAN_ID);
1121 LM90_REG_R_MAN_ID)) < 0 1121 chip_id = i2c_smbus_read_byte_data(client, LM90_REG_R_CHIP_ID);
1122 || (chip_id = i2c_smbus_read_byte_data(new_client, 1122 config1 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
1123 LM90_REG_R_CHIP_ID)) < 0 1123 convrate = i2c_smbus_read_byte_data(client, LM90_REG_R_CONVRATE);
1124 || (reg_config1 = i2c_smbus_read_byte_data(new_client, 1124 if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
1125 LM90_REG_R_CONFIG1)) < 0
1126 || (reg_convrate = i2c_smbus_read_byte_data(new_client,
1127 LM90_REG_R_CONVRATE)) < 0)
1128 return -ENODEV; 1125 return -ENODEV;
1129 1126
1130 if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) { 1127 if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
1131 reg_config2 = i2c_smbus_read_byte_data(new_client, 1128 config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
1132 LM90_REG_R_CONFIG2); 1129 if (config2 < 0)
1133 if (reg_config2 < 0)
1134 return -ENODEV; 1130 return -ENODEV;
1135 } else 1131 } else
1136 reg_config2 = 0; /* Make compiler happy */ 1132 config2 = 0; /* Make compiler happy */
1137 1133
1138 if ((address == 0x4C || address == 0x4D) 1134 if ((address == 0x4C || address == 0x4D)
1139 && man_id == 0x01) { /* National Semiconductor */ 1135 && man_id == 0x01) { /* National Semiconductor */
1140 if ((reg_config1 & 0x2A) == 0x00 1136 if ((config1 & 0x2A) == 0x00
1141 && (reg_config2 & 0xF8) == 0x00 1137 && (config2 & 0xF8) == 0x00
1142 && reg_convrate <= 0x09) { 1138 && convrate <= 0x09) {
1143 if (address == 0x4C 1139 if (address == 0x4C
1144 && (chip_id & 0xF0) == 0x20) { /* LM90 */ 1140 && (chip_id & 0xF0) == 0x20) { /* LM90 */
1145 name = "lm90"; 1141 name = "lm90";
@@ -1163,8 +1159,8 @@ static int lm90_detect(struct i2c_client *new_client,
1163 if ((address == 0x4C || address == 0x4D) 1159 if ((address == 0x4C || address == 0x4D)
1164 && man_id == 0x41) { /* Analog Devices */ 1160 && man_id == 0x41) { /* Analog Devices */
1165 if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ 1161 if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
1166 && (reg_config1 & 0x3F) == 0x00 1162 && (config1 & 0x3F) == 0x00
1167 && reg_convrate <= 0x0A) { 1163 && convrate <= 0x0A) {
1168 name = "adm1032"; 1164 name = "adm1032";
1169 /* The ADM1032 supports PEC, but only if combined 1165 /* The ADM1032 supports PEC, but only if combined
1170 transactions are not used. */ 1166 transactions are not used. */
@@ -1173,18 +1169,18 @@ static int lm90_detect(struct i2c_client *new_client,
1173 info->flags |= I2C_CLIENT_PEC; 1169 info->flags |= I2C_CLIENT_PEC;
1174 } else 1170 } else
1175 if (chip_id == 0x51 /* ADT7461 */ 1171 if (chip_id == 0x51 /* ADT7461 */
1176 && (reg_config1 & 0x1B) == 0x00 1172 && (config1 & 0x1B) == 0x00
1177 && reg_convrate <= 0x0A) { 1173 && convrate <= 0x0A) {
1178 name = "adt7461"; 1174 name = "adt7461";
1179 } else 1175 } else
1180 if (chip_id == 0x57 /* ADT7461A, NCT1008 */ 1176 if (chip_id == 0x57 /* ADT7461A, NCT1008 */
1181 && (reg_config1 & 0x1B) == 0x00 1177 && (config1 & 0x1B) == 0x00
1182 && reg_convrate <= 0x0A) { 1178 && convrate <= 0x0A) {
1183 name = "adt7461a"; 1179 name = "adt7461a";
1184 } 1180 }
1185 } else 1181 } else
1186 if (man_id == 0x4D) { /* Maxim */ 1182 if (man_id == 0x4D) { /* Maxim */
1187 int reg_emerg, reg_emerg2, reg_status2; 1183 int emerg, emerg2, status2;
1188 1184
1189 /* 1185 /*
1190 * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read 1186 * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read
@@ -1192,13 +1188,15 @@ static int lm90_detect(struct i2c_client *new_client,
1192 * exists, both readings will reflect the same value. Otherwise, 1188 * exists, both readings will reflect the same value. Otherwise,
1193 * the readings will be different. 1189 * the readings will be different.
1194 */ 1190 */
1195 if ((reg_emerg = i2c_smbus_read_byte_data(new_client, 1191 emerg = i2c_smbus_read_byte_data(client,
1196 MAX6659_REG_R_REMOTE_EMERG)) < 0 1192 MAX6659_REG_R_REMOTE_EMERG);
1197 || i2c_smbus_read_byte_data(new_client, LM90_REG_R_MAN_ID) < 0 1193 man_id = i2c_smbus_read_byte_data(client,
1198 || (reg_emerg2 = i2c_smbus_read_byte_data(new_client, 1194 LM90_REG_R_MAN_ID);
1199 MAX6659_REG_R_REMOTE_EMERG)) < 0 1195 emerg2 = i2c_smbus_read_byte_data(client,
1200 || (reg_status2 = i2c_smbus_read_byte_data(new_client, 1196 MAX6659_REG_R_REMOTE_EMERG);
1201 MAX6696_REG_R_STATUS2)) < 0) 1197 status2 = i2c_smbus_read_byte_data(client,
1198 MAX6696_REG_R_STATUS2);
1199 if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0)
1202 return -ENODEV; 1200 return -ENODEV;
1203 1201
1204 /* 1202 /*
@@ -1216,8 +1214,8 @@ static int lm90_detect(struct i2c_client *new_client,
1216 */ 1214 */
1217 if (chip_id == man_id 1215 if (chip_id == man_id
1218 && (address == 0x4C || address == 0x4D || address == 0x4E) 1216 && (address == 0x4C || address == 0x4D || address == 0x4E)
1219 && (reg_config1 & 0x1F) == (man_id & 0x0F) 1217 && (config1 & 0x1F) == (man_id & 0x0F)
1220 && reg_convrate <= 0x09) { 1218 && convrate <= 0x09) {
1221 if (address == 0x4C) 1219 if (address == 0x4C)
1222 name = "max6657"; 1220 name = "max6657";
1223 else 1221 else
@@ -1235,10 +1233,10 @@ static int lm90_detect(struct i2c_client *new_client,
1235 * one of those registers exists. 1233 * one of those registers exists.
1236 */ 1234 */
1237 if (chip_id == 0x01 1235 if (chip_id == 0x01
1238 && (reg_config1 & 0x10) == 0x00 1236 && (config1 & 0x10) == 0x00
1239 && (reg_status2 & 0x01) == 0x00 1237 && (status2 & 0x01) == 0x00
1240 && reg_emerg == reg_emerg2 1238 && emerg == emerg2
1241 && reg_convrate <= 0x07) { 1239 && convrate <= 0x07) {
1242 name = "max6696"; 1240 name = "max6696";
1243 } else 1241 } else
1244 /* 1242 /*
@@ -1248,8 +1246,8 @@ static int lm90_detect(struct i2c_client *new_client,
1248 * second to last bit of config1 (software reset). 1246 * second to last bit of config1 (software reset).
1249 */ 1247 */
1250 if (chip_id == 0x01 1248 if (chip_id == 0x01
1251 && (reg_config1 & 0x03) == 0x00 1249 && (config1 & 0x03) == 0x00
1252 && reg_convrate <= 0x07) { 1250 && convrate <= 0x07) {
1253 name = "max6680"; 1251 name = "max6680";
1254 } else 1252 } else
1255 /* 1253 /*
@@ -1258,21 +1256,21 @@ static int lm90_detect(struct i2c_client *new_client,
1258 * register are unused and should return zero when read. 1256 * register are unused and should return zero when read.
1259 */ 1257 */
1260 if (chip_id == 0x59 1258 if (chip_id == 0x59
1261 && (reg_config1 & 0x3f) == 0x00 1259 && (config1 & 0x3f) == 0x00
1262 && reg_convrate <= 0x07) { 1260 && convrate <= 0x07) {
1263 name = "max6646"; 1261 name = "max6646";
1264 } 1262 }
1265 } else 1263 } else
1266 if (address == 0x4C 1264 if (address == 0x4C
1267 && man_id == 0x5C) { /* Winbond/Nuvoton */ 1265 && man_id == 0x5C) { /* Winbond/Nuvoton */
1268 if ((reg_config1 & 0x2A) == 0x00 1266 if ((config1 & 0x2A) == 0x00
1269 && (reg_config2 & 0xF8) == 0x00) { 1267 && (config2 & 0xF8) == 0x00) {
1270 if (chip_id == 0x01 /* W83L771W/G */ 1268 if (chip_id == 0x01 /* W83L771W/G */
1271 && reg_convrate <= 0x09) { 1269 && convrate <= 0x09) {
1272 name = "w83l771"; 1270 name = "w83l771";
1273 } else 1271 } else
1274 if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */ 1272 if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
1275 && reg_convrate <= 0x08) { 1273 && convrate <= 0x08) {
1276 name = "w83l771"; 1274 name = "w83l771";
1277 } 1275 }
1278 } 1276 }
@@ -1280,9 +1278,9 @@ static int lm90_detect(struct i2c_client *new_client,
1280 if (address >= 0x48 && address <= 0x4F 1278 if (address >= 0x48 && address <= 0x4F
1281 && man_id == 0xA1) { /* NXP Semiconductor/Philips */ 1279 && man_id == 0xA1) { /* NXP Semiconductor/Philips */
1282 if (chip_id == 0x00 1280 if (chip_id == 0x00
1283 && (reg_config1 & 0x2A) == 0x00 1281 && (config1 & 0x2A) == 0x00
1284 && (reg_config2 & 0xFE) == 0x00 1282 && (config2 & 0xFE) == 0x00
1285 && reg_convrate <= 0x09) { 1283 && convrate <= 0x09) {
1286 name = "sa56004"; 1284 name = "sa56004";
1287 } 1285 }
1288 } 1286 }
@@ -1301,19 +1299,18 @@ static int lm90_detect(struct i2c_client *new_client,
1301 1299
1302static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) 1300static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
1303{ 1301{
1302 struct device *dev = &client->dev;
1303
1304 if (data->flags & LM90_HAVE_TEMP3) 1304 if (data->flags & LM90_HAVE_TEMP3)
1305 sysfs_remove_group(&client->dev.kobj, &lm90_temp3_group); 1305 sysfs_remove_group(&dev->kobj, &lm90_temp3_group);
1306 if (data->flags & LM90_HAVE_EMERGENCY_ALARM) 1306 if (data->flags & LM90_HAVE_EMERGENCY_ALARM)
1307 sysfs_remove_group(&client->dev.kobj, 1307 sysfs_remove_group(&dev->kobj, &lm90_emergency_alarm_group);
1308 &lm90_emergency_alarm_group);
1309 if (data->flags & LM90_HAVE_EMERGENCY) 1308 if (data->flags & LM90_HAVE_EMERGENCY)
1310 sysfs_remove_group(&client->dev.kobj, 1309 sysfs_remove_group(&dev->kobj, &lm90_emergency_group);
1311 &lm90_emergency_group);
1312 if (data->flags & LM90_HAVE_OFFSET) 1310 if (data->flags & LM90_HAVE_OFFSET)
1313 device_remove_file(&client->dev, 1311 device_remove_file(dev, &sensor_dev_attr_temp2_offset.dev_attr);
1314 &sensor_dev_attr_temp2_offset.dev_attr); 1312 device_remove_file(dev, &dev_attr_pec);
1315 device_remove_file(&client->dev, &dev_attr_pec); 1313 sysfs_remove_group(&dev->kobj, &lm90_group);
1316 sysfs_remove_group(&client->dev.kobj, &lm90_group);
1317} 1314}
1318 1315
1319static void lm90_init_client(struct i2c_client *client) 1316static void lm90_init_client(struct i2c_client *client)
@@ -1362,10 +1359,11 @@ static void lm90_init_client(struct i2c_client *client)
1362 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); 1359 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
1363} 1360}
1364 1361
1365static int lm90_probe(struct i2c_client *new_client, 1362static int lm90_probe(struct i2c_client *client,
1366 const struct i2c_device_id *id) 1363 const struct i2c_device_id *id)
1367{ 1364{
1368 struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent); 1365 struct device *dev = &client->dev;
1366 struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
1369 struct lm90_data *data; 1367 struct lm90_data *data;
1370 int err; 1368 int err;
1371 1369
@@ -1374,14 +1372,14 @@ static int lm90_probe(struct i2c_client *new_client,
1374 err = -ENOMEM; 1372 err = -ENOMEM;
1375 goto exit; 1373 goto exit;
1376 } 1374 }
1377 i2c_set_clientdata(new_client, data); 1375 i2c_set_clientdata(client, data);
1378 mutex_init(&data->update_lock); 1376 mutex_init(&data->update_lock);
1379 1377
1380 /* Set the device type */ 1378 /* Set the device type */
1381 data->kind = id->driver_data; 1379 data->kind = id->driver_data;
1382 if (data->kind == adm1032) { 1380 if (data->kind == adm1032) {
1383 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 1381 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
1384 new_client->flags &= ~I2C_CLIENT_PEC; 1382 client->flags &= ~I2C_CLIENT_PEC;
1385 } 1383 }
1386 1384
1387 /* Different devices have different alarm bits triggering the 1385 /* Different devices have different alarm bits triggering the
@@ -1396,43 +1394,41 @@ static int lm90_probe(struct i2c_client *new_client,
1396 data->max_convrate = lm90_params[data->kind].max_convrate; 1394 data->max_convrate = lm90_params[data->kind].max_convrate;
1397 1395
1398 /* Initialize the LM90 chip */ 1396 /* Initialize the LM90 chip */
1399 lm90_init_client(new_client); 1397 lm90_init_client(client);
1400 1398
1401 /* Register sysfs hooks */ 1399 /* Register sysfs hooks */
1402 err = sysfs_create_group(&new_client->dev.kobj, &lm90_group); 1400 err = sysfs_create_group(&dev->kobj, &lm90_group);
1403 if (err) 1401 if (err)
1404 goto exit_free; 1402 goto exit_free;
1405 if (new_client->flags & I2C_CLIENT_PEC) { 1403 if (client->flags & I2C_CLIENT_PEC) {
1406 err = device_create_file(&new_client->dev, &dev_attr_pec); 1404 err = device_create_file(dev, &dev_attr_pec);
1407 if (err) 1405 if (err)
1408 goto exit_remove_files; 1406 goto exit_remove_files;
1409 } 1407 }
1410 if (data->flags & LM90_HAVE_OFFSET) { 1408 if (data->flags & LM90_HAVE_OFFSET) {
1411 err = device_create_file(&new_client->dev, 1409 err = device_create_file(dev,
1412 &sensor_dev_attr_temp2_offset.dev_attr); 1410 &sensor_dev_attr_temp2_offset.dev_attr);
1413 if (err) 1411 if (err)
1414 goto exit_remove_files; 1412 goto exit_remove_files;
1415 } 1413 }
1416 if (data->flags & LM90_HAVE_EMERGENCY) { 1414 if (data->flags & LM90_HAVE_EMERGENCY) {
1417 err = sysfs_create_group(&new_client->dev.kobj, 1415 err = sysfs_create_group(&dev->kobj, &lm90_emergency_group);
1418 &lm90_emergency_group);
1419 if (err) 1416 if (err)
1420 goto exit_remove_files; 1417 goto exit_remove_files;
1421 } 1418 }
1422 if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { 1419 if (data->flags & LM90_HAVE_EMERGENCY_ALARM) {
1423 err = sysfs_create_group(&new_client->dev.kobj, 1420 err = sysfs_create_group(&dev->kobj,
1424 &lm90_emergency_alarm_group); 1421 &lm90_emergency_alarm_group);
1425 if (err) 1422 if (err)
1426 goto exit_remove_files; 1423 goto exit_remove_files;
1427 } 1424 }
1428 if (data->flags & LM90_HAVE_TEMP3) { 1425 if (data->flags & LM90_HAVE_TEMP3) {
1429 err = sysfs_create_group(&new_client->dev.kobj, 1426 err = sysfs_create_group(&dev->kobj, &lm90_temp3_group);
1430 &lm90_temp3_group);
1431 if (err) 1427 if (err)
1432 goto exit_remove_files; 1428 goto exit_remove_files;
1433 } 1429 }
1434 1430
1435 data->hwmon_dev = hwmon_device_register(&new_client->dev); 1431 data->hwmon_dev = hwmon_device_register(dev);
1436 if (IS_ERR(data->hwmon_dev)) { 1432 if (IS_ERR(data->hwmon_dev)) {
1437 err = PTR_ERR(data->hwmon_dev); 1433 err = PTR_ERR(data->hwmon_dev);
1438 goto exit_remove_files; 1434 goto exit_remove_files;
@@ -1441,7 +1437,7 @@ static int lm90_probe(struct i2c_client *new_client,
1441 return 0; 1437 return 0;
1442 1438
1443exit_remove_files: 1439exit_remove_files:
1444 lm90_remove_files(new_client, data); 1440 lm90_remove_files(client, data);
1445exit_free: 1441exit_free:
1446 kfree(data); 1442 kfree(data);
1447exit: 1443exit:
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 7c31e6205f85..8fcbd4d422c5 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -117,16 +117,16 @@ static struct lm92_data *lm92_update_device(struct device *dev)
117 if (time_after(jiffies, data->last_updated + HZ) 117 if (time_after(jiffies, data->last_updated + HZ)
118 || !data->valid) { 118 || !data->valid) {
119 dev_dbg(&client->dev, "Updating lm92 data\n"); 119 dev_dbg(&client->dev, "Updating lm92 data\n");
120 data->temp1_input = swab16(i2c_smbus_read_word_data(client, 120 data->temp1_input = i2c_smbus_read_word_swapped(client,
121 LM92_REG_TEMP)); 121 LM92_REG_TEMP);
122 data->temp1_hyst = swab16(i2c_smbus_read_word_data(client, 122 data->temp1_hyst = i2c_smbus_read_word_swapped(client,
123 LM92_REG_TEMP_HYST)); 123 LM92_REG_TEMP_HYST);
124 data->temp1_crit = swab16(i2c_smbus_read_word_data(client, 124 data->temp1_crit = i2c_smbus_read_word_swapped(client,
125 LM92_REG_TEMP_CRIT)); 125 LM92_REG_TEMP_CRIT);
126 data->temp1_min = swab16(i2c_smbus_read_word_data(client, 126 data->temp1_min = i2c_smbus_read_word_swapped(client,
127 LM92_REG_TEMP_LOW)); 127 LM92_REG_TEMP_LOW);
128 data->temp1_max = swab16(i2c_smbus_read_word_data(client, 128 data->temp1_max = i2c_smbus_read_word_swapped(client,
129 LM92_REG_TEMP_HIGH)); 129 LM92_REG_TEMP_HIGH);
130 130
131 data->last_updated = jiffies; 131 data->last_updated = jiffies;
132 data->valid = 1; 132 data->valid = 1;
@@ -158,7 +158,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
158 \ 158 \
159 mutex_lock(&data->update_lock); \ 159 mutex_lock(&data->update_lock); \
160 data->value = TEMP_TO_REG(val); \ 160 data->value = TEMP_TO_REG(val); \
161 i2c_smbus_write_word_data(client, reg, swab16(data->value)); \ 161 i2c_smbus_write_word_swapped(client, reg, data->value); \
162 mutex_unlock(&data->update_lock); \ 162 mutex_unlock(&data->update_lock); \
163 return count; \ 163 return count; \
164} 164}
@@ -194,8 +194,8 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *
194 194
195 mutex_lock(&data->update_lock); 195 mutex_lock(&data->update_lock);
196 data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; 196 data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
197 i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST, 197 i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST,
198 swab16(TEMP_TO_REG(data->temp1_hyst))); 198 TEMP_TO_REG(data->temp1_hyst));
199 mutex_unlock(&data->update_lock); 199 mutex_unlock(&data->update_lock);
200 return count; 200 return count;
201} 201}
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index dd2d7b9620c2..385886a4f224 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -137,10 +137,10 @@ static int max16065_read_adc(struct i2c_client *client, int reg)
137{ 137{
138 int rv; 138 int rv;
139 139
140 rv = i2c_smbus_read_word_data(client, reg); 140 rv = i2c_smbus_read_word_swapped(client, reg);
141 if (unlikely(rv < 0)) 141 if (unlikely(rv < 0))
142 return rv; 142 return rv;
143 return ((rv & 0xff) << 2) | ((rv >> 14) & 0x03); 143 return rv >> 6;
144} 144}
145 145
146static struct max16065_data *max16065_update_device(struct device *dev) 146static struct max16065_data *max16065_update_device(struct device *dev)
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 1c8c9812f244..15398780cc00 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -83,25 +83,6 @@ static inline int sht21_rh_ticks_to_per_cent_mille(int ticks)
83} 83}
84 84
85/** 85/**
86 * sht21_read_word_data() - read word from register
87 * @client: I2C client device
88 * @reg: I2C command byte
89 *
90 * Returns value, negative errno on error.
91 */
92static inline int sht21_read_word_data(struct i2c_client *client, u8 reg)
93{
94 int ret = i2c_smbus_read_word_data(client, reg);
95 if (ret < 0)
96 return ret;
97 /*
98 * SMBus specifies low byte first, but the SHT21 returns MSB
99 * first, so we have to swab16 the values
100 */
101 return swab16(ret);
102}
103
104/**
105 * sht21_update_measurements() - get updated measurements from device 86 * sht21_update_measurements() - get updated measurements from device
106 * @client: I2C client device 87 * @client: I2C client device
107 * 88 *
@@ -119,12 +100,13 @@ static int sht21_update_measurements(struct i2c_client *client)
119 * maximum two measurements per second at 12bit accuracy shall be made. 100 * maximum two measurements per second at 12bit accuracy shall be made.
120 */ 101 */
121 if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) { 102 if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) {
122 ret = sht21_read_word_data(client, SHT21_TRIG_T_MEASUREMENT_HM); 103 ret = i2c_smbus_read_word_swapped(client,
104 SHT21_TRIG_T_MEASUREMENT_HM);
123 if (ret < 0) 105 if (ret < 0)
124 goto out; 106 goto out;
125 sht21->temperature = sht21_temp_ticks_to_millicelsius(ret); 107 sht21->temperature = sht21_temp_ticks_to_millicelsius(ret);
126 ret = sht21_read_word_data(client, 108 ret = i2c_smbus_read_word_swapped(client,
127 SHT21_TRIG_RH_MEASUREMENT_HM); 109 SHT21_TRIG_RH_MEASUREMENT_HM);
128 if (ret < 0) 110 if (ret < 0)
129 goto out; 111 goto out;
130 sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret); 112 sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret);
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c
index 425df5bccd45..411638181fd8 100644
--- a/drivers/hwmon/smm665.c
+++ b/drivers/hwmon/smm665.c
@@ -214,33 +214,26 @@ static int smm665_read_adc(struct smm665_data *data, int adc)
214 * 214 *
215 * Neither i2c_smbus_read_byte() nor 215 * Neither i2c_smbus_read_byte() nor
216 * i2c_smbus_read_block_data() worked here, 216 * i2c_smbus_read_block_data() worked here,
217 * so use i2c_smbus_read_word_data() instead. 217 * so use i2c_smbus_read_word_swapped() instead.
218 * We could also try to use i2c_master_recv(), 218 * We could also try to use i2c_master_recv(),
219 * but that is not always supported. 219 * but that is not always supported.
220 */ 220 */
221 rv = i2c_smbus_read_word_data(client, 0); 221 rv = i2c_smbus_read_word_swapped(client, 0);
222 if (rv < 0) { 222 if (rv < 0) {
223 dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv); 223 dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv);
224 return -1; 224 return -1;
225 } 225 }
226 /* 226 /*
227 * Validate/verify readback adc channel (in bit 11..14). 227 * Validate/verify readback adc channel (in bit 11..14).
228 * High byte is in lower 8 bit of rv, so only shift by 3.
229 */ 228 */
230 radc = (rv >> 3) & 0x0f; 229 radc = (rv >> 11) & 0x0f;
231 if (radc != adc) { 230 if (radc != adc) {
232 dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d", 231 dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d",
233 adc, radc); 232 adc, radc);
234 return -EIO; 233 return -EIO;
235 } 234 }
236 /*
237 * Chip replies with H/L, while SMBus expects L/H.
238 * Thus, byte order is reversed, and we have to swap
239 * the result.
240 */
241 rv = swab16(rv) & SMM665_ADC_MASK;
242 235
243 return rv; 236 return rv & SMM665_ADC_MASK;
244} 237}
245 238
246static struct smm665_data *smm665_update_device(struct device *dev) 239static struct smm665_data *smm665_update_device(struct device *dev)
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 9fb7516e6f45..65c88ff5645a 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -113,7 +113,7 @@ struct smsc47b397_data {
113 u8 temp[4]; 113 u8 temp[4];
114}; 114};
115 115
116static int smsc47b397_read_value(struct smsc47b397_data* data, u8 reg) 116static int smsc47b397_read_value(struct smsc47b397_data *data, u8 reg)
117{ 117{
118 int res; 118 int res;
119 119
@@ -265,7 +265,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev)
265 return -EBUSY; 265 return -EBUSY;
266 } 266 }
267 267
268 if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { 268 data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL);
269 if (!data) {
269 err = -ENOMEM; 270 err = -ENOMEM;
270 goto error_release; 271 goto error_release;
271 } 272 }
@@ -276,7 +277,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev)
276 mutex_init(&data->update_lock); 277 mutex_init(&data->update_lock);
277 platform_set_drvdata(pdev, data); 278 platform_set_drvdata(pdev, data);
278 279
279 if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) 280 err = sysfs_create_group(&dev->kobj, &smsc47b397_group);
281 if (err)
280 goto error_free; 282 goto error_free;
281 283
282 data->hwmon_dev = hwmon_device_register(dev); 284 data->hwmon_dev = hwmon_device_register(dev);
@@ -345,7 +347,7 @@ static int __init smsc47b397_find(unsigned short *addr)
345 superio_enter(); 347 superio_enter();
346 id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); 348 id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
347 349
348 switch(id) { 350 switch (id) {
349 case 0x81: 351 case 0x81:
350 name = "SCH5307-NS"; 352 name = "SCH5307-NS";
351 break; 353 break;
@@ -379,7 +381,8 @@ static int __init smsc47b397_init(void)
379 unsigned short address; 381 unsigned short address;
380 int ret; 382 int ret;
381 383
382 if ((ret = smsc47b397_find(&address))) 384 ret = smsc47b397_find(&address);
385 if (ret)
383 return ret; 386 return ret;
384 387
385 ret = platform_driver_register(&smsc47b397_driver); 388 ret = platform_driver_register(&smsc47b397_driver);
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 5bd194968801..643aa8c94535 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -55,19 +55,6 @@ struct tmp102 {
55 int temp[3]; 55 int temp[3];
56}; 56};
57 57
58/* SMBus specifies low byte first, but the TMP102 returns high byte first,
59 * so we have to swab16 the values */
60static inline int tmp102_read_reg(struct i2c_client *client, u8 reg)
61{
62 int result = i2c_smbus_read_word_data(client, reg);
63 return result < 0 ? result : swab16(result);
64}
65
66static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val)
67{
68 return i2c_smbus_write_word_data(client, reg, swab16(val));
69}
70
71/* convert left adjusted 13-bit TMP102 register value to milliCelsius */ 58/* convert left adjusted 13-bit TMP102 register value to milliCelsius */
72static inline int tmp102_reg_to_mC(s16 val) 59static inline int tmp102_reg_to_mC(s16 val)
73{ 60{
@@ -94,7 +81,8 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client)
94 if (time_after(jiffies, tmp102->last_update + HZ / 3)) { 81 if (time_after(jiffies, tmp102->last_update + HZ / 3)) {
95 int i; 82 int i;
96 for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { 83 for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) {
97 int status = tmp102_read_reg(client, tmp102_reg[i]); 84 int status = i2c_smbus_read_word_swapped(client,
85 tmp102_reg[i]);
98 if (status > -1) 86 if (status > -1)
99 tmp102->temp[i] = tmp102_reg_to_mC(status); 87 tmp102->temp[i] = tmp102_reg_to_mC(status);
100 } 88 }
@@ -130,8 +118,8 @@ static ssize_t tmp102_set_temp(struct device *dev,
130 118
131 mutex_lock(&tmp102->lock); 119 mutex_lock(&tmp102->lock);
132 tmp102->temp[sda->index] = val; 120 tmp102->temp[sda->index] = val;
133 status = tmp102_write_reg(client, tmp102_reg[sda->index], 121 status = i2c_smbus_write_word_swapped(client, tmp102_reg[sda->index],
134 tmp102_mC_to_reg(val)); 122 tmp102_mC_to_reg(val));
135 mutex_unlock(&tmp102->lock); 123 mutex_unlock(&tmp102->lock);
136 return status ? : count; 124 return status ? : count;
137} 125}
@@ -178,18 +166,19 @@ static int __devinit tmp102_probe(struct i2c_client *client,
178 } 166 }
179 i2c_set_clientdata(client, tmp102); 167 i2c_set_clientdata(client, tmp102);
180 168
181 status = tmp102_read_reg(client, TMP102_CONF_REG); 169 status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
182 if (status < 0) { 170 if (status < 0) {
183 dev_err(&client->dev, "error reading config register\n"); 171 dev_err(&client->dev, "error reading config register\n");
184 goto fail_free; 172 goto fail_free;
185 } 173 }
186 tmp102->config_orig = status; 174 tmp102->config_orig = status;
187 status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); 175 status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
176 TMP102_CONFIG);
188 if (status < 0) { 177 if (status < 0) {
189 dev_err(&client->dev, "error writing config register\n"); 178 dev_err(&client->dev, "error writing config register\n");
190 goto fail_restore_config; 179 goto fail_restore_config;
191 } 180 }
192 status = tmp102_read_reg(client, TMP102_CONF_REG); 181 status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
193 if (status < 0) { 182 if (status < 0) {
194 dev_err(&client->dev, "error reading config register\n"); 183 dev_err(&client->dev, "error reading config register\n");
195 goto fail_restore_config; 184 goto fail_restore_config;
@@ -222,7 +211,8 @@ static int __devinit tmp102_probe(struct i2c_client *client,
222fail_remove_sysfs: 211fail_remove_sysfs:
223 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); 212 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
224fail_restore_config: 213fail_restore_config:
225 tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); 214 i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
215 tmp102->config_orig);
226fail_free: 216fail_free:
227 kfree(tmp102); 217 kfree(tmp102);
228 218
@@ -240,10 +230,10 @@ static int __devexit tmp102_remove(struct i2c_client *client)
240 if (tmp102->config_orig & TMP102_CONF_SD) { 230 if (tmp102->config_orig & TMP102_CONF_SD) {
241 int config; 231 int config;
242 232
243 config = tmp102_read_reg(client, TMP102_CONF_REG); 233 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
244 if (config >= 0) 234 if (config >= 0)
245 tmp102_write_reg(client, TMP102_CONF_REG, 235 i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
246 config | TMP102_CONF_SD); 236 config | TMP102_CONF_SD);
247 } 237 }
248 238
249 kfree(tmp102); 239 kfree(tmp102);
@@ -257,12 +247,12 @@ static int tmp102_suspend(struct device *dev)
257 struct i2c_client *client = to_i2c_client(dev); 247 struct i2c_client *client = to_i2c_client(dev);
258 int config; 248 int config;
259 249
260 config = tmp102_read_reg(client, TMP102_CONF_REG); 250 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
261 if (config < 0) 251 if (config < 0)
262 return config; 252 return config;
263 253
264 config |= TMP102_CONF_SD; 254 config |= TMP102_CONF_SD;
265 return tmp102_write_reg(client, TMP102_CONF_REG, config); 255 return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config);
266} 256}
267 257
268static int tmp102_resume(struct device *dev) 258static int tmp102_resume(struct device *dev)
@@ -270,12 +260,12 @@ static int tmp102_resume(struct device *dev)
270 struct i2c_client *client = to_i2c_client(dev); 260 struct i2c_client *client = to_i2c_client(dev);
271 int config; 261 int config;
272 262
273 config = tmp102_read_reg(client, TMP102_CONF_REG); 263 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
274 if (config < 0) 264 if (config < 0)
275 return config; 265 return config;
276 266
277 config &= ~TMP102_CONF_SD; 267 config &= ~TMP102_CONF_SD;
278 return tmp102_write_reg(client, TMP102_CONF_REG, config); 268 return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config);
279} 269}
280 270
281static const struct dev_pm_ops tmp102_dev_pm_ops = { 271static const struct dev_pm_ops tmp102_dev_pm_ops = {
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 98aab4bea342..93f5fc7d6059 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1,7 +1,7 @@
1/* 1/*
2 w83627ehf - Driver for the hardware monitoring functionality of 2 w83627ehf - Driver for the hardware monitoring functionality of
3 the Winbond W83627EHF Super-I/O chip 3 the Winbond W83627EHF Super-I/O chip
4 Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> 4 Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org>
5 Copyright (C) 2006 Yuan Mu (Winbond), 5 Copyright (C) 2006 Yuan Mu (Winbond),
6 Rudolf Marek <r.marek@assembler.cz> 6 Rudolf Marek <r.marek@assembler.cz>
7 David Hubbard <david.c.hubbard@gmail.com> 7 David Hubbard <david.c.hubbard@gmail.com>
@@ -39,6 +39,7 @@
39 0x8860 0xa1 39 0x8860 0xa1
40 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 40 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
41 w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 41 w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3
42 w83627uhg 8 2 2 2 0xa230 0xc1 0x5ca3
42 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 43 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
43 w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 44 w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3
44 nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 45 nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3
@@ -61,14 +62,17 @@
61#include <linux/io.h> 62#include <linux/io.h>
62#include "lm75.h" 63#include "lm75.h"
63 64
64enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg, w83667hg_b, nct6775, 65enum kinds {
65 nct6776 }; 66 w83627ehf, w83627dhg, w83627dhg_p, w83627uhg,
67 w83667hg, w83667hg_b, nct6775, nct6776,
68};
66 69
67/* used to set data->name = w83627ehf_device_names[data->sio_kind] */ 70/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
68static const char * const w83627ehf_device_names[] = { 71static const char * const w83627ehf_device_names[] = {
69 "w83627ehf", 72 "w83627ehf",
70 "w83627dhg", 73 "w83627dhg",
71 "w83627dhg", 74 "w83627dhg",
75 "w83627uhg",
72 "w83667hg", 76 "w83667hg",
73 "w83667hg", 77 "w83667hg",
74 "nct6775", 78 "nct6775",
@@ -104,6 +108,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
104#define SIO_W83627EHG_ID 0x8860 108#define SIO_W83627EHG_ID 0x8860
105#define SIO_W83627DHG_ID 0xa020 109#define SIO_W83627DHG_ID 0xa020
106#define SIO_W83627DHG_P_ID 0xb070 110#define SIO_W83627DHG_P_ID 0xb070
111#define SIO_W83627UHG_ID 0xa230
107#define SIO_W83667HG_ID 0xa510 112#define SIO_W83667HG_ID 0xa510
108#define SIO_W83667HG_B_ID 0xb350 113#define SIO_W83667HG_B_ID 0xb350
109#define SIO_NCT6775_ID 0xb470 114#define SIO_NCT6775_ID 0xb470
@@ -388,18 +393,23 @@ div_from_reg(u8 reg)
388 return 1 << reg; 393 return 1 << reg;
389} 394}
390 395
391/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ 396/* Some of the voltage inputs have internal scaling, the tables below
392 397 * contain 8 (the ADC LSB in mV) * scaling factor * 100 */
393static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; 398static const u16 scale_in_common[10] = {
399 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800
400};
401static const u16 scale_in_w83627uhg[9] = {
402 800, 800, 3328, 3424, 800, 800, 0, 3328, 3400
403};
394 404
395static inline long in_from_reg(u8 reg, u8 nr) 405static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale_in)
396{ 406{
397 return reg * scale_in[nr]; 407 return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
398} 408}
399 409
400static inline u8 in_to_reg(u32 val, u8 nr) 410static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in)
401{ 411{
402 return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 412 return SENSORS_LIMIT(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0,
403 255); 413 255);
404} 414}
405 415
@@ -430,6 +440,7 @@ struct w83627ehf_data {
430 const u16 *REG_FAN_STOP_TIME; 440 const u16 *REG_FAN_STOP_TIME;
431 const u16 *REG_FAN_MAX_OUTPUT; 441 const u16 *REG_FAN_MAX_OUTPUT;
432 const u16 *REG_FAN_STEP_OUTPUT; 442 const u16 *REG_FAN_STEP_OUTPUT;
443 const u16 *scale_in;
433 444
434 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); 445 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
435 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); 446 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
@@ -481,7 +492,8 @@ struct w83627ehf_data {
481 u8 vrm; 492 u8 vrm;
482 493
483 u16 have_temp; 494 u16 have_temp;
484 u8 in6_skip; 495 u8 in6_skip:1;
496 u8 temp3_val_only:1;
485}; 497};
486 498
487struct w83627ehf_sio_data { 499struct w83627ehf_sio_data {
@@ -907,7 +919,8 @@ show_##reg(struct device *dev, struct device_attribute *attr, \
907 struct sensor_device_attribute *sensor_attr = \ 919 struct sensor_device_attribute *sensor_attr = \
908 to_sensor_dev_attr(attr); \ 920 to_sensor_dev_attr(attr); \
909 int nr = sensor_attr->index; \ 921 int nr = sensor_attr->index; \
910 return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ 922 return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr, \
923 data->scale_in)); \
911} 924}
912show_in_reg(in) 925show_in_reg(in)
913show_in_reg(in_min) 926show_in_reg(in_min)
@@ -928,7 +941,7 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \
928 if (err < 0) \ 941 if (err < 0) \
929 return err; \ 942 return err; \
930 mutex_lock(&data->update_lock); \ 943 mutex_lock(&data->update_lock); \
931 data->in_##reg[nr] = in_to_reg(val, nr); \ 944 data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \
932 w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ 945 w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \
933 data->in_##reg[nr]); \ 946 data->in_##reg[nr]); \
934 mutex_unlock(&data->update_lock); \ 947 mutex_unlock(&data->update_lock); \
@@ -1617,25 +1630,28 @@ static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
1617 store_fan_step_output, 3), 1630 store_fan_step_output, 3),
1618}; 1631};
1619 1632
1633static struct sensor_device_attribute sda_sf3_arrays_fan3[] = {
1634 SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
1635 store_fan_stop_time, 2),
1636 SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
1637 store_fan_start_output, 2),
1638 SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
1639 store_fan_stop_output, 2),
1640};
1641
1620static struct sensor_device_attribute sda_sf3_arrays[] = { 1642static struct sensor_device_attribute sda_sf3_arrays[] = {
1621 SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, 1643 SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
1622 store_fan_stop_time, 0), 1644 store_fan_stop_time, 0),
1623 SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, 1645 SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
1624 store_fan_stop_time, 1), 1646 store_fan_stop_time, 1),
1625 SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
1626 store_fan_stop_time, 2),
1627 SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, 1647 SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
1628 store_fan_start_output, 0), 1648 store_fan_start_output, 0),
1629 SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, 1649 SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
1630 store_fan_start_output, 1), 1650 store_fan_start_output, 1),
1631 SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
1632 store_fan_start_output, 2),
1633 SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, 1651 SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
1634 store_fan_stop_output, 0), 1652 store_fan_stop_output, 0),
1635 SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, 1653 SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
1636 store_fan_stop_output, 1), 1654 store_fan_stop_output, 1),
1637 SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
1638 store_fan_stop_output, 2),
1639}; 1655};
1640 1656
1641 1657
@@ -1728,6 +1744,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
1728 data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) 1744 data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
1729 device_remove_file(dev, &attr->dev_attr); 1745 device_remove_file(dev, &attr->dev_attr);
1730 } 1746 }
1747 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++)
1748 device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr);
1731 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) 1749 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
1732 device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); 1750 device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
1733 for (i = 0; i < data->in_num; i++) { 1751 for (i = 0; i < data->in_num; i++) {
@@ -1756,6 +1774,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
1756 continue; 1774 continue;
1757 device_remove_file(dev, &sda_temp_input[i].dev_attr); 1775 device_remove_file(dev, &sda_temp_input[i].dev_attr);
1758 device_remove_file(dev, &sda_temp_label[i].dev_attr); 1776 device_remove_file(dev, &sda_temp_label[i].dev_attr);
1777 if (i == 2 && data->temp3_val_only)
1778 continue;
1759 device_remove_file(dev, &sda_temp_max[i].dev_attr); 1779 device_remove_file(dev, &sda_temp_max[i].dev_attr);
1760 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); 1780 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
1761 if (i > 2) 1781 if (i > 2)
@@ -1808,11 +1828,24 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
1808 case w83627ehf: 1828 case w83627ehf:
1809 diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); 1829 diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
1810 break; 1830 break;
1831 case w83627uhg:
1832 diode = 0x00;
1833 break;
1811 default: 1834 default:
1812 diode = 0x70; 1835 diode = 0x70;
1813 } 1836 }
1814 for (i = 0; i < 3; i++) { 1837 for (i = 0; i < 3; i++) {
1815 if ((tmp & (0x02 << i))) 1838 const char *label = NULL;
1839
1840 if (data->temp_label)
1841 label = data->temp_label[data->temp_src[i]];
1842
1843 /* Digital source overrides analog type */
1844 if (label && strncmp(label, "PECI", 4) == 0)
1845 data->temp_type[i] = 6;
1846 else if (label && strncmp(label, "AMD", 3) == 0)
1847 data->temp_type[i] = 5;
1848 else if ((tmp & (0x02 << i)))
1816 data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3; 1849 data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
1817 else 1850 else
1818 data->temp_type[i] = 4; /* thermistor */ 1851 data->temp_type[i] = 4; /* thermistor */
@@ -1846,11 +1879,31 @@ static void w82627ehf_swap_tempreg(struct w83627ehf_data *data,
1846} 1879}
1847 1880
1848static void __devinit 1881static void __devinit
1882w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp)
1883{
1884 int i;
1885
1886 for (i = 0; i < n_temp; i++) {
1887 data->reg_temp[i] = W83627EHF_REG_TEMP[i];
1888 data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
1889 data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
1890 data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
1891 }
1892}
1893
1894static void __devinit
1849w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data, 1895w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
1850 struct w83627ehf_data *data) 1896 struct w83627ehf_data *data)
1851{ 1897{
1852 int fan3pin, fan4pin, fan4min, fan5pin, regval; 1898 int fan3pin, fan4pin, fan4min, fan5pin, regval;
1853 1899
1900 /* The W83627UHG is simple, only two fan inputs, no config */
1901 if (sio_data->kind == w83627uhg) {
1902 data->has_fan = 0x03; /* fan1 and fan2 */
1903 data->has_fan_min = 0x03;
1904 return;
1905 }
1906
1854 superio_enter(sio_data->sioreg); 1907 superio_enter(sio_data->sioreg);
1855 1908
1856 /* fan4 and fan5 share some pins with the GPIO and serial flash */ 1909 /* fan4 and fan5 share some pins with the GPIO and serial flash */
@@ -1942,23 +1995,24 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1942 1995
1943 /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ 1996 /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
1944 data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9; 1997 data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
1945 /* 667HG, NCT6775F, and NCT6776F have 3 pwms */ 1998 /* 667HG, NCT6775F, and NCT6776F have 3 pwms, and 627UHG has only 2 */
1946 data->pwm_num = (sio_data->kind == w83667hg 1999 switch (sio_data->kind) {
1947 || sio_data->kind == w83667hg_b 2000 default:
1948 || sio_data->kind == nct6775 2001 data->pwm_num = 4;
1949 || sio_data->kind == nct6776) ? 3 : 4; 2002 break;
2003 case w83667hg:
2004 case w83667hg_b:
2005 case nct6775:
2006 case nct6776:
2007 data->pwm_num = 3;
2008 break;
2009 case w83627uhg:
2010 data->pwm_num = 2;
2011 break;
2012 }
1950 2013
2014 /* Default to 3 temperature inputs, code below will adjust as needed */
1951 data->have_temp = 0x07; 2015 data->have_temp = 0x07;
1952 /* Check temp3 configuration bit for 667HG */
1953 if (sio_data->kind == w83667hg) {
1954 u8 reg;
1955
1956 reg = w83627ehf_read_value(data, W83627EHF_REG_TEMP_CONFIG[2]);
1957 if (reg & 0x01)
1958 data->have_temp &= ~(1 << 2);
1959 else
1960 data->in6_skip = 1; /* either temp3 or in6 */
1961 }
1962 2016
1963 /* Deal with temperature register setup first. */ 2017 /* Deal with temperature register setup first. */
1964 if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { 2018 if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
@@ -2035,16 +2089,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2035 } else if (sio_data->kind == w83667hg_b) { 2089 } else if (sio_data->kind == w83667hg_b) {
2036 u8 reg; 2090 u8 reg;
2037 2091
2092 w83627ehf_set_temp_reg_ehf(data, 4);
2093
2038 /* 2094 /*
2039 * Temperature sources are selected with bank 0, registers 0x49 2095 * Temperature sources are selected with bank 0, registers 0x49
2040 * and 0x4a. 2096 * and 0x4a.
2041 */ 2097 */
2042 for (i = 0; i < ARRAY_SIZE(W83627EHF_REG_TEMP); i++) {
2043 data->reg_temp[i] = W83627EHF_REG_TEMP[i];
2044 data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
2045 data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
2046 data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
2047 }
2048 reg = w83627ehf_read_value(data, 0x4a); 2098 reg = w83627ehf_read_value(data, 0x4a);
2049 data->temp_src[0] = reg >> 5; 2099 data->temp_src[0] = reg >> 5;
2050 reg = w83627ehf_read_value(data, 0x49); 2100 reg = w83627ehf_read_value(data, 0x49);
@@ -2078,13 +2128,60 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2078 data->in6_skip = 1; 2128 data->in6_skip = 1;
2079 2129
2080 data->temp_label = w83667hg_b_temp_label; 2130 data->temp_label = w83667hg_b_temp_label;
2131 } else if (sio_data->kind == w83627uhg) {
2132 u8 reg;
2133
2134 w83627ehf_set_temp_reg_ehf(data, 3);
2135
2136 /*
2137 * Temperature sources for temp1 and temp2 are selected with
2138 * bank 0, registers 0x49 and 0x4a.
2139 */
2140 data->temp_src[0] = 0; /* SYSTIN */
2141 reg = w83627ehf_read_value(data, 0x49) & 0x07;
2142 /* Adjust to have the same mapping as other source registers */
2143 if (reg == 0)
2144 data->temp_src[1]++;
2145 else if (reg >= 2 && reg <= 5)
2146 data->temp_src[1] += 2;
2147 else /* should never happen */
2148 data->have_temp &= ~(1 << 1);
2149 reg = w83627ehf_read_value(data, 0x4a);
2150 data->temp_src[2] = reg >> 5;
2151
2152 /*
2153 * Skip temp3 if source is invalid or the same as temp1
2154 * or temp2.
2155 */
2156 if (data->temp_src[2] == 2 || data->temp_src[2] == 3 ||
2157 data->temp_src[2] == data->temp_src[0] ||
2158 ((data->have_temp & (1 << 1)) &&
2159 data->temp_src[2] == data->temp_src[1]))
2160 data->have_temp &= ~(1 << 2);
2161 else
2162 data->temp3_val_only = 1; /* No limit regs */
2163
2164 data->in6_skip = 1; /* No VIN3 */
2165
2166 data->temp_label = w83667hg_b_temp_label;
2081 } else { 2167 } else {
2168 w83627ehf_set_temp_reg_ehf(data, 3);
2169
2082 /* Temperature sources are fixed */ 2170 /* Temperature sources are fixed */
2083 for (i = 0; i < 3; i++) { 2171
2084 data->reg_temp[i] = W83627EHF_REG_TEMP[i]; 2172 if (sio_data->kind == w83667hg) {
2085 data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i]; 2173 u8 reg;
2086 data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i]; 2174
2087 data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i]; 2175 /*
2176 * Chip supports either AUXTIN or VIN3. Try to find
2177 * out which one.
2178 */
2179 reg = w83627ehf_read_value(data,
2180 W83627EHF_REG_TEMP_CONFIG[2]);
2181 if (reg & 0x01)
2182 data->have_temp &= ~(1 << 2);
2183 else
2184 data->in6_skip = 1;
2088 } 2185 }
2089 } 2186 }
2090 2187
@@ -2144,6 +2241,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2144 W83627EHF_REG_FAN_STEP_OUTPUT_COMMON; 2241 W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
2145 } 2242 }
2146 2243
2244 /* Setup input voltage scaling factors */
2245 if (sio_data->kind == w83627uhg)
2246 data->scale_in = scale_in_w83627uhg;
2247 else
2248 data->scale_in = scale_in_common;
2249
2147 /* Initialize the chip */ 2250 /* Initialize the chip */
2148 w83627ehf_init_device(data, sio_data->kind); 2251 w83627ehf_init_device(data, sio_data->kind);
2149 2252
@@ -2160,7 +2263,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2160 err = device_create_file(dev, &dev_attr_cpu0_vid); 2263 err = device_create_file(dev, &dev_attr_cpu0_vid);
2161 if (err) 2264 if (err)
2162 goto exit_release; 2265 goto exit_release;
2163 } else { 2266 } else if (sio_data->kind != w83627uhg) {
2164 superio_select(sio_data->sioreg, W83627EHF_LD_HWM); 2267 superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
2165 if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { 2268 if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
2166 /* Set VID input sensibility if needed. In theory the 2269 /* Set VID input sensibility if needed. In theory the
@@ -2250,7 +2353,14 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2250 goto exit_remove; 2353 goto exit_remove;
2251 } 2354 }
2252 } 2355 }
2253 /* if fan4 is enabled create the sf3 files for it */ 2356 /* if fan3 and fan4 are enabled create the sf3 files for them */
2357 if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3)
2358 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) {
2359 err = device_create_file(dev,
2360 &sda_sf3_arrays_fan3[i].dev_attr);
2361 if (err)
2362 goto exit_remove;
2363 }
2254 if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) 2364 if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
2255 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { 2365 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
2256 err = device_create_file(dev, 2366 err = device_create_file(dev,
@@ -2318,6 +2428,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
2318 if (err) 2428 if (err)
2319 goto exit_remove; 2429 goto exit_remove;
2320 } 2430 }
2431 if (i == 2 && data->temp3_val_only)
2432 continue;
2321 if (data->reg_temp_over[i]) { 2433 if (data->reg_temp_over[i]) {
2322 err = device_create_file(dev, 2434 err = device_create_file(dev,
2323 &sda_temp_max[i].dev_attr); 2435 &sda_temp_max[i].dev_attr);
@@ -2401,6 +2513,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
2401 static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; 2513 static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
2402 static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; 2514 static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
2403 static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; 2515 static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
2516 static const char __initdata sio_name_W83627UHG[] = "W83627UHG";
2404 static const char __initdata sio_name_W83667HG[] = "W83667HG"; 2517 static const char __initdata sio_name_W83667HG[] = "W83667HG";
2405 static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B"; 2518 static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
2406 static const char __initdata sio_name_NCT6775[] = "NCT6775F"; 2519 static const char __initdata sio_name_NCT6775[] = "NCT6775F";
@@ -2433,6 +2546,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
2433 sio_data->kind = w83627dhg_p; 2546 sio_data->kind = w83627dhg_p;
2434 sio_name = sio_name_W83627DHG_P; 2547 sio_name = sio_name_W83627DHG_P;
2435 break; 2548 break;
2549 case SIO_W83627UHG_ID:
2550 sio_data->kind = w83627uhg;
2551 sio_name = sio_name_W83627UHG;
2552 break;
2436 case SIO_W83667HG_ID: 2553 case SIO_W83667HG_ID:
2437 sio_data->kind = w83667hg; 2554 sio_data->kind = w83667hg;
2438 sio_name = sio_name_W83667HG; 2555 sio_name = sio_name_W83667HG;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index eed43a008be1..65b685e2c7b7 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1245,17 +1245,17 @@ w83781d_read_value_i2c(struct w83781d_data *data, u16 reg)
1245 /* convert from ISA to LM75 I2C addresses */ 1245 /* convert from ISA to LM75 I2C addresses */
1246 switch (reg & 0xff) { 1246 switch (reg & 0xff) {
1247 case 0x50: /* TEMP */ 1247 case 0x50: /* TEMP */
1248 res = swab16(i2c_smbus_read_word_data(cl, 0)); 1248 res = i2c_smbus_read_word_swapped(cl, 0);
1249 break; 1249 break;
1250 case 0x52: /* CONFIG */ 1250 case 0x52: /* CONFIG */
1251 res = i2c_smbus_read_byte_data(cl, 1); 1251 res = i2c_smbus_read_byte_data(cl, 1);
1252 break; 1252 break;
1253 case 0x53: /* HYST */ 1253 case 0x53: /* HYST */
1254 res = swab16(i2c_smbus_read_word_data(cl, 2)); 1254 res = i2c_smbus_read_word_swapped(cl, 2);
1255 break; 1255 break;
1256 case 0x55: /* OVER */ 1256 case 0x55: /* OVER */
1257 default: 1257 default:
1258 res = swab16(i2c_smbus_read_word_data(cl, 3)); 1258 res = i2c_smbus_read_word_swapped(cl, 3);
1259 break; 1259 break;
1260 } 1260 }
1261 } 1261 }
@@ -1289,10 +1289,10 @@ w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value)
1289 i2c_smbus_write_byte_data(cl, 1, value & 0xff); 1289 i2c_smbus_write_byte_data(cl, 1, value & 0xff);
1290 break; 1290 break;
1291 case 0x53: /* HYST */ 1291 case 0x53: /* HYST */
1292 i2c_smbus_write_word_data(cl, 2, swab16(value)); 1292 i2c_smbus_write_word_swapped(cl, 2, value);
1293 break; 1293 break;
1294 case 0x55: /* OVER */ 1294 case 0x55: /* OVER */
1295 i2c_smbus_write_word_data(cl, 3, swab16(value)); 1295 i2c_smbus_write_word_swapped(cl, 3, value);
1296 break; 1296 break;
1297 } 1297 }
1298 } 1298 }
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index ab876f928a1b..ed9a989e501b 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -146,7 +146,7 @@ static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order)
146 146
147 buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), 147 buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *),
148 GFP_KERNEL); 148 GFP_KERNEL);
149 buddy->num_free = kzalloc((buddy->max_order + 1) * sizeof (int *), 149 buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free,
150 GFP_KERNEL); 150 GFP_KERNEL);
151 if (!buddy->bits || !buddy->num_free) 151 if (!buddy->bits || !buddy->num_free)
152 goto err_out; 152 goto err_out;
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index afaf4ac79f42..894afac26f3b 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -271,13 +271,9 @@ int qib_make_rc_req(struct qib_qp *qp)
271 goto bail; 271 goto bail;
272 } 272 }
273 wqe = get_swqe_ptr(qp, qp->s_last); 273 wqe = get_swqe_ptr(qp, qp->s_last);
274 while (qp->s_last != qp->s_acked) { 274 qib_send_complete(qp, wqe, qp->s_last != qp->s_acked ?
275 qib_send_complete(qp, wqe, IB_WC_SUCCESS); 275 IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR);
276 if (++qp->s_last >= qp->s_size) 276 /* will get called again */
277 qp->s_last = 0;
278 wqe = get_swqe_ptr(qp, qp->s_last);
279 }
280 qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
281 goto done; 277 goto done;
282 } 278 }
283 279
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 84e8c293a715..c42b8f390c0b 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -151,7 +151,6 @@ int iser_initialize_task_headers(struct iscsi_task *task,
151 tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; 151 tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
152 tx_desc->tx_sg[0].lkey = device->mr->lkey; 152 tx_desc->tx_sg[0].lkey = device->mr->lkey;
153 153
154 iser_task->headers_initialized = 1;
155 iser_task->iser_conn = iser_conn; 154 iser_task->iser_conn = iser_conn;
156 return 0; 155 return 0;
157} 156}
@@ -166,8 +165,7 @@ iscsi_iser_task_init(struct iscsi_task *task)
166{ 165{
167 struct iscsi_iser_task *iser_task = task->dd_data; 166 struct iscsi_iser_task *iser_task = task->dd_data;
168 167
169 if (!iser_task->headers_initialized) 168 if (iser_initialize_task_headers(task, &iser_task->desc))
170 if (iser_initialize_task_headers(task, &iser_task->desc))
171 return -ENOMEM; 169 return -ENOMEM;
172 170
173 /* mgmt task */ 171 /* mgmt task */
@@ -278,6 +276,13 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
278static void iscsi_iser_cleanup_task(struct iscsi_task *task) 276static void iscsi_iser_cleanup_task(struct iscsi_task *task)
279{ 277{
280 struct iscsi_iser_task *iser_task = task->dd_data; 278 struct iscsi_iser_task *iser_task = task->dd_data;
279 struct iser_tx_desc *tx_desc = &iser_task->desc;
280
281 struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
282 struct iser_device *device = iser_conn->ib_conn->device;
283
284 ib_dma_unmap_single(device->ib_device,
285 tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
281 286
282 /* mgmt tasks do not need special cleanup */ 287 /* mgmt tasks do not need special cleanup */
283 if (!task->sc) 288 if (!task->sc)
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index db6f3ce9f3bf..db7ea3704da7 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -257,7 +257,8 @@ struct iser_conn {
257 struct list_head conn_list; /* entry in ig conn list */ 257 struct list_head conn_list; /* entry in ig conn list */
258 258
259 char *login_buf; 259 char *login_buf;
260 u64 login_dma; 260 char *login_req_buf, *login_resp_buf;
261 u64 login_req_dma, login_resp_dma;
261 unsigned int rx_desc_head; 262 unsigned int rx_desc_head;
262 struct iser_rx_desc *rx_descs; 263 struct iser_rx_desc *rx_descs;
263 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; 264 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX];
@@ -277,7 +278,6 @@ struct iscsi_iser_task {
277 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ 278 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
278 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ 279 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/
279 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ 280 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */
280 int headers_initialized;
281}; 281};
282 282
283struct iser_page_vec { 283struct iser_page_vec {
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index f299de6b419b..a607542fc796 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -221,8 +221,14 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
221 struct iser_device *device = ib_conn->device; 221 struct iser_device *device = ib_conn->device;
222 222
223 if (ib_conn->login_buf) { 223 if (ib_conn->login_buf) {
224 ib_dma_unmap_single(device->ib_device, ib_conn->login_dma, 224 if (ib_conn->login_req_dma)
225 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); 225 ib_dma_unmap_single(device->ib_device,
226 ib_conn->login_req_dma,
227 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
228 if (ib_conn->login_resp_dma)
229 ib_dma_unmap_single(device->ib_device,
230 ib_conn->login_resp_dma,
231 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
226 kfree(ib_conn->login_buf); 232 kfree(ib_conn->login_buf);
227 } 233 }
228 234
@@ -394,6 +400,7 @@ int iser_send_control(struct iscsi_conn *conn,
394 unsigned long data_seg_len; 400 unsigned long data_seg_len;
395 int err = 0; 401 int err = 0;
396 struct iser_device *device; 402 struct iser_device *device;
403 struct iser_conn *ib_conn = iser_conn->ib_conn;
397 404
398 /* build the tx desc regd header and add it to the tx desc dto */ 405 /* build the tx desc regd header and add it to the tx desc dto */
399 mdesc->type = ISCSI_TX_CONTROL; 406 mdesc->type = ISCSI_TX_CONTROL;
@@ -409,9 +416,19 @@ int iser_send_control(struct iscsi_conn *conn,
409 iser_err("data present on non login task!!!\n"); 416 iser_err("data present on non login task!!!\n");
410 goto send_control_error; 417 goto send_control_error;
411 } 418 }
412 memcpy(iser_conn->ib_conn->login_buf, task->data, 419
420 ib_dma_sync_single_for_cpu(device->ib_device,
421 ib_conn->login_req_dma, task->data_count,
422 DMA_TO_DEVICE);
423
424 memcpy(iser_conn->ib_conn->login_req_buf, task->data,
413 task->data_count); 425 task->data_count);
414 tx_dsg->addr = iser_conn->ib_conn->login_dma; 426
427 ib_dma_sync_single_for_device(device->ib_device,
428 ib_conn->login_req_dma, task->data_count,
429 DMA_TO_DEVICE);
430
431 tx_dsg->addr = iser_conn->ib_conn->login_req_dma;
415 tx_dsg->length = task->data_count; 432 tx_dsg->length = task->data_count;
416 tx_dsg->lkey = device->mr->lkey; 433 tx_dsg->lkey = device->mr->lkey;
417 mdesc->num_sge = 2; 434 mdesc->num_sge = 2;
@@ -445,8 +462,8 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
445 int rx_buflen, outstanding, count, err; 462 int rx_buflen, outstanding, count, err;
446 463
447 /* differentiate between login to all other PDUs */ 464 /* differentiate between login to all other PDUs */
448 if ((char *)rx_desc == ib_conn->login_buf) { 465 if ((char *)rx_desc == ib_conn->login_resp_buf) {
449 rx_dma = ib_conn->login_dma; 466 rx_dma = ib_conn->login_resp_dma;
450 rx_buflen = ISER_RX_LOGIN_SIZE; 467 rx_buflen = ISER_RX_LOGIN_SIZE;
451 } else { 468 } else {
452 rx_dma = rx_desc->dma_addr; 469 rx_dma = rx_desc->dma_addr;
@@ -473,7 +490,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
473 * for the posted rx bufs refcount to become zero handles everything */ 490 * for the posted rx bufs refcount to become zero handles everything */
474 conn->ib_conn->post_recv_buf_count--; 491 conn->ib_conn->post_recv_buf_count--;
475 492
476 if (rx_dma == ib_conn->login_dma) 493 if (rx_dma == ib_conn->login_resp_dma)
477 return; 494 return;
478 495
479 outstanding = ib_conn->post_recv_buf_count; 496 outstanding = ib_conn->post_recv_buf_count;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ede1475bee09..e28877c4ce15 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -155,20 +155,39 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
155{ 155{
156 struct iser_device *device; 156 struct iser_device *device;
157 struct ib_qp_init_attr init_attr; 157 struct ib_qp_init_attr init_attr;
158 int ret = -ENOMEM; 158 int req_err, resp_err, ret = -ENOMEM;
159 struct ib_fmr_pool_param params; 159 struct ib_fmr_pool_param params;
160 160
161 BUG_ON(ib_conn->device == NULL); 161 BUG_ON(ib_conn->device == NULL);
162 162
163 device = ib_conn->device; 163 device = ib_conn->device;
164 164
165 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); 165 ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
166 ISER_RX_LOGIN_SIZE, GFP_KERNEL);
166 if (!ib_conn->login_buf) 167 if (!ib_conn->login_buf)
167 goto out_err; 168 goto out_err;
168 169
169 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, 170 ib_conn->login_req_buf = ib_conn->login_buf;
170 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, 171 ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN;
171 DMA_FROM_DEVICE); 172
173 ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device,
174 (void *)ib_conn->login_req_buf,
175 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
176
177 ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device,
178 (void *)ib_conn->login_resp_buf,
179 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
180
181 req_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma);
182 resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma);
183
184 if (req_err || resp_err) {
185 if (req_err)
186 ib_conn->login_req_dma = 0;
187 if (resp_err)
188 ib_conn->login_resp_dma = 0;
189 goto out_err;
190 }
172 191
173 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + 192 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
174 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), 193 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
@@ -658,11 +677,11 @@ int iser_post_recvl(struct iser_conn *ib_conn)
658 struct ib_sge sge; 677 struct ib_sge sge;
659 int ib_ret; 678 int ib_ret;
660 679
661 sge.addr = ib_conn->login_dma; 680 sge.addr = ib_conn->login_resp_dma;
662 sge.length = ISER_RX_LOGIN_SIZE; 681 sge.length = ISER_RX_LOGIN_SIZE;
663 sge.lkey = ib_conn->device->mr->lkey; 682 sge.lkey = ib_conn->device->mr->lkey;
664 683
665 rx_wr.wr_id = (unsigned long)ib_conn->login_buf; 684 rx_wr.wr_id = (unsigned long)ib_conn->login_resp_buf;
666 rx_wr.sg_list = &sge; 685 rx_wr.sg_list = &sge;
667 rx_wr.num_sge = 1; 686 rx_wr.num_sge = 1;
668 rx_wr.next = NULL; 687 rx_wr.next = NULL;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 6b6616a41baa..4720f68f817e 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -192,9 +192,6 @@ struct mapped_device {
192 /* forced geometry settings */ 192 /* forced geometry settings */
193 struct hd_geometry geometry; 193 struct hd_geometry geometry;
194 194
195 /* For saving the address of __make_request for request based dm */
196 make_request_fn *saved_make_request_fn;
197
198 /* sysfs handle */ 195 /* sysfs handle */
199 struct kobject kobj; 196 struct kobject kobj;
200 197
@@ -1403,7 +1400,7 @@ out:
1403 * The request function that just remaps the bio built up by 1400 * The request function that just remaps the bio built up by
1404 * dm_merge_bvec. 1401 * dm_merge_bvec.
1405 */ 1402 */
1406static int _dm_request(struct request_queue *q, struct bio *bio) 1403static void _dm_request(struct request_queue *q, struct bio *bio)
1407{ 1404{
1408 int rw = bio_data_dir(bio); 1405 int rw = bio_data_dir(bio);
1409 struct mapped_device *md = q->queuedata; 1406 struct mapped_device *md = q->queuedata;
@@ -1424,19 +1421,12 @@ static int _dm_request(struct request_queue *q, struct bio *bio)
1424 queue_io(md, bio); 1421 queue_io(md, bio);
1425 else 1422 else
1426 bio_io_error(bio); 1423 bio_io_error(bio);
1427 return 0; 1424 return;
1428 } 1425 }
1429 1426
1430 __split_and_process_bio(md, bio); 1427 __split_and_process_bio(md, bio);
1431 up_read(&md->io_lock); 1428 up_read(&md->io_lock);
1432 return 0; 1429 return;
1433}
1434
1435static int dm_make_request(struct request_queue *q, struct bio *bio)
1436{
1437 struct mapped_device *md = q->queuedata;
1438
1439 return md->saved_make_request_fn(q, bio); /* call __make_request() */
1440} 1430}
1441 1431
1442static int dm_request_based(struct mapped_device *md) 1432static int dm_request_based(struct mapped_device *md)
@@ -1444,14 +1434,14 @@ static int dm_request_based(struct mapped_device *md)
1444 return blk_queue_stackable(md->queue); 1434 return blk_queue_stackable(md->queue);
1445} 1435}
1446 1436
1447static int dm_request(struct request_queue *q, struct bio *bio) 1437static void dm_request(struct request_queue *q, struct bio *bio)
1448{ 1438{
1449 struct mapped_device *md = q->queuedata; 1439 struct mapped_device *md = q->queuedata;
1450 1440
1451 if (dm_request_based(md)) 1441 if (dm_request_based(md))
1452 return dm_make_request(q, bio); 1442 blk_queue_bio(q, bio);
1453 1443 else
1454 return _dm_request(q, bio); 1444 _dm_request(q, bio);
1455} 1445}
1456 1446
1457void dm_dispatch_request(struct request *rq) 1447void dm_dispatch_request(struct request *rq)
@@ -2191,7 +2181,6 @@ static int dm_init_request_based_queue(struct mapped_device *md)
2191 return 0; 2181 return 0;
2192 2182
2193 md->queue = q; 2183 md->queue = q;
2194 md->saved_make_request_fn = md->queue->make_request_fn;
2195 dm_init_md_queue(md); 2184 dm_init_md_queue(md);
2196 blk_queue_softirq_done(md->queue, dm_softirq_done); 2185 blk_queue_softirq_done(md->queue, dm_softirq_done);
2197 blk_queue_prep_rq(md->queue, dm_prep_fn); 2186 blk_queue_prep_rq(md->queue, dm_prep_fn);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 60816b132c2e..918fb8ac6607 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -169,7 +169,7 @@ static void add_sector(struct faulty_conf *conf, sector_t start, int mode)
169 conf->nfaults = n+1; 169 conf->nfaults = n+1;
170} 170}
171 171
172static int make_request(struct mddev *mddev, struct bio *bio) 172static void make_request(struct mddev *mddev, struct bio *bio)
173{ 173{
174 struct faulty_conf *conf = mddev->private; 174 struct faulty_conf *conf = mddev->private;
175 int failit = 0; 175 int failit = 0;
@@ -181,7 +181,7 @@ static int make_request(struct mddev *mddev, struct bio *bio)
181 * just fail immediately 181 * just fail immediately
182 */ 182 */
183 bio_endio(bio, -EIO); 183 bio_endio(bio, -EIO);
184 return 0; 184 return;
185 } 185 }
186 186
187 if (check_sector(conf, bio->bi_sector, bio->bi_sector+(bio->bi_size>>9), 187 if (check_sector(conf, bio->bi_sector, bio->bi_sector+(bio->bi_size>>9),
@@ -211,15 +211,15 @@ static int make_request(struct mddev *mddev, struct bio *bio)
211 } 211 }
212 if (failit) { 212 if (failit) {
213 struct bio *b = bio_clone_mddev(bio, GFP_NOIO, mddev); 213 struct bio *b = bio_clone_mddev(bio, GFP_NOIO, mddev);
214
214 b->bi_bdev = conf->rdev->bdev; 215 b->bi_bdev = conf->rdev->bdev;
215 b->bi_private = bio; 216 b->bi_private = bio;
216 b->bi_end_io = faulty_fail; 217 b->bi_end_io = faulty_fail;
217 generic_make_request(b); 218 bio = b;
218 return 0; 219 } else
219 } else {
220 bio->bi_bdev = conf->rdev->bdev; 220 bio->bi_bdev = conf->rdev->bdev;
221 return 1; 221
222 } 222 generic_make_request(bio);
223} 223}
224 224
225static void status(struct seq_file *seq, struct mddev *mddev) 225static void status(struct seq_file *seq, struct mddev *mddev)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 10c5844460cb..a82035867519 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -264,14 +264,14 @@ static int linear_stop (struct mddev *mddev)
264 return 0; 264 return 0;
265} 265}
266 266
267static int linear_make_request (struct mddev *mddev, struct bio *bio) 267static void linear_make_request(struct mddev *mddev, struct bio *bio)
268{ 268{
269 struct dev_info *tmp_dev; 269 struct dev_info *tmp_dev;
270 sector_t start_sector; 270 sector_t start_sector;
271 271
272 if (unlikely(bio->bi_rw & REQ_FLUSH)) { 272 if (unlikely(bio->bi_rw & REQ_FLUSH)) {
273 md_flush_request(mddev, bio); 273 md_flush_request(mddev, bio);
274 return 0; 274 return;
275 } 275 }
276 276
277 rcu_read_lock(); 277 rcu_read_lock();
@@ -293,7 +293,7 @@ static int linear_make_request (struct mddev *mddev, struct bio *bio)
293 (unsigned long long)start_sector); 293 (unsigned long long)start_sector);
294 rcu_read_unlock(); 294 rcu_read_unlock();
295 bio_io_error(bio); 295 bio_io_error(bio);
296 return 0; 296 return;
297 } 297 }
298 if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > 298 if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
299 tmp_dev->end_sector)) { 299 tmp_dev->end_sector)) {
@@ -307,20 +307,17 @@ static int linear_make_request (struct mddev *mddev, struct bio *bio)
307 307
308 bp = bio_split(bio, end_sector - bio->bi_sector); 308 bp = bio_split(bio, end_sector - bio->bi_sector);
309 309
310 if (linear_make_request(mddev, &bp->bio1)) 310 linear_make_request(mddev, &bp->bio1);
311 generic_make_request(&bp->bio1); 311 linear_make_request(mddev, &bp->bio2);
312 if (linear_make_request(mddev, &bp->bio2))
313 generic_make_request(&bp->bio2);
314 bio_pair_release(bp); 312 bio_pair_release(bp);
315 return 0; 313 return;
316 } 314 }
317 315
318 bio->bi_bdev = tmp_dev->rdev->bdev; 316 bio->bi_bdev = tmp_dev->rdev->bdev;
319 bio->bi_sector = bio->bi_sector - start_sector 317 bio->bi_sector = bio->bi_sector - start_sector
320 + tmp_dev->rdev->data_offset; 318 + tmp_dev->rdev->data_offset;
321 rcu_read_unlock(); 319 rcu_read_unlock();
322 320 generic_make_request(bio);
323 return 1;
324} 321}
325 322
326static void linear_status (struct seq_file *seq, struct mddev *mddev) 323static void linear_status (struct seq_file *seq, struct mddev *mddev)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 266e82ebaf11..2acb32827fde 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -332,18 +332,17 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
332 * call has finished, the bio has been linked into some internal structure 332 * call has finished, the bio has been linked into some internal structure
333 * and so is visible to ->quiesce(), so we don't need the refcount any more. 333 * and so is visible to ->quiesce(), so we don't need the refcount any more.
334 */ 334 */
335static int md_make_request(struct request_queue *q, struct bio *bio) 335static void md_make_request(struct request_queue *q, struct bio *bio)
336{ 336{
337 const int rw = bio_data_dir(bio); 337 const int rw = bio_data_dir(bio);
338 struct mddev *mddev = q->queuedata; 338 struct mddev *mddev = q->queuedata;
339 int rv;
340 int cpu; 339 int cpu;
341 unsigned int sectors; 340 unsigned int sectors;
342 341
343 if (mddev == NULL || mddev->pers == NULL 342 if (mddev == NULL || mddev->pers == NULL
344 || !mddev->ready) { 343 || !mddev->ready) {
345 bio_io_error(bio); 344 bio_io_error(bio);
346 return 0; 345 return;
347 } 346 }
348 smp_rmb(); /* Ensure implications of 'active' are visible */ 347 smp_rmb(); /* Ensure implications of 'active' are visible */
349 rcu_read_lock(); 348 rcu_read_lock();
@@ -368,7 +367,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
368 * go away inside make_request 367 * go away inside make_request
369 */ 368 */
370 sectors = bio_sectors(bio); 369 sectors = bio_sectors(bio);
371 rv = mddev->pers->make_request(mddev, bio); 370 mddev->pers->make_request(mddev, bio);
372 371
373 cpu = part_stat_lock(); 372 cpu = part_stat_lock();
374 part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); 373 part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
@@ -377,8 +376,6 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
377 376
378 if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) 377 if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
379 wake_up(&mddev->sb_wait); 378 wake_up(&mddev->sb_wait);
380
381 return rv;
382} 379}
383 380
384/* mddev_suspend makes sure no new requests are submitted 381/* mddev_suspend makes sure no new requests are submitted
@@ -477,8 +474,7 @@ static void md_submit_flush_data(struct work_struct *ws)
477 bio_endio(bio, 0); 474 bio_endio(bio, 0);
478 else { 475 else {
479 bio->bi_rw &= ~REQ_FLUSH; 476 bio->bi_rw &= ~REQ_FLUSH;
480 if (mddev->pers->make_request(mddev, bio)) 477 mddev->pers->make_request(mddev, bio);
481 generic_make_request(bio);
482 } 478 }
483 479
484 mddev->flush_bio = NULL; 480 mddev->flush_bio = NULL;
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 51c1d91557e0..cf742d9306ec 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -419,7 +419,7 @@ struct md_personality
419 int level; 419 int level;
420 struct list_head list; 420 struct list_head list;
421 struct module *owner; 421 struct module *owner;
422 int (*make_request)(struct mddev *mddev, struct bio *bio); 422 void (*make_request)(struct mddev *mddev, struct bio *bio);
423 int (*run)(struct mddev *mddev); 423 int (*run)(struct mddev *mddev);
424 int (*stop)(struct mddev *mddev); 424 int (*stop)(struct mddev *mddev);
425 void (*status)(struct seq_file *seq, struct mddev *mddev); 425 void (*status)(struct seq_file *seq, struct mddev *mddev);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index d32c785e17d4..ad20a28fbf2a 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -106,7 +106,7 @@ static void multipath_end_request(struct bio *bio, int error)
106 rdev_dec_pending(rdev, conf->mddev); 106 rdev_dec_pending(rdev, conf->mddev);
107} 107}
108 108
109static int multipath_make_request(struct mddev *mddev, struct bio * bio) 109static void multipath_make_request(struct mddev *mddev, struct bio * bio)
110{ 110{
111 struct mpconf *conf = mddev->private; 111 struct mpconf *conf = mddev->private;
112 struct multipath_bh * mp_bh; 112 struct multipath_bh * mp_bh;
@@ -114,7 +114,7 @@ static int multipath_make_request(struct mddev *mddev, struct bio * bio)
114 114
115 if (unlikely(bio->bi_rw & REQ_FLUSH)) { 115 if (unlikely(bio->bi_rw & REQ_FLUSH)) {
116 md_flush_request(mddev, bio); 116 md_flush_request(mddev, bio);
117 return 0; 117 return;
118 } 118 }
119 119
120 mp_bh = mempool_alloc(conf->pool, GFP_NOIO); 120 mp_bh = mempool_alloc(conf->pool, GFP_NOIO);
@@ -126,7 +126,7 @@ static int multipath_make_request(struct mddev *mddev, struct bio * bio)
126 if (mp_bh->path < 0) { 126 if (mp_bh->path < 0) {
127 bio_endio(bio, -EIO); 127 bio_endio(bio, -EIO);
128 mempool_free(mp_bh, conf->pool); 128 mempool_free(mp_bh, conf->pool);
129 return 0; 129 return;
130 } 130 }
131 multipath = conf->multipaths + mp_bh->path; 131 multipath = conf->multipaths + mp_bh->path;
132 132
@@ -137,7 +137,7 @@ static int multipath_make_request(struct mddev *mddev, struct bio * bio)
137 mp_bh->bio.bi_end_io = multipath_end_request; 137 mp_bh->bio.bi_end_io = multipath_end_request;
138 mp_bh->bio.bi_private = mp_bh; 138 mp_bh->bio.bi_private = mp_bh;
139 generic_make_request(&mp_bh->bio); 139 generic_make_request(&mp_bh->bio);
140 return 0; 140 return;
141} 141}
142 142
143static void multipath_status (struct seq_file *seq, struct mddev *mddev) 143static void multipath_status (struct seq_file *seq, struct mddev *mddev)
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 0eb08a4df759..27e19e2b51d4 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -468,7 +468,7 @@ static inline int is_io_in_chunk_boundary(struct mddev *mddev,
468 } 468 }
469} 469}
470 470
471static int raid0_make_request(struct mddev *mddev, struct bio *bio) 471static void raid0_make_request(struct mddev *mddev, struct bio *bio)
472{ 472{
473 unsigned int chunk_sects; 473 unsigned int chunk_sects;
474 sector_t sector_offset; 474 sector_t sector_offset;
@@ -477,7 +477,7 @@ static int raid0_make_request(struct mddev *mddev, struct bio *bio)
477 477
478 if (unlikely(bio->bi_rw & REQ_FLUSH)) { 478 if (unlikely(bio->bi_rw & REQ_FLUSH)) {
479 md_flush_request(mddev, bio); 479 md_flush_request(mddev, bio);
480 return 0; 480 return;
481 } 481 }
482 482
483 chunk_sects = mddev->chunk_sectors; 483 chunk_sects = mddev->chunk_sectors;
@@ -497,13 +497,10 @@ static int raid0_make_request(struct mddev *mddev, struct bio *bio)
497 else 497 else
498 bp = bio_split(bio, chunk_sects - 498 bp = bio_split(bio, chunk_sects -
499 sector_div(sector, chunk_sects)); 499 sector_div(sector, chunk_sects));
500 if (raid0_make_request(mddev, &bp->bio1)) 500 raid0_make_request(mddev, &bp->bio1);
501 generic_make_request(&bp->bio1); 501 raid0_make_request(mddev, &bp->bio2);
502 if (raid0_make_request(mddev, &bp->bio2))
503 generic_make_request(&bp->bio2);
504
505 bio_pair_release(bp); 502 bio_pair_release(bp);
506 return 0; 503 return;
507 } 504 }
508 505
509 sector_offset = bio->bi_sector; 506 sector_offset = bio->bi_sector;
@@ -513,10 +510,9 @@ static int raid0_make_request(struct mddev *mddev, struct bio *bio)
513 bio->bi_bdev = tmp_dev->bdev; 510 bio->bi_bdev = tmp_dev->bdev;
514 bio->bi_sector = sector_offset + zone->dev_start + 511 bio->bi_sector = sector_offset + zone->dev_start +
515 tmp_dev->data_offset; 512 tmp_dev->data_offset;
516 /* 513
517 * Let the main block layer submit the IO and resolve recursion: 514 generic_make_request(bio);
518 */ 515 return;
519 return 1;
520 516
521bad_map: 517bad_map:
522 printk("md/raid0:%s: make_request bug: can't convert block across chunks" 518 printk("md/raid0:%s: make_request bug: can't convert block across chunks"
@@ -525,7 +521,7 @@ bad_map:
525 (unsigned long long)bio->bi_sector, bio->bi_size >> 10); 521 (unsigned long long)bio->bi_sector, bio->bi_size >> 10);
526 522
527 bio_io_error(bio); 523 bio_io_error(bio);
528 return 0; 524 return;
529} 525}
530 526
531static void raid0_status(struct seq_file *seq, struct mddev *mddev) 527static void raid0_status(struct seq_file *seq, struct mddev *mddev)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4602fc57c961..cae874646d9e 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -807,7 +807,7 @@ do_sync_io:
807 pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); 807 pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
808} 808}
809 809
810static int make_request(struct mddev *mddev, struct bio * bio) 810static void make_request(struct mddev *mddev, struct bio * bio)
811{ 811{
812 struct r1conf *conf = mddev->private; 812 struct r1conf *conf = mddev->private;
813 struct mirror_info *mirror; 813 struct mirror_info *mirror;
@@ -892,7 +892,7 @@ read_again:
892 if (rdisk < 0) { 892 if (rdisk < 0) {
893 /* couldn't find anywhere to read from */ 893 /* couldn't find anywhere to read from */
894 raid_end_bio_io(r1_bio); 894 raid_end_bio_io(r1_bio);
895 return 0; 895 return;
896 } 896 }
897 mirror = conf->mirrors + rdisk; 897 mirror = conf->mirrors + rdisk;
898 898
@@ -950,7 +950,7 @@ read_again:
950 goto read_again; 950 goto read_again;
951 } else 951 } else
952 generic_make_request(read_bio); 952 generic_make_request(read_bio);
953 return 0; 953 return;
954 } 954 }
955 955
956 /* 956 /*
@@ -1151,8 +1151,6 @@ read_again:
1151 1151
1152 if (do_sync || !bitmap || !plugged) 1152 if (do_sync || !bitmap || !plugged)
1153 md_wakeup_thread(mddev->thread); 1153 md_wakeup_thread(mddev->thread);
1154
1155 return 0;
1156} 1154}
1157 1155
1158static void status(struct seq_file *seq, struct mddev *mddev) 1156static void status(struct seq_file *seq, struct mddev *mddev)
@@ -2193,7 +2191,6 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp
2193 bio->bi_next = NULL; 2191 bio->bi_next = NULL;
2194 bio->bi_flags &= ~(BIO_POOL_MASK-1); 2192 bio->bi_flags &= ~(BIO_POOL_MASK-1);
2195 bio->bi_flags |= 1 << BIO_UPTODATE; 2193 bio->bi_flags |= 1 << BIO_UPTODATE;
2196 bio->bi_comp_cpu = -1;
2197 bio->bi_rw = READ; 2194 bio->bi_rw = READ;
2198 bio->bi_vcnt = 0; 2195 bio->bi_vcnt = 0;
2199 bio->bi_idx = 0; 2196 bio->bi_idx = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c025a8276dc1..dde6dd4b47ec 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -842,7 +842,7 @@ static void unfreeze_array(struct r10conf *conf)
842 spin_unlock_irq(&conf->resync_lock); 842 spin_unlock_irq(&conf->resync_lock);
843} 843}
844 844
845static int make_request(struct mddev *mddev, struct bio * bio) 845static void make_request(struct mddev *mddev, struct bio * bio)
846{ 846{
847 struct r10conf *conf = mddev->private; 847 struct r10conf *conf = mddev->private;
848 struct mirror_info *mirror; 848 struct mirror_info *mirror;
@@ -861,7 +861,7 @@ static int make_request(struct mddev *mddev, struct bio * bio)
861 861
862 if (unlikely(bio->bi_rw & REQ_FLUSH)) { 862 if (unlikely(bio->bi_rw & REQ_FLUSH)) {
863 md_flush_request(mddev, bio); 863 md_flush_request(mddev, bio);
864 return 0; 864 return;
865 } 865 }
866 866
867 /* If this request crosses a chunk boundary, we need to 867 /* If this request crosses a chunk boundary, we need to
@@ -893,10 +893,8 @@ static int make_request(struct mddev *mddev, struct bio * bio)
893 conf->nr_waiting++; 893 conf->nr_waiting++;
894 spin_unlock_irq(&conf->resync_lock); 894 spin_unlock_irq(&conf->resync_lock);
895 895
896 if (make_request(mddev, &bp->bio1)) 896 make_request(mddev, &bp->bio1);
897 generic_make_request(&bp->bio1); 897 make_request(mddev, &bp->bio2);
898 if (make_request(mddev, &bp->bio2))
899 generic_make_request(&bp->bio2);
900 898
901 spin_lock_irq(&conf->resync_lock); 899 spin_lock_irq(&conf->resync_lock);
902 conf->nr_waiting--; 900 conf->nr_waiting--;
@@ -904,14 +902,14 @@ static int make_request(struct mddev *mddev, struct bio * bio)
904 spin_unlock_irq(&conf->resync_lock); 902 spin_unlock_irq(&conf->resync_lock);
905 903
906 bio_pair_release(bp); 904 bio_pair_release(bp);
907 return 0; 905 return;
908 bad_map: 906 bad_map:
909 printk("md/raid10:%s: make_request bug: can't convert block across chunks" 907 printk("md/raid10:%s: make_request bug: can't convert block across chunks"
910 " or bigger than %dk %llu %d\n", mdname(mddev), chunk_sects/2, 908 " or bigger than %dk %llu %d\n", mdname(mddev), chunk_sects/2,
911 (unsigned long long)bio->bi_sector, bio->bi_size >> 10); 909 (unsigned long long)bio->bi_sector, bio->bi_size >> 10);
912 910
913 bio_io_error(bio); 911 bio_io_error(bio);
914 return 0; 912 return;
915 } 913 }
916 914
917 md_write_start(mddev, bio); 915 md_write_start(mddev, bio);
@@ -954,7 +952,7 @@ read_again:
954 slot = r10_bio->read_slot; 952 slot = r10_bio->read_slot;
955 if (disk < 0) { 953 if (disk < 0) {
956 raid_end_bio_io(r10_bio); 954 raid_end_bio_io(r10_bio);
957 return 0; 955 return;
958 } 956 }
959 mirror = conf->mirrors + disk; 957 mirror = conf->mirrors + disk;
960 958
@@ -1002,7 +1000,7 @@ read_again:
1002 goto read_again; 1000 goto read_again;
1003 } else 1001 } else
1004 generic_make_request(read_bio); 1002 generic_make_request(read_bio);
1005 return 0; 1003 return;
1006 } 1004 }
1007 1005
1008 /* 1006 /*
@@ -1176,7 +1174,6 @@ retry_write:
1176 1174
1177 if (do_sync || !mddev->bitmap || !plugged) 1175 if (do_sync || !mddev->bitmap || !plugged)
1178 md_wakeup_thread(mddev->thread); 1176 md_wakeup_thread(mddev->thread);
1179 return 0;
1180} 1177}
1181 1178
1182static void status(struct seq_file *seq, struct mddev *mddev) 1179static void status(struct seq_file *seq, struct mddev *mddev)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index f6fe053a5bed..bb1b46143fb6 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3688,7 +3688,7 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf)
3688 return sh; 3688 return sh;
3689} 3689}
3690 3690
3691static int make_request(struct mddev *mddev, struct bio * bi) 3691static void make_request(struct mddev *mddev, struct bio * bi)
3692{ 3692{
3693 struct r5conf *conf = mddev->private; 3693 struct r5conf *conf = mddev->private;
3694 int dd_idx; 3694 int dd_idx;
@@ -3701,7 +3701,7 @@ static int make_request(struct mddev *mddev, struct bio * bi)
3701 3701
3702 if (unlikely(bi->bi_rw & REQ_FLUSH)) { 3702 if (unlikely(bi->bi_rw & REQ_FLUSH)) {
3703 md_flush_request(mddev, bi); 3703 md_flush_request(mddev, bi);
3704 return 0; 3704 return;
3705 } 3705 }
3706 3706
3707 md_write_start(mddev, bi); 3707 md_write_start(mddev, bi);
@@ -3709,7 +3709,7 @@ static int make_request(struct mddev *mddev, struct bio * bi)
3709 if (rw == READ && 3709 if (rw == READ &&
3710 mddev->reshape_position == MaxSector && 3710 mddev->reshape_position == MaxSector &&
3711 chunk_aligned_read(mddev,bi)) 3711 chunk_aligned_read(mddev,bi))
3712 return 0; 3712 return;
3713 3713
3714 logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1); 3714 logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
3715 last_sector = bi->bi_sector + (bi->bi_size>>9); 3715 last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3844,8 +3844,6 @@ static int make_request(struct mddev *mddev, struct bio * bi)
3844 3844
3845 bio_endio(bi, 0); 3845 bio_endio(bi, 0);
3846 } 3846 }
3847
3848 return 0;
3849} 3847}
3850 3848
3851static sector_t raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks); 3849static sector_t raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks);
diff --git a/drivers/media/dvb/ddbridge/Makefile b/drivers/media/dvb/ddbridge/Makefile
index cf7214edf65f..38019bafb862 100644
--- a/drivers/media/dvb/ddbridge/Makefile
+++ b/drivers/media/dvb/ddbridge/Makefile
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
11ccflags-y += -Idrivers/media/common/tuners/ 11ccflags-y += -Idrivers/media/common/tuners/
12 12
13# For the staging CI driver cxd2099 13# For the staging CI driver cxd2099
14ccflags-y += -Idrivers/staging/cxd2099/ 14ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 7d0710bb1978..26c8b9e57050 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
102 102
103dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o 103dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
104obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o 104obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
105obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
105obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o 106obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
106 107
107ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 108ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 2ad33ba92ba2..2d08c9b5128a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -37,6 +37,7 @@
37#define USB_VID_HAUPPAUGE 0x2040 37#define USB_VID_HAUPPAUGE 0x2040
38#define USB_VID_HYPER_PALTEK 0x1025 38#define USB_VID_HYPER_PALTEK 0x1025
39#define USB_VID_INTEL 0x8086 39#define USB_VID_INTEL 0x8086
40#define USB_VID_ITETECH 0x048d
40#define USB_VID_KWORLD 0xeb2a 41#define USB_VID_KWORLD 0xeb2a
41#define USB_VID_KWORLD_2 0x1b80 42#define USB_VID_KWORLD_2 0x1b80
42#define USB_VID_KYE 0x0458 43#define USB_VID_KYE 0x0458
@@ -126,6 +127,7 @@
126#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 127#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
127#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 128#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
128#define USB_PID_INTEL_CE9500 0x9500 129#define USB_PID_INTEL_CE9500 0x9500
130#define USB_PID_ITETECH_IT9135 0x9135
129#define USB_PID_KWORLD_399U 0xe399 131#define USB_PID_KWORLD_399U 0xe399
130#define USB_PID_KWORLD_399U_2 0xe400 132#define USB_PID_KWORLD_399U_2 0xe400
131#define USB_PID_KWORLD_395U 0xe396 133#define USB_PID_KWORLD_395U 0xe396
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index f027a2c1c3e8..c46226187143 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -60,6 +60,17 @@ struct it913x_state {
60 u8 id; 60 u8 id;
61}; 61};
62 62
63struct ite_config {
64 u8 chip_ver;
65 u16 chip_type;
66 u32 firmware;
67 u8 tuner_id_0;
68 u8 tuner_id_1;
69 u8 dual_mode;
70};
71
72struct ite_config it913x_config;
73
63static int it913x_bulk_write(struct usb_device *dev, 74static int it913x_bulk_write(struct usb_device *dev,
64 u8 *snd, int len, u8 pipe) 75 u8 *snd, int len, u8 pipe)
65{ 76{
@@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
191static u32 it913x_query(struct usb_device *udev, u8 pro) 202static u32 it913x_query(struct usb_device *udev, u8 pro)
192{ 203{
193 int ret; 204 int ret;
194 u32 res = 0;
195 u8 data[4]; 205 u8 data[4];
196 ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, 206 ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
197 0x1222, 0, &data[0], 1); 207 0x1222, 0, &data[0], 3);
198 if (data[0] == 0x1) { 208
199 ret = it913x_io(udev, READ_SHORT, pro, 209 it913x_config.chip_ver = data[0];
210 it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
211
212 info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
213 it913x_config.chip_type);
214
215 ret |= it913x_io(udev, READ_SHORT, pro,
200 CMD_QUERYINFO, 0, 0x1, &data[0], 4); 216 CMD_QUERYINFO, 0, 0x1, &data[0], 4);
201 res = (data[0] << 24) + (data[1] << 16) + 217
218 it913x_config.firmware = (data[0] << 24) + (data[1] << 16) +
202 (data[2] << 8) + data[3]; 219 (data[2] << 8) + data[3];
203 }
204 220
205 return (ret < 0) ? 0 : res; 221 return (ret < 0) ? 0 : it913x_config.firmware;
206} 222}
207 223
208static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 224static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
@@ -336,26 +352,35 @@ static int it913x_identify_state(struct usb_device *udev,
336 int *cold) 352 int *cold)
337{ 353{
338 int ret = 0, firm_no; 354 int ret = 0, firm_no;
339 u8 reg, adap, ep, tun0, tun1; 355 u8 reg, remote;
340 356
341 firm_no = it913x_return_status(udev); 357 firm_no = it913x_return_status(udev);
342 358
343 ep = it913x_read_reg(udev, 0x49ac); 359 /* checnk for dual mode */
344 adap = it913x_read_reg(udev, 0x49c5); 360 it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5);
345 tun0 = it913x_read_reg(udev, 0x49d0); 361
346 info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0); 362 /* TODO different remotes */
363 remote = it913x_read_reg(udev, 0x49ac); /* Remote */
364 if (remote == 0)
365 props->rc.core.rc_codes = NULL;
366
367 /* TODO at the moment tuner_id is always assigned to 0x38 */
368 it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
369
370 info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
371 , remote, it913x_config.tuner_id_0);
347 372
348 if (firm_no > 0) { 373 if (firm_no > 0) {
349 *cold = 0; 374 *cold = 0;
350 return 0; 375 return 0;
351 } 376 }
352 377
353 if (adap > 2) { 378 if (it913x_config.dual_mode) {
354 tun1 = it913x_read_reg(udev, 0x49e0); 379 it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0);
355 ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1); 380 ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1);
356 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1); 381 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1);
357 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1); 382 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
358 msleep(50); /* Delay noticed reset cycle ? */ 383 msleep(50);
359 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); 384 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0);
360 msleep(50); 385 msleep(50);
361 reg = it913x_read_reg(udev, GPIOH1_O); 386 reg = it913x_read_reg(udev, GPIOH1_O);
@@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev,
366 ret = it913x_wr_reg(udev, DEV_0, 391 ret = it913x_wr_reg(udev, DEV_0,
367 GPIOH1_O, 0x0); 392 GPIOH1_O, 0x0);
368 } 393 }
394 props->num_adapters = 2;
369 } else 395 } else
370 props->num_adapters = 1; 396 props->num_adapters = 1;
371 397
372 reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); 398 reg = it913x_read_reg(udev, IO_MUX_POWER_CLK);
373 399
374 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); 400 if (it913x_config.dual_mode) {
375 401 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
376 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); 402 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1);
403 } else {
404 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
405 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0);
406 }
377 407
378 *cold = 1; 408 *cold = 1;
379 409
@@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev,
403 const struct firmware *fw) 433 const struct firmware *fw)
404{ 434{
405 int ret = 0, i; 435 int ret = 0, i;
406 u8 packet_size, dlen, tun1; 436 u8 packet_size, dlen;
407 u8 *fw_data; 437 u8 *fw_data;
408 438
409 packet_size = 0x29; 439 packet_size = 0x29;
410 440
411 tun1 = it913x_read_reg(udev, 0x49e0);
412
413 ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); 441 ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100);
414 442
415 info("FRM Starting Firmware Download"); 443 info("FRM Starting Firmware Download");
@@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev,
444 ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); 472 ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
445 473
446 /* Tuner function */ 474 /* Tuner function */
447 ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); 475 if (it913x_config.dual_mode)
476 ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
448 477
449 ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); 478 ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0);
450 ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); 479 ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0);
451 if (tun1 > 0) { 480 if (it913x_config.dual_mode) {
452 ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); 481 ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0);
453 ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); 482 ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0);
454 } 483 }
@@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
475 u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); 504 u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
476 u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); 505 u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
477 u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; 506 u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize;
507 u8 tuner_id, tuner_type;
508
509 if (adap->id == 0)
510 tuner_id = it913x_config.tuner_id_0;
511 else
512 tuner_id = it913x_config.tuner_id_1;
513
514 /* TODO we always use IT9137 possible references here*/
515 /* Documentation suggests don't care */
516 switch (tuner_id) {
517 case 0x51:
518 case 0x52:
519 case 0x60:
520 case 0x61:
521 case 0x62:
522 default:
523 case 0x38:
524 tuner_type = IT9137;
525 }
478 526
479 adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, 527 adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
480 &adap->dev->i2c_adap, adap_addr, adf, IT9137); 528 &adap->dev->i2c_adap, adap_addr, adf, tuner_type);
481 529
482 if (adap->id == 0 && adap->fe_adap[0].fe) { 530 if (adap->id == 0 && adap->fe_adap[0].fe) {
483 ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); 531 ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
@@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf,
533 581
534static struct usb_device_id it913x_table[] = { 582static struct usb_device_id it913x_table[] = {
535 { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, 583 { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
584 { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
536 {} /* Terminating entry */ 585 {} /* Terminating entry */
537}; 586};
538 587
@@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = {
608 .rc_codes = RC_MAP_KWORLD_315U, 657 .rc_codes = RC_MAP_KWORLD_315U,
609 }, 658 },
610 .i2c_algo = &it913x_i2c_algo, 659 .i2c_algo = &it913x_i2c_algo,
611 .num_device_descs = 1, 660 .num_device_descs = 2,
612 .devices = { 661 .devices = {
613 { "Kworld UB499-2T T09(IT9137)", 662 { "Kworld UB499-2T T09(IT9137)",
614 { &it913x_table[0], NULL }, 663 { &it913x_table[0], NULL },
615 }, 664 },
616 665 { "ITE 9135 Generic",
666 { &it913x_table[1], NULL },
667 },
617 } 668 }
618}; 669};
619 670
@@ -647,5 +698,5 @@ module_exit(it913x_module_exit);
647 698
648MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 699MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
649MODULE_DESCRIPTION("it913x USB 2 Driver"); 700MODULE_DESCRIPTION("it913x USB 2 Driver");
650MODULE_VERSION("1.06"); 701MODULE_VERSION("1.07");
651MODULE_LICENSE("GPL"); 702MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
new file mode 100644
index 000000000000..d1f58371c711
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
@@ -0,0 +1,614 @@
1/*
2 * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-demod.h"
22#include "mxl111sf-reg.h"
23
24/* debug */
25static int mxl111sf_demod_debug;
26module_param_named(debug, mxl111sf_demod_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
28
29#define mxl_dbg(fmt, arg...) \
30 if (mxl111sf_demod_debug) \
31 mxl_printk(KERN_DEBUG, fmt, ##arg)
32
33/* ------------------------------------------------------------------------ */
34
35struct mxl111sf_demod_state {
36 struct mxl111sf_state *mxl_state;
37
38 struct mxl111sf_demod_config *cfg;
39
40 struct dvb_frontend fe;
41};
42
43/* ------------------------------------------------------------------------ */
44
45static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
46 u8 addr, u8 *data)
47{
48 return (state->cfg->read_reg) ?
49 state->cfg->read_reg(state->mxl_state, addr, data) :
50 -EINVAL;
51}
52
53static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
54 u8 addr, u8 data)
55{
56 return (state->cfg->write_reg) ?
57 state->cfg->write_reg(state->mxl_state, addr, data) :
58 -EINVAL;
59}
60
61static
62int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
63 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
64{
65 return (state->cfg->program_regs) ?
66 state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
67 -EINVAL;
68}
69
70/* ------------------------------------------------------------------------ */
71/* TPS */
72
73static
74int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
75 fe_code_rate_t *code_rate)
76{
77 u8 val;
78 int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
79 /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
80 if (mxl_fail(ret))
81 goto fail;
82
83 switch (val & V6_CODE_RATE_TPS_MASK) {
84 case 0:
85 *code_rate = FEC_1_2;
86 break;
87 case 1:
88 *code_rate = FEC_2_3;
89 break;
90 case 2:
91 *code_rate = FEC_3_4;
92 break;
93 case 3:
94 *code_rate = FEC_5_6;
95 break;
96 case 4:
97 *code_rate = FEC_7_8;
98 break;
99 }
100fail:
101 return ret;
102}
103
104static
105int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state,
106 fe_modulation_t *constellation)
107{
108 u8 val;
109 int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
110 /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
111 if (mxl_fail(ret))
112 goto fail;
113
114 switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
115 case 0:
116 *constellation = QPSK;
117 break;
118 case 1:
119 *constellation = QAM_16;
120 break;
121 case 2:
122 *constellation = QAM_64;
123 break;
124 }
125fail:
126 return ret;
127}
128
129static
130int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
131 fe_transmit_mode_t *fft_mode)
132{
133 u8 val;
134 int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
135 /* FFT Mode, 00:2K, 01:8K, 10:4K */
136 if (mxl_fail(ret))
137 goto fail;
138
139 switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
140 case 0:
141 *fft_mode = TRANSMISSION_MODE_2K;
142 break;
143 case 1:
144 *fft_mode = TRANSMISSION_MODE_8K;
145 break;
146 case 2:
147 *fft_mode = TRANSMISSION_MODE_4K;
148 break;
149 }
150fail:
151 return ret;
152}
153
154static
155int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
156 fe_guard_interval_t *guard)
157{
158 u8 val;
159 int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
160 /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
161 if (mxl_fail(ret))
162 goto fail;
163
164 switch ((val & V6_PARAM_GI_MASK) >> 4) {
165 case 0:
166 *guard = GUARD_INTERVAL_1_32;
167 break;
168 case 1:
169 *guard = GUARD_INTERVAL_1_16;
170 break;
171 case 2:
172 *guard = GUARD_INTERVAL_1_8;
173 break;
174 case 3:
175 *guard = GUARD_INTERVAL_1_4;
176 break;
177 }
178fail:
179 return ret;
180}
181
182static
183int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
184 fe_hierarchy_t *hierarchy)
185{
186 u8 val;
187 int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
188 /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
189 if (mxl_fail(ret))
190 goto fail;
191
192 switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
193 case 0:
194 *hierarchy = HIERARCHY_NONE;
195 break;
196 case 1:
197 *hierarchy = HIERARCHY_1;
198 break;
199 case 2:
200 *hierarchy = HIERARCHY_2;
201 break;
202 case 3:
203 *hierarchy = HIERARCHY_4;
204 break;
205 }
206fail:
207 return ret;
208}
209
210/* ------------------------------------------------------------------------ */
211/* LOCKS */
212
213static
214int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
215 int *sync_lock)
216{
217 u8 val = 0;
218 int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
219 if (mxl_fail(ret))
220 goto fail;
221 *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
222fail:
223 return ret;
224}
225
226static
227int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
228 int *rs_lock)
229{
230 u8 val = 0;
231 int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
232 if (mxl_fail(ret))
233 goto fail;
234 *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
235fail:
236 return ret;
237}
238
239static
240int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
241 int *tps_lock)
242{
243 u8 val = 0;
244 int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
245 if (mxl_fail(ret))
246 goto fail;
247 *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
248fail:
249 return ret;
250}
251
252static
253int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
254 int *fec_lock)
255{
256 u8 val = 0;
257 int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
258 if (mxl_fail(ret))
259 goto fail;
260 *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
261fail:
262 return ret;
263}
264
265#if 0
266static
267int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
268 int *cp_lock)
269{
270 u8 val = 0;
271 int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
272 if (mxl_fail(ret))
273 goto fail;
274 *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
275fail:
276 return ret;
277}
278#endif
279
280static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
281{
282 return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
283}
284
285/* ------------------------------------------------------------------------ */
286
287static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe,
288 struct dvb_frontend_parameters *param)
289{
290 struct mxl111sf_demod_state *state = fe->demodulator_priv;
291 int ret = 0;
292
293 struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
294 {0x00, 0xff, 0x01}, /* change page to 1 */
295 {0x40, 0xff, 0x05},
296 {0x40, 0xff, 0x01},
297 {0x41, 0xff, 0xca},
298 {0x41, 0xff, 0xc0},
299 {0x00, 0xff, 0x00}, /* change page to 0 */
300 {0, 0, 0}
301 };
302
303 mxl_dbg("()");
304
305 if (fe->ops.tuner_ops.set_params) {
306 ret = fe->ops.tuner_ops.set_params(fe, param);
307 if (mxl_fail(ret))
308 goto fail;
309 msleep(50);
310 }
311 ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
312 mxl_fail(ret);
313 msleep(50);
314 ret = mxl1x1sf_demod_reset_irq_status(state);
315 mxl_fail(ret);
316 msleep(100);
317fail:
318 return ret;
319}
320
321/* ------------------------------------------------------------------------ */
322
323#if 0
324/* resets TS Packet error count */
325/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
326static
327int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
328{
329 struct mxl111sf_reg_ctrl_info reset_per_count[] = {
330 {0x20, 0x01, 0x01},
331 {0x20, 0x01, 0x00},
332 {0, 0, 0}
333 };
334 return mxl111sf_demod_program_regs(state, reset_per_count);
335}
336#endif
337
338/* returns TS Packet error count */
339/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
340static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
341{
342 struct mxl111sf_demod_state *state = fe->demodulator_priv;
343 u32 fec_per_count, fec_per_scale;
344 u8 val;
345 int ret;
346
347 *ucblocks = 0;
348
349 /* FEC_PER_COUNT Register */
350 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
351 if (mxl_fail(ret))
352 goto fail;
353
354 fec_per_count = val;
355
356 /* FEC_PER_SCALE Register */
357 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
358 if (mxl_fail(ret))
359 goto fail;
360
361 val &= V6_FEC_PER_SCALE_MASK;
362 val *= 4;
363
364 fec_per_scale = 1 << val;
365
366 fec_per_count *= fec_per_scale;
367
368 *ucblocks = fec_per_count;
369fail:
370 return ret;
371}
372
373#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
374/* FIXME: leaving this enabled breaks the build on some architectures,
375 * and we shouldn't have any floating point math in the kernel, anyway.
376 *
377 * These macros need to be re-written, but it's harmless to simply
378 * return zero for now. */
379#define CALCULATE_BER(avg_errors, count) \
380 ((u32)(avg_errors * 4)/(count*64*188*8))
381#define CALCULATE_SNR(data) \
382 ((u32)((10 * (u32)data / 64) - 2.5))
383#else
384#define CALCULATE_BER(avg_errors, count) 0
385#define CALCULATE_SNR(data) 0
386#endif
387
388static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
389{
390 struct mxl111sf_demod_state *state = fe->demodulator_priv;
391 u8 val1, val2, val3;
392 int ret;
393
394 *ber = 0;
395
396 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
397 if (mxl_fail(ret))
398 goto fail;
399 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
400 if (mxl_fail(ret))
401 goto fail;
402 ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
403 if (mxl_fail(ret))
404 goto fail;
405
406 *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
407fail:
408 return ret;
409}
410
411static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
412 u16 *snr)
413{
414 u8 val1, val2;
415 int ret;
416
417 *snr = 0;
418
419 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
420 if (mxl_fail(ret))
421 goto fail;
422 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
423 if (mxl_fail(ret))
424 goto fail;
425
426 *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
427fail:
428 return ret;
429}
430
431static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
432{
433 struct mxl111sf_demod_state *state = fe->demodulator_priv;
434
435 int ret = mxl111sf_demod_calc_snr(state, snr);
436 if (mxl_fail(ret))
437 goto fail;
438
439 *snr /= 10; /* 0.1 dB */
440fail:
441 return ret;
442}
443
444static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
445 fe_status_t *status)
446{
447 struct mxl111sf_demod_state *state = fe->demodulator_priv;
448 int ret, locked, cr_lock, sync_lock, fec_lock;
449
450 *status = 0;
451
452 ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
453 if (mxl_fail(ret))
454 goto fail;
455 ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
456 if (mxl_fail(ret))
457 goto fail;
458 ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
459 if (mxl_fail(ret))
460 goto fail;
461 ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
462 if (mxl_fail(ret))
463 goto fail;
464
465 if (locked)
466 *status |= FE_HAS_SIGNAL;
467 if (cr_lock)
468 *status |= FE_HAS_CARRIER;
469 if (sync_lock)
470 *status |= FE_HAS_SYNC;
471 if (fec_lock) /* false positives? */
472 *status |= FE_HAS_VITERBI;
473
474 if ((locked) && (cr_lock) && (sync_lock))
475 *status |= FE_HAS_LOCK;
476fail:
477 return ret;
478}
479
480static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
481 u16 *signal_strength)
482{
483 struct mxl111sf_demod_state *state = fe->demodulator_priv;
484 fe_modulation_t constellation;
485 u16 snr;
486
487 mxl111sf_demod_calc_snr(state, &snr);
488 mxl1x1sf_demod_get_tps_constellation(state, &constellation);
489
490 switch (constellation) {
491 case QPSK:
492 *signal_strength = (snr >= 1300) ?
493 min(65535, snr * 44) : snr * 38;
494 break;
495 case QAM_16:
496 *signal_strength = (snr >= 1500) ?
497 min(65535, snr * 38) : snr * 33;
498 break;
499 case QAM_64:
500 *signal_strength = (snr >= 2000) ?
501 min(65535, snr * 29) : snr * 25;
502 break;
503 default:
504 *signal_strength = 0;
505 return -EINVAL;
506 }
507
508 return 0;
509}
510
511static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe,
512 struct dvb_frontend_parameters *p)
513{
514 struct mxl111sf_demod_state *state = fe->demodulator_priv;
515
516 mxl_dbg("()");
517#if 0
518 p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
519#endif
520 if (fe->ops.tuner_ops.get_bandwidth)
521 fe->ops.tuner_ops.get_bandwidth(fe, &p->u.ofdm.bandwidth);
522 if (fe->ops.tuner_ops.get_frequency)
523 fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
524 mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_HP);
525 mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_LP);
526 mxl1x1sf_demod_get_tps_constellation(state, &p->u.ofdm.constellation);
527 mxl1x1sf_demod_get_tps_guard_fft_mode(state,
528 &p->u.ofdm.transmission_mode);
529 mxl1x1sf_demod_get_tps_guard_interval(state,
530 &p->u.ofdm.guard_interval);
531 mxl1x1sf_demod_get_tps_hierarchy(state,
532 &p->u.ofdm.hierarchy_information);
533
534 return 0;
535}
536
537static
538int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
539 struct dvb_frontend_tune_settings *tune)
540{
541 tune->min_delay_ms = 1000;
542 return 0;
543}
544
545static void mxl111sf_demod_release(struct dvb_frontend *fe)
546{
547 struct mxl111sf_demod_state *state = fe->demodulator_priv;
548 mxl_dbg("()");
549 kfree(state);
550 fe->demodulator_priv = NULL;
551}
552
553static struct dvb_frontend_ops mxl111sf_demod_ops = {
554
555 .info = {
556 .name = "MaxLinear MxL111SF DVB-T demodulator",
557 .type = FE_OFDM,
558 .frequency_min = 177000000,
559 .frequency_max = 858000000,
560 .frequency_stepsize = 166666,
561 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
562 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
563 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
564 FE_CAN_QAM_AUTO |
565 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
566 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
567 },
568 .release = mxl111sf_demod_release,
569#if 0
570 .init = mxl111sf_init,
571 .i2c_gate_ctrl = mxl111sf_i2c_gate_ctrl,
572#endif
573 .set_frontend = mxl111sf_demod_set_frontend,
574 .get_frontend = mxl111sf_demod_get_frontend,
575 .get_tune_settings = mxl111sf_demod_get_tune_settings,
576 .read_status = mxl111sf_demod_read_status,
577 .read_signal_strength = mxl111sf_demod_read_signal_strength,
578 .read_ber = mxl111sf_demod_read_ber,
579 .read_snr = mxl111sf_demod_read_snr,
580 .read_ucblocks = mxl111sf_demod_read_ucblocks,
581};
582
583struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
584 struct mxl111sf_demod_config *cfg)
585{
586 struct mxl111sf_demod_state *state = NULL;
587
588 mxl_dbg("()");
589
590 state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
591 if (state == NULL)
592 return NULL;
593
594 state->mxl_state = mxl_state;
595 state->cfg = cfg;
596
597 memcpy(&state->fe.ops, &mxl111sf_demod_ops,
598 sizeof(struct dvb_frontend_ops));
599
600 state->fe.demodulator_priv = state;
601 return &state->fe;
602}
603EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
604
605MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
606MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
607MODULE_LICENSE("GPL");
608MODULE_VERSION("0.1");
609
610/*
611 * Local variables:
612 * c-basic-offset: 8
613 * End:
614 */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
new file mode 100644
index 000000000000..432706ae5274
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
@@ -0,0 +1,55 @@
1/*
2 * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __MXL111SF_DEMOD_H__
22#define __MXL111SF_DEMOD_H__
23
24#include "dvb_frontend.h"
25#include "mxl111sf.h"
26
27struct mxl111sf_demod_config {
28 int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
29 int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
30 int (*program_regs)(struct mxl111sf_state *state,
31 struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
32};
33
34#if defined(CONFIG_DVB_USB_MXL111SF) || \
35 (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
36extern
37struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
38 struct mxl111sf_demod_config *cfg);
39#else
40static inline
41struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
42 struct mxl111sf_demod_config *cfg)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_USB_MXL111SF */
48
49#endif /* __MXL111SF_DEMOD_H__ */
50
51/*
52 * Local variables:
53 * c-basic-offset: 8
54 * End:
55 */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index 546ba5915a5b..b5c98da5d9e2 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -17,6 +17,7 @@
17#include "mxl111sf-i2c.h" 17#include "mxl111sf-i2c.h"
18#include "mxl111sf-gpio.h" 18#include "mxl111sf-gpio.h"
19 19
20#include "mxl111sf-demod.h"
20#include "mxl111sf-tuner.h" 21#include "mxl111sf-tuner.h"
21 22
22#include "lgdt3305.h" 23#include "lgdt3305.h"
@@ -362,6 +363,22 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
362 return ret; 363 return ret;
363} 364}
364 365
366static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
367{
368 struct dvb_usb_device *d = adap->dev;
369 struct mxl111sf_state *state = d->priv;
370 int ret = 0;
371
372 deb_info("%s(%d)\n", __func__, onoff);
373
374 if (onoff) {
375 ret = mxl111sf_enable_usb_output(state);
376 mxl_fail(ret);
377 }
378
379 return ret;
380}
381
365/* ------------------------------------------------------------------------ */ 382/* ------------------------------------------------------------------------ */
366 383
367static struct lgdt3305_config hauppauge_lgdt3305_config = { 384static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -438,6 +455,70 @@ fail:
438 return ret; 455 return ret;
439} 456}
440 457
458static struct mxl111sf_demod_config mxl_demod_config = {
459 .read_reg = mxl111sf_read_reg,
460 .write_reg = mxl111sf_write_reg,
461 .program_regs = mxl111sf_ctrl_program_regs,
462};
463
464static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
465{
466 struct dvb_usb_device *d = adap->dev;
467 struct mxl111sf_state *state = d->priv;
468 int fe_id = adap->num_frontends_initialized;
469 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
470 int ret;
471
472 deb_adv("%s()\n", __func__);
473
474 /* save a pointer to the dvb_usb_device in device state */
475 state->d = d;
476 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
477 state->alt_mode = adap_state->alt_mode;
478
479 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
480 err("set interface failed");
481
482 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
483 adap_state->gpio_mode = state->gpio_mode;
484 adap_state->device_mode = MXL_SOC_MODE;
485 adap_state->ep6_clockphase = 1;
486
487 ret = mxl1x1sf_soft_reset(state);
488 if (mxl_fail(ret))
489 goto fail;
490 ret = mxl111sf_init_tuner_demod(state);
491 if (mxl_fail(ret))
492 goto fail;
493
494 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
495 if (mxl_fail(ret))
496 goto fail;
497
498 ret = mxl111sf_enable_usb_output(state);
499 if (mxl_fail(ret))
500 goto fail;
501 ret = mxl1x1sf_top_master_ctrl(state, 1);
502 if (mxl_fail(ret))
503 goto fail;
504
505 /* dont care if this fails */
506 mxl111sf_init_port_expander(state);
507
508 adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
509 &mxl_demod_config);
510 if (adap->fe_adap[fe_id].fe) {
511 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
512 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
513 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
514 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
515 return 0;
516 }
517 ret = -EIO;
518fail:
519 return ret;
520}
521
441static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, 522static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
442 int antpath) 523 int antpath)
443{ 524{
@@ -567,7 +648,8 @@ struct i2c_algorithm mxl111sf_i2c_algo = {
567#endif 648#endif
568}; 649};
569 650
570/* DVB USB Driver stuff */ 651static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
652static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
571static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; 653static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
572static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; 654static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
573 655
@@ -580,9 +662,15 @@ static int mxl111sf_probe(struct usb_interface *intf,
580 662
581 if (((dvb_usb_mxl111sf_isoc) && 663 if (((dvb_usb_mxl111sf_isoc) &&
582 (0 == dvb_usb_device_init(intf, 664 (0 == dvb_usb_device_init(intf,
665 &mxl111sf_dvbt_isoc_properties,
666 THIS_MODULE, &d, adapter_nr) ||
667 0 == dvb_usb_device_init(intf,
583 &mxl111sf_atsc_isoc_properties, 668 &mxl111sf_atsc_isoc_properties,
584 THIS_MODULE, &d, adapter_nr))) || 669 THIS_MODULE, &d, adapter_nr))) ||
585 0 == dvb_usb_device_init(intf, 670 0 == dvb_usb_device_init(intf,
671 &mxl111sf_dvbt_bulk_properties,
672 THIS_MODULE, &d, adapter_nr) ||
673 0 == dvb_usb_device_init(intf,
586 &mxl111sf_atsc_bulk_properties, 674 &mxl111sf_atsc_bulk_properties,
587 THIS_MODULE, &d, adapter_nr) || 0) { 675 THIS_MODULE, &d, adapter_nr) || 0) {
588 676
@@ -669,6 +757,36 @@ static struct usb_device_id mxl111sf_table[] = {
669MODULE_DEVICE_TABLE(usb, mxl111sf_table); 757MODULE_DEVICE_TABLE(usb, mxl111sf_table);
670 758
671 759
760#define MXL111SF_EP4_BULK_STREAMING_CONFIG \
761 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
762 .stream = { \
763 .type = USB_BULK, \
764 .count = 5, \
765 .endpoint = 0x04, \
766 .u = { \
767 .bulk = { \
768 .buffersize = 8192, \
769 } \
770 } \
771 }
772
773/* FIXME: works for v6 but not v8 silicon */
774#define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
775 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
776 .stream = { \
777 .type = USB_ISOC, \
778 .count = 5, \
779 .endpoint = 0x04, \
780 .u = { \
781 .isoc = { \
782 .framesperurb = 96, \
783 /* FIXME: v6 SILICON: */ \
784 .framesize = 564, \
785 .interval = 1, \
786 } \
787 } \
788 }
789
672#define MXL111SF_EP6_BULK_STREAMING_CONFIG \ 790#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
673 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ 791 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
674 .stream = { \ 792 .stream = { \
@@ -712,7 +830,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table);
712 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \ 830 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
713 .size_of_priv = sizeof(struct mxl111sf_state) 831 .size_of_priv = sizeof(struct mxl111sf_state)
714 832
715static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { 833static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
716 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 834 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
717 835
718 .num_adapters = 1, 836 .num_adapters = 1,
@@ -723,10 +841,106 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
723 .fe = {{ 841 .fe = {{
724 .size_of_priv = sizeof(struct mxl111sf_adap_state), 842 .size_of_priv = sizeof(struct mxl111sf_adap_state),
725 843
844 .frontend_attach = mxl111sf_attach_demod,
845 .tuner_attach = mxl111sf_attach_tuner,
846
847 MXL111SF_EP4_BULK_STREAMING_CONFIG,
848 } },
849 },
850 },
851 .num_device_descs = 4,
852 .devices = {
853 { "Hauppauge 126xxx DVBT (bulk)",
854 { NULL },
855 { &mxl111sf_table[4], &mxl111sf_table[8],
856 NULL },
857 },
858 { "Hauppauge 117xxx DVBT (bulk)",
859 { NULL },
860 { &mxl111sf_table[15], &mxl111sf_table[18],
861 NULL },
862 },
863 { "Hauppauge 138xxx DVBT (bulk)",
864 { NULL },
865 { &mxl111sf_table[20], &mxl111sf_table[22],
866 &mxl111sf_table[24], &mxl111sf_table[26],
867 NULL },
868 },
869 { "Hauppauge 126xxx (tp-bulk)",
870 { NULL },
871 { &mxl111sf_table[28], &mxl111sf_table[30],
872 NULL },
873 },
874 }
875};
876
877static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
878 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
879
880 .num_adapters = 1,
881 .adapter = {
882 {
883 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
884 .num_frontends = 1,
885 .fe = {{
886 .size_of_priv = sizeof(struct mxl111sf_adap_state),
887
888 .frontend_attach = mxl111sf_attach_demod,
889 .tuner_attach = mxl111sf_attach_tuner,
890
891 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
892 } },
893 },
894 },
895 .num_device_descs = 4,
896 .devices = {
897 { "Hauppauge 126xxx DVBT (isoc)",
898 { NULL },
899 { &mxl111sf_table[4], &mxl111sf_table[8],
900 NULL },
901 },
902 { "Hauppauge 117xxx DVBT (isoc)",
903 { NULL },
904 { &mxl111sf_table[15], &mxl111sf_table[18],
905 NULL },
906 },
907 { "Hauppauge 138xxx DVBT (isoc)",
908 { NULL },
909 { &mxl111sf_table[20], &mxl111sf_table[22],
910 &mxl111sf_table[24], &mxl111sf_table[26],
911 NULL },
912 },
913 { "Hauppauge 126xxx (tp-isoc)",
914 { NULL },
915 { &mxl111sf_table[28], &mxl111sf_table[30],
916 NULL },
917 },
918 }
919};
920
921static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
922 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
923
924 .num_adapters = 1,
925 .adapter = {
926 {
927 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
928 .num_frontends = 2,
929 .fe = {{
930 .size_of_priv = sizeof(struct mxl111sf_adap_state),
931
726 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 932 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
727 .tuner_attach = mxl111sf_attach_tuner, 933 .tuner_attach = mxl111sf_attach_tuner,
728 934
729 MXL111SF_EP6_BULK_STREAMING_CONFIG, 935 MXL111SF_EP6_BULK_STREAMING_CONFIG,
936 },
937 {
938 .size_of_priv = sizeof(struct mxl111sf_adap_state),
939
940 .frontend_attach = mxl111sf_attach_demod,
941 .tuner_attach = mxl111sf_attach_tuner,
942
943 MXL111SF_EP4_BULK_STREAMING_CONFIG,
730 }}, 944 }},
731 }, 945 },
732 }, 946 },
@@ -776,7 +990,7 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
776 .adapter = { 990 .adapter = {
777 { 991 {
778 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 992 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
779 .num_frontends = 1, 993 .num_frontends = 2,
780 .fe = {{ 994 .fe = {{
781 .size_of_priv = sizeof(struct mxl111sf_adap_state), 995 .size_of_priv = sizeof(struct mxl111sf_adap_state),
782 996
@@ -784,6 +998,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
784 .tuner_attach = mxl111sf_attach_tuner, 998 .tuner_attach = mxl111sf_attach_tuner,
785 999
786 MXL111SF_EP6_ISOC_STREAMING_CONFIG, 1000 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1001 },
1002 {
1003 .size_of_priv = sizeof(struct mxl111sf_adap_state),
1004
1005 .frontend_attach = mxl111sf_attach_demod,
1006 .tuner_attach = mxl111sf_attach_tuner,
1007
1008 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
787 }}, 1009 }},
788 }, 1010 },
789 }, 1011 },
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.h b/drivers/media/dvb/dvb-usb/mxl111sf.h
index 5a2c7bb386cd..364d89f826bd 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.h
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.h
@@ -133,7 +133,7 @@ extern int dvb_usb_mxl111sf_debug;
133/* The following allows the mxl_fail() macro defined below to work 133/* The following allows the mxl_fail() macro defined below to work
134 * in externel modules, such as mxl111sf-tuner.ko, even though 134 * in externel modules, such as mxl111sf-tuner.ko, even though
135 * dvb_usb_mxl111sf_debug is not defined within those modules */ 135 * dvb_usb_mxl111sf_debug is not defined within those modules */
136#ifdef __MXL111SF_TUNER_H__ 136#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
137#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG 137#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
138#else 138#else
139#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug 139#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
index 89873615e683..13ebeffb705f 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/dvb/ngene/Makefile
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
11ccflags-y += -Idrivers/media/common/tuners/ 11ccflags-y += -Idrivers/media/common/tuners/
12 12
13# For the staging CI driver cxd2099 13# For the staging CI driver cxd2099
14ccflags-y += -Idrivers/staging/cxd2099/ 14ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 95ddcc4845d3..db20904d01f0 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -128,8 +128,10 @@ struct tea5764_write_regs {
128 u16 rdsbbl; /* PAUSEDET & RDSBBL */ 128 u16 rdsbbl; /* PAUSEDET & RDSBBL */
129} __attribute__ ((packed)); 129} __attribute__ ((packed));
130 130
131#ifndef RADIO_TEA5764_XTAL 131#ifdef CONFIG_RADIO_TEA5764_XTAL
132#define RADIO_TEA5764_XTAL 1 132#define RADIO_TEA5764_XTAL 1
133#else
134#define RADIO_TEA5764_XTAL 0
133#endif 135#endif
134 136
135static int radio_nr = -1; 137static int radio_nr = -1;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d285c8c92819..b303a3f8a9f8 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -517,6 +517,13 @@ config VIDEO_NOON010PC30
517 517
518source "drivers/media/video/m5mols/Kconfig" 518source "drivers/media/video/m5mols/Kconfig"
519 519
520config VIDEO_S5K6AA
521 tristate "Samsung S5K6AAFX sensor support"
522 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
523 ---help---
524 This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
525 camera sensor with an embedded SoC image signal processor.
526
520comment "Flash devices" 527comment "Flash devices"
521 528
522config VIDEO_ADP1653 529config VIDEO_ADP1653
@@ -736,6 +743,8 @@ source "drivers/media/video/cx88/Kconfig"
736 743
737source "drivers/media/video/cx23885/Kconfig" 744source "drivers/media/video/cx23885/Kconfig"
738 745
746source "drivers/media/video/cx25821/Kconfig"
747
739source "drivers/media/video/au0828/Kconfig" 748source "drivers/media/video/au0828/Kconfig"
740 749
741source "drivers/media/video/ivtv/Kconfig" 750source "drivers/media/video/ivtv/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 11fff97e7196..117f9c4b4cb9 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
72obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 72obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
73obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 73obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
74obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ 74obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
75obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
75obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o 76obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
76 77
77obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o 78obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
@@ -104,6 +105,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
104obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 105obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
105obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/ 106obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
106obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 107obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
108obj-$(CONFIG_VIDEO_CX25821) += cx25821/
107obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 109obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
108obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 110obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
109obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ 111obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 774715d2f84f..8c775c59e120 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -94,6 +94,7 @@ struct atmel_isi {
94 unsigned int irq; 94 unsigned int irq;
95 95
96 struct isi_platform_data *pdata; 96 struct isi_platform_data *pdata;
97 u16 width_flags; /* max 12 bits */
97 98
98 struct list_head video_buffer_list; 99 struct list_head video_buffer_list;
99 struct frame_buffer *active; 100 struct frame_buffer *active;
@@ -248,9 +249,9 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
248/* ------------------------------------------------------------------ 249/* ------------------------------------------------------------------
249 Videobuf operations 250 Videobuf operations
250 ------------------------------------------------------------------*/ 251 ------------------------------------------------------------------*/
251static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 252static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
252 unsigned int *nplanes, unsigned int sizes[], 253 unsigned int *nbuffers, unsigned int *nplanes,
253 void *alloc_ctxs[]) 254 unsigned int sizes[], void *alloc_ctxs[])
254{ 255{
255 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 256 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
256 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 257 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
@@ -647,50 +648,42 @@ static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
647 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 648 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
648} 649}
649 650
650static unsigned long make_bus_param(struct atmel_isi *isi) 651#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
651{ 652 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
652 unsigned long flags; 653 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
653 /* 654 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
654 * Platform specified synchronization and pixel clock polarities are 655 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
655 * only a recommendation and are only used during probing. Atmel ISI 656 V4L2_MBUS_PCLK_SAMPLE_RISING | \
656 * camera interface only works in master mode, i.e., uses HSYNC and 657 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
657 * VSYNC signals from the sensor 658 V4L2_MBUS_DATA_ACTIVE_HIGH)
658 */
659 flags = SOCAM_MASTER |
660 SOCAM_HSYNC_ACTIVE_HIGH |
661 SOCAM_HSYNC_ACTIVE_LOW |
662 SOCAM_VSYNC_ACTIVE_HIGH |
663 SOCAM_VSYNC_ACTIVE_LOW |
664 SOCAM_PCLK_SAMPLE_RISING |
665 SOCAM_PCLK_SAMPLE_FALLING |
666 SOCAM_DATA_ACTIVE_HIGH;
667
668 if (isi->pdata->data_width_flags & ISI_DATAWIDTH_10)
669 flags |= SOCAM_DATAWIDTH_10;
670
671 if (isi->pdata->data_width_flags & ISI_DATAWIDTH_8)
672 flags |= SOCAM_DATAWIDTH_8;
673
674 if (flags & SOCAM_DATAWIDTH_MASK)
675 return flags;
676
677 return 0;
678}
679 659
680static int isi_camera_try_bus_param(struct soc_camera_device *icd, 660static int isi_camera_try_bus_param(struct soc_camera_device *icd,
681 unsigned char buswidth) 661 unsigned char buswidth)
682{ 662{
663 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
683 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 664 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
684 struct atmel_isi *isi = ici->priv; 665 struct atmel_isi *isi = ici->priv;
685 unsigned long camera_flags; 666 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
667 unsigned long common_flags;
686 int ret; 668 int ret;
687 669
688 camera_flags = icd->ops->query_bus_param(icd); 670 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
689 ret = soc_camera_bus_param_compatible(camera_flags, 671 if (!ret) {
690 make_bus_param(isi)); 672 common_flags = soc_mbus_config_compatible(&cfg,
691 if (!ret) 673 ISI_BUS_PARAM);
692 return -EINVAL; 674 if (!common_flags) {
693 return 0; 675 dev_warn(icd->parent,
676 "Flags incompatible: camera 0x%x, host 0x%x\n",
677 cfg.flags, ISI_BUS_PARAM);
678 return -EINVAL;
679 }
680 } else if (ret != -ENOIOCTLCMD) {
681 return ret;
682 }
683
684 if ((1 << (buswidth - 1)) & isi->width_flags)
685 return 0;
686 return -EINVAL;
694} 687}
695 688
696 689
@@ -812,59 +805,71 @@ static int isi_camera_querycap(struct soc_camera_host *ici,
812 805
813static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt) 806static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt)
814{ 807{
808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
815 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 809 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
816 struct atmel_isi *isi = ici->priv; 810 struct atmel_isi *isi = ici->priv;
817 unsigned long bus_flags, camera_flags, common_flags; 811 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
812 unsigned long common_flags;
818 int ret; 813 int ret;
819 u32 cfg1 = 0; 814 u32 cfg1 = 0;
820 815
821 camera_flags = icd->ops->query_bus_param(icd); 816 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
822 817 if (!ret) {
823 bus_flags = make_bus_param(isi); 818 common_flags = soc_mbus_config_compatible(&cfg,
824 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 819 ISI_BUS_PARAM);
825 dev_dbg(icd->parent, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n", 820 if (!common_flags) {
826 camera_flags, bus_flags, common_flags); 821 dev_warn(icd->parent,
827 if (!common_flags) 822 "Flags incompatible: camera 0x%x, host 0x%x\n",
828 return -EINVAL; 823 cfg.flags, ISI_BUS_PARAM);
824 return -EINVAL;
825 }
826 } else if (ret != -ENOIOCTLCMD) {
827 return ret;
828 } else {
829 common_flags = ISI_BUS_PARAM;
830 }
831 dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
832 cfg.flags, ISI_BUS_PARAM, common_flags);
829 833
830 /* Make choises, based on platform preferences */ 834 /* Make choises, based on platform preferences */
831 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 835 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
832 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 836 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
833 if (isi->pdata->hsync_act_low) 837 if (isi->pdata->hsync_act_low)
834 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 838 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
835 else 839 else
836 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 840 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
837 } 841 }
838 842
839 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 843 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
840 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 844 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
841 if (isi->pdata->vsync_act_low) 845 if (isi->pdata->vsync_act_low)
842 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 846 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
843 else 847 else
844 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 848 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
845 } 849 }
846 850
847 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 851 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
848 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 852 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
849 if (isi->pdata->pclk_act_falling) 853 if (isi->pdata->pclk_act_falling)
850 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 854 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
851 else 855 else
852 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 856 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
853 } 857 }
854 858
855 ret = icd->ops->set_bus_param(icd, common_flags); 859 cfg.flags = common_flags;
856 if (ret < 0) { 860 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
857 dev_dbg(icd->parent, "Camera set_bus_param(%lx) returned %d\n", 861 if (ret < 0 && ret != -ENOIOCTLCMD) {
862 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
858 common_flags, ret); 863 common_flags, ret);
859 return ret; 864 return ret;
860 } 865 }
861 866
862 /* set bus param for ISI */ 867 /* set bus param for ISI */
863 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 868 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
864 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW; 869 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
865 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 870 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
866 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW; 871 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
867 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 872 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
868 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; 873 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
869 874
870 if (isi->pdata->has_emb_sync) 875 if (isi->pdata->has_emb_sync)
@@ -983,6 +988,11 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
983 goto err_ioremap; 988 goto err_ioremap;
984 } 989 }
985 990
991 if (pdata->data_width_flags & ISI_DATAWIDTH_8)
992 isi->width_flags = 1 << 7;
993 if (pdata->data_width_flags & ISI_DATAWIDTH_10)
994 isi->width_flags |= 1 << 9;
995
986 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 996 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
987 997
988 irq = platform_get_irq(pdev, 0); 998 irq = platform_get_irq(pdev, 0);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 9e2f870f4258..c6ff32a6137c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -1085,6 +1085,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1085 setup.addr = ADDR_UNSET; 1085 setup.addr = ADDR_UNSET;
1086 setup.type = cx->options.tuner; 1086 setup.type = cx->options.tuner;
1087 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 1087 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1088 if (cx->options.radio > 0)
1089 setup.mode_mask |= T_RADIO;
1088 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 1090 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1089 cx18_reset_tuner_gpio : NULL; 1091 cx18_reset_tuner_gpio : NULL;
1090 cx18_call_all(cx, tuner, s_type_addr, &setup); 1092 cx18_call_all(cx, tuner, s_type_addr, &setup);
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/media/video/cx25821/Kconfig
index 5f6b54213713..5f6b54213713 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/media/video/cx25821/Kconfig
diff --git a/drivers/staging/cx25821/Makefile b/drivers/media/video/cx25821/Makefile
index aedde18c68f9..aedde18c68f9 100644
--- a/drivers/staging/cx25821/Makefile
+++ b/drivers/media/video/cx25821/Makefile
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
index 09e99de5fd21..09e99de5fd21 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/media/video/cx25821/cx25821-alsa.c
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c
index c20d6dece154..c20d6dece154 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/media/video/cx25821/cx25821-audio-upstream.h
index af2ae7c5815a..af2ae7c5815a 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.h
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.h
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h
index 8eb55b7b88cb..8eb55b7b88cb 100644
--- a/drivers/staging/cx25821/cx25821-audio.h
+++ b/drivers/media/video/cx25821/cx25821-audio.h
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/media/video/cx25821/cx25821-biffuncs.h
index 9326a7c729ec..9326a7c729ec 100644
--- a/drivers/staging/cx25821/cx25821-biffuncs.h
+++ b/drivers/media/video/cx25821/cx25821-biffuncs.h
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c
index 6ace60313b49..6ace60313b49 100644
--- a/drivers/staging/cx25821/cx25821-cards.c
+++ b/drivers/media/video/cx25821/cx25821-cards.c
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
index a7fa38f9594e..a7fa38f9594e 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/media/video/cx25821/cx25821-core.c
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/media/video/cx25821/cx25821-gpio.c
index 29e43b03c85e..29e43b03c85e 100644
--- a/drivers/staging/cx25821/cx25821-gpio.c
+++ b/drivers/media/video/cx25821/cx25821-gpio.c
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c
index 4d3d0ce40785..4d3d0ce40785 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/media/video/cx25821/cx25821-i2c.c
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h
index 60d197f57556..60d197f57556 100644
--- a/drivers/staging/cx25821/cx25821-medusa-defines.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h
index 1c1c228352d1..1c1c228352d1 100644
--- a/drivers/staging/cx25821/cx25821-medusa-reg.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-reg.h
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c
index fc780d0908dc..fc780d0908dc 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.c
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/media/video/cx25821/cx25821-medusa-video.h
index 6175e0961855..6175e0961855 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.h
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/media/video/cx25821/cx25821-reg.h
index a3fc25a4dc0b..a3fc25a4dc0b 100644
--- a/drivers/staging/cx25821/cx25821-reg.h
+++ b/drivers/media/video/cx25821/cx25821-reg.h
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/media/video/cx25821/cx25821-sram.h
index 5f05d153bc4d..5f05d153bc4d 100644
--- a/drivers/staging/cx25821/cx25821-sram.h
+++ b/drivers/media/video/cx25821/cx25821-sram.h
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
index 2a724ddfa53f..2a724ddfa53f 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
index d42dab59b663..d42dab59b663 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c
index c0b80068f468..c0b80068f468 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.c
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/media/video/cx25821/cx25821-video-upstream.h
index 268ec8aa6a61..268ec8aa6a61 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.h
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.h
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c
index 084fc0899e13..4d6907cda75b 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/media/video/cx25821/cx25821-video.c
@@ -1312,7 +1312,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1312 return err; 1312 return err;
1313 } 1313 }
1314 1314
1315 if (i > 2) { 1315 if (i >= CX25821_NR_INPUT) {
1316 dprintk(1, "%s(): -EINVAL\n", __func__); 1316 dprintk(1, "%s(): -EINVAL\n", __func__);
1317 return -EINVAL; 1317 return -EINVAL;
1318 } 1318 }
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/media/video/cx25821/cx25821-video.h
index d0d9538ca5b3..d0d9538ca5b3 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/media/video/cx25821/cx25821-video.h
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h
index db2615b2bac3..2d2d00932823 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/media/video/cx25821/cx25821.h
@@ -98,6 +98,7 @@
98#define CX25821_BOARD_CONEXANT_ATHENA10 1 98#define CX25821_BOARD_CONEXANT_ATHENA10 1
99#define MAX_VID_CHANNEL_NUM 12 99#define MAX_VID_CHANNEL_NUM 12
100#define VID_CHANNEL_NUM 8 100#define VID_CHANNEL_NUM 8
101#define CX25821_NR_INPUT 2
101 102
102struct cx25821_fmt { 103struct cx25821_fmt {
103 char *name; 104 char *name;
@@ -196,7 +197,7 @@ struct cx25821_board {
196 unsigned char radio_addr; 197 unsigned char radio_addr;
197 198
198 u32 clk_freq; 199 u32 clk_freq;
199 struct cx25821_input input[2]; 200 struct cx25821_input input[CX25821_NR_INPUT];
200}; 201};
201 202
202struct cx25821_subid { 203struct cx25821_subid {
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 4240f0b720fa..9b747c266afa 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1923,6 +1923,8 @@ struct usb_device_id em28xx_id_table[] = {
1923 .driver_info = EM2860_BOARD_TERRATEC_AV350 }, 1923 .driver_info = EM2860_BOARD_TERRATEC_AV350 },
1924 { USB_DEVICE(0x0ccd, 0x0096), 1924 { USB_DEVICE(0x0ccd, 0x0096),
1925 .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, 1925 .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
1926 { USB_DEVICE(0x0ccd, 0x10AF),
1927 .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
1926 { USB_DEVICE(0x0fd9, 0x0033), 1928 { USB_DEVICE(0x0fd9, 0x0033),
1927 .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, 1929 .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
1928 { USB_DEVICE(0x185b, 0x2870), 1930 { USB_DEVICE(0x185b, 0x2870),
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 0382ea752e6f..8775e262bb6e 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -12,11 +12,11 @@
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/v4l2-mediabus.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/videodev2.h> 17#include <linux/videodev2.h>
17 18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
19#include <media/soc_mediabus.h>
20#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
21#include <media/v4l2-chip-ident.h> 21#include <media/v4l2-chip-ident.h>
22 22
@@ -267,6 +267,17 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
267 return 0; 267 return 0;
268} 268}
269 269
270static int imx074_g_mbus_config(struct v4l2_subdev *sd,
271 struct v4l2_mbus_config *cfg)
272{
273 cfg->type = V4L2_MBUS_CSI2;
274 cfg->flags = V4L2_MBUS_CSI2_2_LANE |
275 V4L2_MBUS_CSI2_CHANNEL_0 |
276 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
277
278 return 0;
279}
280
270static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { 281static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
271 .s_stream = imx074_s_stream, 282 .s_stream = imx074_s_stream,
272 .s_mbus_fmt = imx074_s_fmt, 283 .s_mbus_fmt = imx074_s_fmt,
@@ -275,6 +286,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
275 .enum_mbus_fmt = imx074_enum_fmt, 286 .enum_mbus_fmt = imx074_enum_fmt,
276 .g_crop = imx074_g_crop, 287 .g_crop = imx074_g_crop,
277 .cropcap = imx074_cropcap, 288 .cropcap = imx074_cropcap,
289 .g_mbus_config = imx074_g_mbus_config,
278}; 290};
279 291
280static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { 292static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
@@ -286,28 +298,7 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
286 .video = &imx074_subdev_video_ops, 298 .video = &imx074_subdev_video_ops,
287}; 299};
288 300
289/* 301static int imx074_video_probe(struct i2c_client *client)
290 * We have to provide soc-camera operations, but we don't have anything to say
291 * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
292 */
293static unsigned long imx074_query_bus_param(struct soc_camera_device *icd)
294{
295 return 0;
296}
297
298static int imx074_set_bus_param(struct soc_camera_device *icd,
299 unsigned long flags)
300{
301 return -EINVAL;
302}
303
304static struct soc_camera_ops imx074_ops = {
305 .query_bus_param = imx074_query_bus_param,
306 .set_bus_param = imx074_set_bus_param,
307};
308
309static int imx074_video_probe(struct soc_camera_device *icd,
310 struct i2c_client *client)
311{ 302{
312 int ret; 303 int ret;
313 u16 id; 304 u16 id;
@@ -417,17 +408,10 @@ static int imx074_probe(struct i2c_client *client,
417 const struct i2c_device_id *did) 408 const struct i2c_device_id *did)
418{ 409{
419 struct imx074 *priv; 410 struct imx074 *priv;
420 struct soc_camera_device *icd = client->dev.platform_data;
421 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 411 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
422 struct soc_camera_link *icl; 412 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
423 int ret; 413 int ret;
424 414
425 if (!icd) {
426 dev_err(&client->dev, "IMX074: missing soc-camera data!\n");
427 return -EINVAL;
428 }
429
430 icl = to_soc_camera_link(icd);
431 if (!icl) { 415 if (!icl) {
432 dev_err(&client->dev, "IMX074: missing platform data!\n"); 416 dev_err(&client->dev, "IMX074: missing platform data!\n");
433 return -EINVAL; 417 return -EINVAL;
@@ -445,12 +429,10 @@ static int imx074_probe(struct i2c_client *client,
445 429
446 v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops); 430 v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops);
447 431
448 icd->ops = &imx074_ops;
449 priv->fmt = &imx074_colour_fmts[0]; 432 priv->fmt = &imx074_colour_fmts[0];
450 433
451 ret = imx074_video_probe(icd, client); 434 ret = imx074_video_probe(client);
452 if (ret < 0) { 435 if (ret < 0) {
453 icd->ops = NULL;
454 kfree(priv); 436 kfree(priv);
455 return ret; 437 return ret;
456 } 438 }
@@ -461,10 +443,8 @@ static int imx074_probe(struct i2c_client *client,
461static int imx074_remove(struct i2c_client *client) 443static int imx074_remove(struct i2c_client *client)
462{ 444{
463 struct imx074 *priv = to_imx074(client); 445 struct imx074 *priv = to_imx074(client);
464 struct soc_camera_device *icd = client->dev.platform_data; 446 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
465 struct soc_camera_link *icl = to_soc_camera_link(icd);
466 447
467 icd->ops = NULL;
468 if (icl->free_bus) 448 if (icl->free_bus)
469 icl->free_bus(icl); 449 icl->free_bus(icl);
470 kfree(priv); 450 kfree(priv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 0fb75524484d..41108a9a195e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1180,6 +1180,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
1180 setup.addr = ADDR_UNSET; 1180 setup.addr = ADDR_UNSET;
1181 setup.type = itv->options.tuner; 1181 setup.type = itv->options.tuner;
1182 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 1182 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1183 if (itv->options.radio > 0)
1184 setup.mode_mask |= T_RADIO;
1183 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 1185 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1184 ivtv_reset_tuner_gpio : NULL; 1186 ivtv_reset_tuner_gpio : NULL;
1185 ivtv_call_all(itv, tuner, s_type_addr, &setup); 1187 ivtv_call_all(itv, tuner, s_type_addr, &setup);
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 1141b976dff4..80ec64d2d6d8 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -883,7 +883,8 @@ static int mcam_read_setup(struct mcam_camera *cam)
883 * Videobuf2 interface code. 883 * Videobuf2 interface code.
884 */ 884 */
885 885
886static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs, 886static int mcam_vb_queue_setup(struct vb2_queue *vq,
887 const struct v4l2_format *fmt, unsigned int *nbufs,
887 unsigned int *num_planes, unsigned int sizes[], 888 unsigned int *num_planes, unsigned int sizes[],
888 void *alloc_ctxs[]) 889 void *alloc_ctxs[])
889{ 890{
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 9594b52f8605..12897e8a3314 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -738,9 +738,10 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
738 * Queue operations 738 * Queue operations
739 */ 739 */
740 740
741static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 741static int m2mtest_queue_setup(struct vb2_queue *vq,
742 unsigned int *nplanes, unsigned int sizes[], 742 const struct v4l2_format *fmt,
743 void *alloc_ctxs[]) 743 unsigned int *nbuffers, unsigned int *nplanes,
744 unsigned int sizes[], void *alloc_ctxs[])
744{ 745{
745 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq); 746 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
746 struct m2mtest_q_data *q_data; 747 struct m2mtest_q_data *q_data;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 4da9cca939c1..63ae5c61c9bf 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -13,9 +13,11 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/soc_camera.h>
17#include <media/soc_mediabus.h>
16#include <media/v4l2-subdev.h> 18#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 19#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 20#include <media/v4l2-ctrls.h>
19 21
20/* 22/*
21 * mt9m001 i2c address 0x5d 23 * mt9m001 i2c address 0x5d
@@ -84,15 +86,19 @@ static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
84 86
85struct mt9m001 { 87struct mt9m001 {
86 struct v4l2_subdev subdev; 88 struct v4l2_subdev subdev;
89 struct v4l2_ctrl_handler hdl;
90 struct {
91 /* exposure/auto-exposure cluster */
92 struct v4l2_ctrl *autoexposure;
93 struct v4l2_ctrl *exposure;
94 };
87 struct v4l2_rect rect; /* Sensor window */ 95 struct v4l2_rect rect; /* Sensor window */
88 const struct mt9m001_datafmt *fmt; 96 const struct mt9m001_datafmt *fmt;
89 const struct mt9m001_datafmt *fmts; 97 const struct mt9m001_datafmt *fmts;
90 int num_fmts; 98 int num_fmts;
91 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 99 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
92 unsigned int gain; 100 unsigned int total_h;
93 unsigned int exposure;
94 unsigned short y_skip_top; /* Lines to skip at the top */ 101 unsigned short y_skip_top; /* Lines to skip at the top */
95 unsigned char autoexposure;
96}; 102};
97 103
98static struct mt9m001 *to_mt9m001(const struct i2c_client *client) 104static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
@@ -165,54 +171,13 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
165 return 0; 171 return 0;
166} 172}
167 173
168static int mt9m001_set_bus_param(struct soc_camera_device *icd,
169 unsigned long flags)
170{
171 struct soc_camera_link *icl = to_soc_camera_link(icd);
172 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
173
174 /* Only one width bit may be set */
175 if (!is_power_of_2(width_flag))
176 return -EINVAL;
177
178 if (icl->set_bus_param)
179 return icl->set_bus_param(icl, width_flag);
180
181 /*
182 * Without board specific bus width settings we only support the
183 * sensors native bus width
184 */
185 if (width_flag == SOCAM_DATAWIDTH_10)
186 return 0;
187
188 return -EINVAL;
189}
190
191static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
192{
193 struct soc_camera_link *icl = to_soc_camera_link(icd);
194 /* MT9M001 has all capture_format parameters fixed */
195 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
196 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
197 SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
198
199 if (icl->query_bus_param)
200 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
201 else
202 flags |= SOCAM_DATAWIDTH_10;
203
204 return soc_camera_apply_sensor_flags(icl, flags);
205}
206
207static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 174static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
208{ 175{
209 struct i2c_client *client = v4l2_get_subdevdata(sd); 176 struct i2c_client *client = v4l2_get_subdevdata(sd);
210 struct mt9m001 *mt9m001 = to_mt9m001(client); 177 struct mt9m001 *mt9m001 = to_mt9m001(client);
211 struct v4l2_rect rect = a->c; 178 struct v4l2_rect rect = a->c;
212 struct soc_camera_device *icd = client->dev.platform_data;
213 int ret; 179 int ret;
214 const u16 hblank = 9, vblank = 25; 180 const u16 hblank = 9, vblank = 25;
215 unsigned int total_h;
216 181
217 if (mt9m001->fmts == mt9m001_colour_fmts) 182 if (mt9m001->fmts == mt9m001_colour_fmts)
218 /* 183 /*
@@ -231,7 +196,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
231 soc_camera_limit_side(&rect.top, &rect.height, 196 soc_camera_limit_side(&rect.top, &rect.height,
232 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); 197 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
233 198
234 total_h = rect.height + mt9m001->y_skip_top + vblank; 199 mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
235 200
236 /* Blanking and start values - default... */ 201 /* Blanking and start values - default... */
237 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); 202 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -240,7 +205,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
240 205
241 /* 206 /*
242 * The caller provides a supported format, as verified per 207 * The caller provides a supported format, as verified per
243 * call to icd->try_fmt() 208 * call to .try_mbus_fmt()
244 */ 209 */
245 if (!ret) 210 if (!ret)
246 ret = reg_write(client, MT9M001_COLUMN_START, rect.left); 211 ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
@@ -251,17 +216,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
251 if (!ret) 216 if (!ret)
252 ret = reg_write(client, MT9M001_WINDOW_HEIGHT, 217 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
253 rect.height + mt9m001->y_skip_top - 1); 218 rect.height + mt9m001->y_skip_top - 1);
254 if (!ret && mt9m001->autoexposure) { 219 if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
255 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); 220 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
256 if (!ret) {
257 const struct v4l2_queryctrl *qctrl =
258 soc_camera_find_qctrl(icd->ops,
259 V4L2_CID_EXPOSURE);
260 mt9m001->exposure = (524 + (total_h - 1) *
261 (qctrl->maximum - qctrl->minimum)) /
262 1048 + qctrl->minimum;
263 }
264 }
265 221
266 if (!ret) 222 if (!ret)
267 mt9m001->rect = rect; 223 mt9m001->rect = rect;
@@ -421,107 +377,48 @@ static int mt9m001_s_register(struct v4l2_subdev *sd,
421} 377}
422#endif 378#endif
423 379
424static const struct v4l2_queryctrl mt9m001_controls[] = { 380static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
425 {
426 .id = V4L2_CID_VFLIP,
427 .type = V4L2_CTRL_TYPE_BOOLEAN,
428 .name = "Flip Vertically",
429 .minimum = 0,
430 .maximum = 1,
431 .step = 1,
432 .default_value = 0,
433 }, {
434 .id = V4L2_CID_GAIN,
435 .type = V4L2_CTRL_TYPE_INTEGER,
436 .name = "Gain",
437 .minimum = 0,
438 .maximum = 127,
439 .step = 1,
440 .default_value = 64,
441 .flags = V4L2_CTRL_FLAG_SLIDER,
442 }, {
443 .id = V4L2_CID_EXPOSURE,
444 .type = V4L2_CTRL_TYPE_INTEGER,
445 .name = "Exposure",
446 .minimum = 1,
447 .maximum = 255,
448 .step = 1,
449 .default_value = 255,
450 .flags = V4L2_CTRL_FLAG_SLIDER,
451 }, {
452 .id = V4L2_CID_EXPOSURE_AUTO,
453 .type = V4L2_CTRL_TYPE_BOOLEAN,
454 .name = "Automatic Exposure",
455 .minimum = 0,
456 .maximum = 1,
457 .step = 1,
458 .default_value = 1,
459 }
460};
461
462static struct soc_camera_ops mt9m001_ops = {
463 .set_bus_param = mt9m001_set_bus_param,
464 .query_bus_param = mt9m001_query_bus_param,
465 .controls = mt9m001_controls,
466 .num_controls = ARRAY_SIZE(mt9m001_controls),
467};
468
469static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
470{ 381{
471 struct i2c_client *client = v4l2_get_subdevdata(sd); 382 struct mt9m001 *mt9m001 = container_of(ctrl->handler,
472 struct mt9m001 *mt9m001 = to_mt9m001(client); 383 struct mt9m001, hdl);
473 int data; 384 s32 min, max;
474 385
475 switch (ctrl->id) { 386 switch (ctrl->id) {
476 case V4L2_CID_VFLIP:
477 data = reg_read(client, MT9M001_READ_OPTIONS2);
478 if (data < 0)
479 return -EIO;
480 ctrl->value = !!(data & 0x8000);
481 break;
482 case V4L2_CID_EXPOSURE_AUTO: 387 case V4L2_CID_EXPOSURE_AUTO:
483 ctrl->value = mt9m001->autoexposure; 388 min = mt9m001->exposure->minimum;
484 break; 389 max = mt9m001->exposure->maximum;
485 case V4L2_CID_GAIN: 390 mt9m001->exposure->val =
486 ctrl->value = mt9m001->gain; 391 (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
487 break;
488 case V4L2_CID_EXPOSURE:
489 ctrl->value = mt9m001->exposure;
490 break; 392 break;
491 } 393 }
492 return 0; 394 return 0;
493} 395}
494 396
495static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 397static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
496{ 398{
399 struct mt9m001 *mt9m001 = container_of(ctrl->handler,
400 struct mt9m001, hdl);
401 struct v4l2_subdev *sd = &mt9m001->subdev;
497 struct i2c_client *client = v4l2_get_subdevdata(sd); 402 struct i2c_client *client = v4l2_get_subdevdata(sd);
498 struct mt9m001 *mt9m001 = to_mt9m001(client); 403 struct v4l2_ctrl *exp = mt9m001->exposure;
499 struct soc_camera_device *icd = client->dev.platform_data;
500 const struct v4l2_queryctrl *qctrl;
501 int data; 404 int data;
502 405
503 qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id);
504
505 if (!qctrl)
506 return -EINVAL;
507
508 switch (ctrl->id) { 406 switch (ctrl->id) {
509 case V4L2_CID_VFLIP: 407 case V4L2_CID_VFLIP:
510 if (ctrl->value) 408 if (ctrl->val)
511 data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000); 409 data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
512 else 410 else
513 data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000); 411 data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
514 if (data < 0) 412 if (data < 0)
515 return -EIO; 413 return -EIO;
516 break; 414 return 0;
415
517 case V4L2_CID_GAIN: 416 case V4L2_CID_GAIN:
518 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
519 return -EINVAL;
520 /* See Datasheet Table 7, Gain settings. */ 417 /* See Datasheet Table 7, Gain settings. */
521 if (ctrl->value <= qctrl->default_value) { 418 if (ctrl->val <= ctrl->default_value) {
522 /* Pack it into 0..1 step 0.125, register values 0..8 */ 419 /* Pack it into 0..1 step 0.125, register values 0..8 */
523 unsigned long range = qctrl->default_value - qctrl->minimum; 420 unsigned long range = ctrl->default_value - ctrl->minimum;
524 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 421 data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
525 422
526 dev_dbg(&client->dev, "Setting gain %d\n", data); 423 dev_dbg(&client->dev, "Setting gain %d\n", data);
527 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 424 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
@@ -530,8 +427,8 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
530 } else { 427 } else {
531 /* Pack it into 1.125..15 variable step, register values 9..67 */ 428 /* Pack it into 1.125..15 variable step, register values 9..67 */
532 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ 429 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
533 unsigned long range = qctrl->maximum - qctrl->default_value - 1; 430 unsigned long range = ctrl->maximum - ctrl->default_value - 1;
534 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * 431 unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
535 111 + range / 2) / range + 9; 432 111 + range / 2) / range + 9;
536 433
537 if (gain <= 32) 434 if (gain <= 32)
@@ -547,66 +444,44 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
547 if (data < 0) 444 if (data < 0)
548 return -EIO; 445 return -EIO;
549 } 446 }
447 return 0;
550 448
551 /* Success */ 449 case V4L2_CID_EXPOSURE_AUTO:
552 mt9m001->gain = ctrl->value; 450 if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
553 break; 451 unsigned long range = exp->maximum - exp->minimum;
554 case V4L2_CID_EXPOSURE: 452 unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
555 /* mt9m001 has maximum == default */
556 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
557 return -EINVAL;
558 else {
559 unsigned long range = qctrl->maximum - qctrl->minimum;
560 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
561 range / 2) / range + 1; 453 range / 2) / range + 1;
562 454
563 dev_dbg(&client->dev, 455 dev_dbg(&client->dev,
564 "Setting shutter width from %d to %lu\n", 456 "Setting shutter width from %d to %lu\n",
565 reg_read(client, MT9M001_SHUTTER_WIDTH), 457 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
566 shutter);
567 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) 458 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
568 return -EIO; 459 return -EIO;
569 mt9m001->exposure = ctrl->value; 460 } else {
570 mt9m001->autoexposure = 0;
571 }
572 break;
573 case V4L2_CID_EXPOSURE_AUTO:
574 if (ctrl->value) {
575 const u16 vblank = 25; 461 const u16 vblank = 25;
576 unsigned int total_h = mt9m001->rect.height + 462
463 mt9m001->total_h = mt9m001->rect.height +
577 mt9m001->y_skip_top + vblank; 464 mt9m001->y_skip_top + vblank;
578 if (reg_write(client, MT9M001_SHUTTER_WIDTH, 465 if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
579 total_h) < 0)
580 return -EIO; 466 return -EIO;
581 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 467 }
582 mt9m001->exposure = (524 + (total_h - 1) * 468 return 0;
583 (qctrl->maximum - qctrl->minimum)) /
584 1048 + qctrl->minimum;
585 mt9m001->autoexposure = 1;
586 } else
587 mt9m001->autoexposure = 0;
588 break;
589 } 469 }
590 return 0; 470 return -EINVAL;
591} 471}
592 472
593/* 473/*
594 * Interface active, can use i2c. If it fails, it can indeed mean, that 474 * Interface active, can use i2c. If it fails, it can indeed mean, that
595 * this wasn't our capture interface, so, we wait for the right one 475 * this wasn't our capture interface, so, we wait for the right one
596 */ 476 */
597static int mt9m001_video_probe(struct soc_camera_device *icd, 477static int mt9m001_video_probe(struct soc_camera_link *icl,
598 struct i2c_client *client) 478 struct i2c_client *client)
599{ 479{
600 struct mt9m001 *mt9m001 = to_mt9m001(client); 480 struct mt9m001 *mt9m001 = to_mt9m001(client);
601 struct soc_camera_link *icl = to_soc_camera_link(icd);
602 s32 data; 481 s32 data;
603 unsigned long flags; 482 unsigned long flags;
604 int ret; 483 int ret;
605 484
606 /* We must have a parent by now. And it cannot be a wrong one. */
607 BUG_ON(!icd->parent ||
608 to_soc_camera_host(icd->parent)->nr != icd->iface);
609
610 /* Enable the chip */ 485 /* Enable the chip */
611 data = reg_write(client, MT9M001_CHIP_ENABLE, 1); 486 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
612 dev_dbg(&client->dev, "write: %d\n", data); 487 dev_dbg(&client->dev, "write: %d\n", data);
@@ -661,18 +536,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
661 dev_err(&client->dev, "Failed to initialise the camera\n"); 536 dev_err(&client->dev, "Failed to initialise the camera\n");
662 537
663 /* mt9m001_init() has reset the chip, returning registers to defaults */ 538 /* mt9m001_init() has reset the chip, returning registers to defaults */
664 mt9m001->gain = 64; 539 return v4l2_ctrl_handler_setup(&mt9m001->hdl);
665 mt9m001->exposure = 255;
666
667 return ret;
668} 540}
669 541
670static void mt9m001_video_remove(struct soc_camera_device *icd) 542static void mt9m001_video_remove(struct soc_camera_link *icl)
671{ 543{
672 struct soc_camera_link *icl = to_soc_camera_link(icd);
673
674 dev_dbg(icd->pdev, "Video removed: %p, %p\n",
675 icd->parent, icd->vdev);
676 if (icl->free_bus) 544 if (icl->free_bus)
677 icl->free_bus(icl); 545 icl->free_bus(icl);
678} 546}
@@ -687,9 +555,12 @@ static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
687 return 0; 555 return 0;
688} 556}
689 557
558static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
559 .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
560 .s_ctrl = mt9m001_s_ctrl,
561};
562
690static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { 563static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
691 .g_ctrl = mt9m001_g_ctrl,
692 .s_ctrl = mt9m001_s_ctrl,
693 .g_chip_ident = mt9m001_g_chip_ident, 564 .g_chip_ident = mt9m001_g_chip_ident,
694#ifdef CONFIG_VIDEO_ADV_DEBUG 565#ifdef CONFIG_VIDEO_ADV_DEBUG
695 .g_register = mt9m001_g_register, 566 .g_register = mt9m001_g_register,
@@ -710,6 +581,40 @@ static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
710 return 0; 581 return 0;
711} 582}
712 583
584static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
585 struct v4l2_mbus_config *cfg)
586{
587 struct i2c_client *client = v4l2_get_subdevdata(sd);
588 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
589
590 /* MT9M001 has all capture_format parameters fixed */
591 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
592 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
593 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
594 cfg->type = V4L2_MBUS_PARALLEL;
595 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
596
597 return 0;
598}
599
600static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
601 const struct v4l2_mbus_config *cfg)
602{
603 const struct i2c_client *client = v4l2_get_subdevdata(sd);
604 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
605 struct mt9m001 *mt9m001 = to_mt9m001(client);
606 unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
607
608 if (icl->set_bus_param)
609 return icl->set_bus_param(icl, 1 << (bps - 1));
610
611 /*
612 * Without board specific bus width settings we only support the
613 * sensors native bus width
614 */
615 return bps == 10 ? 0 : -EINVAL;
616}
617
713static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { 618static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
714 .s_stream = mt9m001_s_stream, 619 .s_stream = mt9m001_s_stream,
715 .s_mbus_fmt = mt9m001_s_fmt, 620 .s_mbus_fmt = mt9m001_s_fmt,
@@ -719,6 +624,8 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
719 .g_crop = mt9m001_g_crop, 624 .g_crop = mt9m001_g_crop,
720 .cropcap = mt9m001_cropcap, 625 .cropcap = mt9m001_cropcap,
721 .enum_mbus_fmt = mt9m001_enum_fmt, 626 .enum_mbus_fmt = mt9m001_enum_fmt,
627 .g_mbus_config = mt9m001_g_mbus_config,
628 .s_mbus_config = mt9m001_s_mbus_config,
722}; 629};
723 630
724static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { 631static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
@@ -735,17 +642,10 @@ static int mt9m001_probe(struct i2c_client *client,
735 const struct i2c_device_id *did) 642 const struct i2c_device_id *did)
736{ 643{
737 struct mt9m001 *mt9m001; 644 struct mt9m001 *mt9m001;
738 struct soc_camera_device *icd = client->dev.platform_data;
739 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 645 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
740 struct soc_camera_link *icl; 646 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
741 int ret; 647 int ret;
742 648
743 if (!icd) {
744 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
745 return -EINVAL;
746 }
747
748 icl = to_soc_camera_link(icd);
749 if (!icl) { 649 if (!icl) {
750 dev_err(&client->dev, "MT9M001 driver needs platform data\n"); 650 dev_err(&client->dev, "MT9M001 driver needs platform data\n");
751 return -EINVAL; 651 return -EINVAL;
@@ -762,25 +662,40 @@ static int mt9m001_probe(struct i2c_client *client,
762 return -ENOMEM; 662 return -ENOMEM;
763 663
764 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops); 664 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
665 v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
666 v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
667 V4L2_CID_VFLIP, 0, 1, 1, 0);
668 v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
669 V4L2_CID_GAIN, 0, 127, 1, 64);
670 mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
671 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
672 /*
673 * Simulated autoexposure. If enabled, we calculate shutter width
674 * ourselves in the driver based on vertical blanking and frame width
675 */
676 mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
677 &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
678 V4L2_EXPOSURE_AUTO);
679 mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
680 if (mt9m001->hdl.error) {
681 int err = mt9m001->hdl.error;
765 682
766 /* Second stage probe - when a capture adapter is there */ 683 kfree(mt9m001);
767 icd->ops = &mt9m001_ops; 684 return err;
685 }
686 v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
687 V4L2_EXPOSURE_MANUAL, true);
768 688
689 /* Second stage probe - when a capture adapter is there */
769 mt9m001->y_skip_top = 0; 690 mt9m001->y_skip_top = 0;
770 mt9m001->rect.left = MT9M001_COLUMN_SKIP; 691 mt9m001->rect.left = MT9M001_COLUMN_SKIP;
771 mt9m001->rect.top = MT9M001_ROW_SKIP; 692 mt9m001->rect.top = MT9M001_ROW_SKIP;
772 mt9m001->rect.width = MT9M001_MAX_WIDTH; 693 mt9m001->rect.width = MT9M001_MAX_WIDTH;
773 mt9m001->rect.height = MT9M001_MAX_HEIGHT; 694 mt9m001->rect.height = MT9M001_MAX_HEIGHT;
774 695
775 /* 696 ret = mt9m001_video_probe(icl, client);
776 * Simulated autoexposure. If enabled, we calculate shutter width
777 * ourselves in the driver based on vertical blanking and frame width
778 */
779 mt9m001->autoexposure = 1;
780
781 ret = mt9m001_video_probe(icd, client);
782 if (ret) { 697 if (ret) {
783 icd->ops = NULL; 698 v4l2_ctrl_handler_free(&mt9m001->hdl);
784 kfree(mt9m001); 699 kfree(mt9m001);
785 } 700 }
786 701
@@ -790,10 +705,11 @@ static int mt9m001_probe(struct i2c_client *client,
790static int mt9m001_remove(struct i2c_client *client) 705static int mt9m001_remove(struct i2c_client *client)
791{ 706{
792 struct mt9m001 *mt9m001 = to_mt9m001(client); 707 struct mt9m001 *mt9m001 = to_mt9m001(client);
793 struct soc_camera_device *icd = client->dev.platform_data; 708 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
794 709
795 icd->ops = NULL; 710 v4l2_device_unregister_subdev(&mt9m001->subdev);
796 mt9m001_video_remove(icd); 711 v4l2_ctrl_handler_free(&mt9m001->hdl);
712 mt9m001_video_remove(icl);
797 kfree(mt9m001); 713 kfree(mt9m001);
798 714
799 return 0; 715 return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 07af26e6bebd..f023cc092c2b 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -13,10 +13,12 @@
13#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/v4l2-mediabus.h>
16 17
18#include <media/soc_camera.h>
17#include <media/v4l2-common.h> 19#include <media/v4l2-common.h>
20#include <media/v4l2-ctrls.h>
18#include <media/v4l2-chip-ident.h> 21#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h>
20 22
21/* 23/*
22 * MT9M111, MT9M112 and MT9M131: 24 * MT9M111, MT9M112 and MT9M131:
@@ -177,6 +179,8 @@ enum mt9m111_context {
177 179
178struct mt9m111 { 180struct mt9m111 {
179 struct v4l2_subdev subdev; 181 struct v4l2_subdev subdev;
182 struct v4l2_ctrl_handler hdl;
183 struct v4l2_ctrl *gain;
180 int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code 184 int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
181 * from v4l2-chip-ident.h */ 185 * from v4l2-chip-ident.h */
182 enum mt9m111_context context; 186 enum mt9m111_context context;
@@ -185,13 +189,8 @@ struct mt9m111 {
185 int power_count; 189 int power_count;
186 const struct mt9m111_datafmt *fmt; 190 const struct mt9m111_datafmt *fmt;
187 int lastpage; /* PageMap cache value */ 191 int lastpage; /* PageMap cache value */
188 unsigned int gain;
189 unsigned char autoexposure;
190 unsigned char datawidth; 192 unsigned char datawidth;
191 unsigned int powered:1; 193 unsigned int powered:1;
192 unsigned int hflip:1;
193 unsigned int vflip:1;
194 unsigned int autowhitebalance:1;
195}; 194};
196 195
197static struct mt9m111 *to_mt9m111(const struct i2c_client *client) 196static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
@@ -363,21 +362,6 @@ static int mt9m111_reset(struct mt9m111 *mt9m111)
363 return ret; 362 return ret;
364} 363}
365 364
366static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
367{
368 struct soc_camera_link *icl = to_soc_camera_link(icd);
369 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
370 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
371 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
372
373 return soc_camera_apply_sensor_flags(icl, flags);
374}
375
376static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
377{
378 return 0;
379}
380
381static int mt9m111_make_rect(struct mt9m111 *mt9m111, 365static int mt9m111_make_rect(struct mt9m111 *mt9m111,
382 struct v4l2_rect *rect) 366 struct v4l2_rect *rect)
383{ 367{
@@ -660,50 +644,6 @@ static int mt9m111_s_register(struct v4l2_subdev *sd,
660} 644}
661#endif 645#endif
662 646
663static const struct v4l2_queryctrl mt9m111_controls[] = {
664 {
665 .id = V4L2_CID_VFLIP,
666 .type = V4L2_CTRL_TYPE_BOOLEAN,
667 .name = "Flip Verticaly",
668 .minimum = 0,
669 .maximum = 1,
670 .step = 1,
671 .default_value = 0,
672 }, {
673 .id = V4L2_CID_HFLIP,
674 .type = V4L2_CTRL_TYPE_BOOLEAN,
675 .name = "Flip Horizontaly",
676 .minimum = 0,
677 .maximum = 1,
678 .step = 1,
679 .default_value = 0,
680 }, { /* gain = 1/32*val (=>gain=1 if val==32) */
681 .id = V4L2_CID_GAIN,
682 .type = V4L2_CTRL_TYPE_INTEGER,
683 .name = "Gain",
684 .minimum = 0,
685 .maximum = 63 * 2 * 2,
686 .step = 1,
687 .default_value = 32,
688 .flags = V4L2_CTRL_FLAG_SLIDER,
689 }, {
690 .id = V4L2_CID_EXPOSURE_AUTO,
691 .type = V4L2_CTRL_TYPE_BOOLEAN,
692 .name = "Auto Exposure",
693 .minimum = 0,
694 .maximum = 1,
695 .step = 1,
696 .default_value = 1,
697 }
698};
699
700static struct soc_camera_ops mt9m111_ops = {
701 .query_bus_param = mt9m111_query_bus_param,
702 .set_bus_param = mt9m111_set_bus_param,
703 .controls = mt9m111_controls,
704 .num_controls = ARRAY_SIZE(mt9m111_controls),
705};
706
707static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask) 647static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask)
708{ 648{
709 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 649 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
@@ -744,7 +684,6 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
744 if (gain > 63 * 2 * 2) 684 if (gain > 63 * 2 * 2)
745 return -EINVAL; 685 return -EINVAL;
746 686
747 mt9m111->gain = gain;
748 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) 687 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
749 val = (1 << 10) | (1 << 9) | (gain / 4); 688 val = (1 << 10) | (1 << 9) | (gain / 4);
750 else if ((gain >= 64) && (gain < 64 * 2)) 689 else if ((gain >= 64) && (gain < 64 * 2))
@@ -758,118 +697,47 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
758static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on) 697static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on)
759{ 698{
760 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 699 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
761 int ret;
762 700
763 if (on) 701 if (on)
764 ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); 702 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
765 else 703 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
766 ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
767
768 if (!ret)
769 mt9m111->autoexposure = on;
770
771 return ret;
772} 704}
773 705
774static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on) 706static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
775{ 707{
776 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 708 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
777 int ret;
778 709
779 if (on) 710 if (on)
780 ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN); 711 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
781 else 712 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
782 ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
783
784 if (!ret)
785 mt9m111->autowhitebalance = on;
786
787 return ret;
788}
789
790static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
791{
792 struct i2c_client *client = v4l2_get_subdevdata(sd);
793 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
794 int data;
795
796 switch (ctrl->id) {
797 case V4L2_CID_VFLIP:
798 if (mt9m111->context == HIGHPOWER)
799 data = reg_read(READ_MODE_B);
800 else
801 data = reg_read(READ_MODE_A);
802
803 if (data < 0)
804 return -EIO;
805 ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS);
806 break;
807 case V4L2_CID_HFLIP:
808 if (mt9m111->context == HIGHPOWER)
809 data = reg_read(READ_MODE_B);
810 else
811 data = reg_read(READ_MODE_A);
812
813 if (data < 0)
814 return -EIO;
815 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
816 break;
817 case V4L2_CID_GAIN:
818 data = mt9m111_get_global_gain(mt9m111);
819 if (data < 0)
820 return data;
821 ctrl->value = data;
822 break;
823 case V4L2_CID_EXPOSURE_AUTO:
824 ctrl->value = mt9m111->autoexposure;
825 break;
826 case V4L2_CID_AUTO_WHITE_BALANCE:
827 ctrl->value = mt9m111->autowhitebalance;
828 break;
829 }
830 return 0;
831} 713}
832 714
833static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 715static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
834{ 716{
835 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); 717 struct mt9m111 *mt9m111 = container_of(ctrl->handler,
836 const struct v4l2_queryctrl *qctrl; 718 struct mt9m111, hdl);
837 int ret;
838
839 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
840 if (!qctrl)
841 return -EINVAL;
842 719
843 switch (ctrl->id) { 720 switch (ctrl->id) {
844 case V4L2_CID_VFLIP: 721 case V4L2_CID_VFLIP:
845 mt9m111->vflip = ctrl->value; 722 return mt9m111_set_flip(mt9m111, ctrl->val,
846 ret = mt9m111_set_flip(mt9m111, ctrl->value,
847 MT9M111_RMB_MIRROR_ROWS); 723 MT9M111_RMB_MIRROR_ROWS);
848 break;
849 case V4L2_CID_HFLIP: 724 case V4L2_CID_HFLIP:
850 mt9m111->hflip = ctrl->value; 725 return mt9m111_set_flip(mt9m111, ctrl->val,
851 ret = mt9m111_set_flip(mt9m111, ctrl->value,
852 MT9M111_RMB_MIRROR_COLS); 726 MT9M111_RMB_MIRROR_COLS);
853 break;
854 case V4L2_CID_GAIN: 727 case V4L2_CID_GAIN:
855 ret = mt9m111_set_global_gain(mt9m111, ctrl->value); 728 return mt9m111_set_global_gain(mt9m111, ctrl->val);
856 break;
857 case V4L2_CID_EXPOSURE_AUTO: 729 case V4L2_CID_EXPOSURE_AUTO:
858 ret = mt9m111_set_autoexposure(mt9m111, ctrl->value); 730 return mt9m111_set_autoexposure(mt9m111, ctrl->val);
859 break;
860 case V4L2_CID_AUTO_WHITE_BALANCE: 731 case V4L2_CID_AUTO_WHITE_BALANCE:
861 ret = mt9m111_set_autowhitebalance(mt9m111, ctrl->value); 732 return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
862 break;
863 default:
864 ret = -EINVAL;
865 } 733 }
866 734
867 return ret; 735 return -EINVAL;
868} 736}
869 737
870static int mt9m111_suspend(struct mt9m111 *mt9m111) 738static int mt9m111_suspend(struct mt9m111 *mt9m111)
871{ 739{
872 mt9m111->gain = mt9m111_get_global_gain(mt9m111); 740 v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111));
873 741
874 return 0; 742 return 0;
875} 743}
@@ -879,11 +747,7 @@ static void mt9m111_restore_state(struct mt9m111 *mt9m111)
879 mt9m111_set_context(mt9m111, mt9m111->context); 747 mt9m111_set_context(mt9m111, mt9m111->context);
880 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code); 748 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code);
881 mt9m111_setup_rect(mt9m111, &mt9m111->rect); 749 mt9m111_setup_rect(mt9m111, &mt9m111->rect);
882 mt9m111_set_flip(mt9m111, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 750 v4l2_ctrl_handler_setup(&mt9m111->hdl);
883 mt9m111_set_flip(mt9m111, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
884 mt9m111_set_global_gain(mt9m111, mt9m111->gain);
885 mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
886 mt9m111_set_autowhitebalance(mt9m111, mt9m111->autowhitebalance);
887} 751}
888 752
889static int mt9m111_resume(struct mt9m111 *mt9m111) 753static int mt9m111_resume(struct mt9m111 *mt9m111)
@@ -911,8 +775,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
911 ret = mt9m111_reset(mt9m111); 775 ret = mt9m111_reset(mt9m111);
912 if (!ret) 776 if (!ret)
913 ret = mt9m111_set_context(mt9m111, mt9m111->context); 777 ret = mt9m111_set_context(mt9m111, mt9m111->context);
914 if (!ret)
915 ret = mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
916 if (ret) 778 if (ret)
917 dev_err(&client->dev, "mt9m111 init failed: %d\n", ret); 779 dev_err(&client->dev, "mt9m111 init failed: %d\n", ret);
918 return ret; 780 return ret;
@@ -922,22 +784,12 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
922 * Interface active, can use i2c. If it fails, it can indeed mean, that 784 * Interface active, can use i2c. If it fails, it can indeed mean, that
923 * this wasn't our capture interface, so, we wait for the right one 785 * this wasn't our capture interface, so, we wait for the right one
924 */ 786 */
925static int mt9m111_video_probe(struct soc_camera_device *icd, 787static int mt9m111_video_probe(struct i2c_client *client)
926 struct i2c_client *client)
927{ 788{
928 struct mt9m111 *mt9m111 = to_mt9m111(client); 789 struct mt9m111 *mt9m111 = to_mt9m111(client);
929 s32 data; 790 s32 data;
930 int ret; 791 int ret;
931 792
932 /* We must have a parent by now. And it cannot be a wrong one. */
933 BUG_ON(!icd->parent ||
934 to_soc_camera_host(icd->parent)->nr != icd->iface);
935
936 mt9m111->lastpage = -1;
937
938 mt9m111->autoexposure = 1;
939 mt9m111->autowhitebalance = 1;
940
941 data = reg_read(CHIP_VERSION); 793 data = reg_read(CHIP_VERSION);
942 794
943 switch (data) { 795 switch (data) {
@@ -951,17 +803,16 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
951 dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); 803 dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
952 break; 804 break;
953 default: 805 default:
954 ret = -ENODEV;
955 dev_err(&client->dev, 806 dev_err(&client->dev,
956 "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n", 807 "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
957 data); 808 data);
958 goto ei2c; 809 return -ENODEV;
959 } 810 }
960 811
961 ret = mt9m111_init(mt9m111); 812 ret = mt9m111_init(mt9m111);
962 813 if (ret)
963ei2c: 814 return ret;
964 return ret; 815 return v4l2_ctrl_handler_setup(&mt9m111->hdl);
965} 816}
966 817
967static int mt9m111_s_power(struct v4l2_subdev *sd, int on) 818static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -998,9 +849,11 @@ out:
998 return ret; 849 return ret;
999} 850}
1000 851
852static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = {
853 .s_ctrl = mt9m111_s_ctrl,
854};
855
1001static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { 856static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
1002 .g_ctrl = mt9m111_g_ctrl,
1003 .s_ctrl = mt9m111_s_ctrl,
1004 .g_chip_ident = mt9m111_g_chip_ident, 857 .g_chip_ident = mt9m111_g_chip_ident,
1005 .s_power = mt9m111_s_power, 858 .s_power = mt9m111_s_power,
1006#ifdef CONFIG_VIDEO_ADV_DEBUG 859#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1019,6 +872,21 @@ static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1019 return 0; 872 return 0;
1020} 873}
1021 874
875static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
876 struct v4l2_mbus_config *cfg)
877{
878 struct i2c_client *client = v4l2_get_subdevdata(sd);
879 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
880
881 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
882 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
883 V4L2_MBUS_DATA_ACTIVE_HIGH;
884 cfg->type = V4L2_MBUS_PARALLEL;
885 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
886
887 return 0;
888}
889
1022static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { 890static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
1023 .s_mbus_fmt = mt9m111_s_fmt, 891 .s_mbus_fmt = mt9m111_s_fmt,
1024 .g_mbus_fmt = mt9m111_g_fmt, 892 .g_mbus_fmt = mt9m111_g_fmt,
@@ -1027,6 +895,7 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
1027 .g_crop = mt9m111_g_crop, 895 .g_crop = mt9m111_g_crop,
1028 .cropcap = mt9m111_cropcap, 896 .cropcap = mt9m111_cropcap,
1029 .enum_mbus_fmt = mt9m111_enum_fmt, 897 .enum_mbus_fmt = mt9m111_enum_fmt,
898 .g_mbus_config = mt9m111_g_mbus_config,
1030}; 899};
1031 900
1032static struct v4l2_subdev_ops mt9m111_subdev_ops = { 901static struct v4l2_subdev_ops mt9m111_subdev_ops = {
@@ -1038,17 +907,10 @@ static int mt9m111_probe(struct i2c_client *client,
1038 const struct i2c_device_id *did) 907 const struct i2c_device_id *did)
1039{ 908{
1040 struct mt9m111 *mt9m111; 909 struct mt9m111 *mt9m111;
1041 struct soc_camera_device *icd = client->dev.platform_data;
1042 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 910 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1043 struct soc_camera_link *icl; 911 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1044 int ret; 912 int ret;
1045 913
1046 if (!icd) {
1047 dev_err(&client->dev, "mt9m111: soc-camera data missing!\n");
1048 return -EINVAL;
1049 }
1050
1051 icl = to_soc_camera_link(icd);
1052 if (!icl) { 914 if (!icl) {
1053 dev_err(&client->dev, "mt9m111: driver needs platform data\n"); 915 dev_err(&client->dev, "mt9m111: driver needs platform data\n");
1054 return -EINVAL; 916 return -EINVAL;
@@ -1065,19 +927,37 @@ static int mt9m111_probe(struct i2c_client *client,
1065 return -ENOMEM; 927 return -ENOMEM;
1066 928
1067 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); 929 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
930 v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
931 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
932 V4L2_CID_VFLIP, 0, 1, 1, 0);
933 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
934 V4L2_CID_HFLIP, 0, 1, 1, 0);
935 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
936 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
937 mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
938 V4L2_CID_GAIN, 0, 63 * 2 * 2, 1, 32);
939 v4l2_ctrl_new_std_menu(&mt9m111->hdl,
940 &mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
941 V4L2_EXPOSURE_AUTO);
942 mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
943 if (mt9m111->hdl.error) {
944 int err = mt9m111->hdl.error;
1068 945
1069 /* Second stage probe - when a capture adapter is there */ 946 kfree(mt9m111);
1070 icd->ops = &mt9m111_ops; 947 return err;
948 }
1071 949
950 /* Second stage probe - when a capture adapter is there */
1072 mt9m111->rect.left = MT9M111_MIN_DARK_COLS; 951 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1073 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; 952 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1074 mt9m111->rect.width = MT9M111_MAX_WIDTH; 953 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1075 mt9m111->rect.height = MT9M111_MAX_HEIGHT; 954 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
1076 mt9m111->fmt = &mt9m111_colour_fmts[0]; 955 mt9m111->fmt = &mt9m111_colour_fmts[0];
956 mt9m111->lastpage = -1;
1077 957
1078 ret = mt9m111_video_probe(icd, client); 958 ret = mt9m111_video_probe(client);
1079 if (ret) { 959 if (ret) {
1080 icd->ops = NULL; 960 v4l2_ctrl_handler_free(&mt9m111->hdl);
1081 kfree(mt9m111); 961 kfree(mt9m111);
1082 } 962 }
1083 963
@@ -1087,9 +967,9 @@ static int mt9m111_probe(struct i2c_client *client,
1087static int mt9m111_remove(struct i2c_client *client) 967static int mt9m111_remove(struct i2c_client *client)
1088{ 968{
1089 struct mt9m111 *mt9m111 = to_mt9m111(client); 969 struct mt9m111 *mt9m111 = to_mt9m111(client);
1090 struct soc_camera_device *icd = client->dev.platform_data;
1091 970
1092 icd->ops = NULL; 971 v4l2_device_unregister_subdev(&mt9m111->subdev);
972 v4l2_ctrl_handler_free(&mt9m111->hdl);
1093 kfree(mt9m111); 973 kfree(mt9m111);
1094 974
1095 return 0; 975 return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 30547cc3f89b..7ee84cc578b9 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,11 +13,20 @@
13#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/pm.h> 14#include <linux/pm.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/v4l2-mediabus.h>
16#include <linux/videodev2.h> 17#include <linux/videodev2.h>
17 18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
19#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
20#include <media/v4l2-subdev.h> 21#include <media/v4l2-subdev.h>
22#include <media/v4l2-ctrls.h>
23
24/*
25 * ATTENTION: this driver still cannot be used outside of the soc-camera
26 * framework because of its PM implementation, using the video_device node.
27 * If hardware becomes available for testing, alternative PM approaches shall
28 * be considered and tested.
29 */
21 30
22/* 31/*
23 * mt9t031 i2c address 0x5d 32 * mt9t031 i2c address 0x5d
@@ -57,21 +66,20 @@
57#define MT9T031_COLUMN_SKIP 32 66#define MT9T031_COLUMN_SKIP 32
58#define MT9T031_ROW_SKIP 20 67#define MT9T031_ROW_SKIP 20
59 68
60#define MT9T031_BUS_PARAM (SOCAM_PCLK_SAMPLE_RISING | \
61 SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH | \
62 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \
63 SOCAM_MASTER | SOCAM_DATAWIDTH_10)
64
65struct mt9t031 { 69struct mt9t031 {
66 struct v4l2_subdev subdev; 70 struct v4l2_subdev subdev;
71 struct v4l2_ctrl_handler hdl;
72 struct {
73 /* exposure/auto-exposure cluster */
74 struct v4l2_ctrl *autoexposure;
75 struct v4l2_ctrl *exposure;
76 };
67 struct v4l2_rect rect; /* Sensor window */ 77 struct v4l2_rect rect; /* Sensor window */
68 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 78 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
69 u16 xskip; 79 u16 xskip;
70 u16 yskip; 80 u16 yskip;
71 unsigned int gain; 81 unsigned int total_h;
72 unsigned short y_skip_top; /* Lines to skip at the top */ 82 unsigned short y_skip_top; /* Lines to skip at the top */
73 unsigned int exposure;
74 unsigned char autoexposure;
75}; 83};
76 84
77static struct mt9t031 *to_mt9t031(const struct i2c_client *client) 85static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
@@ -179,95 +187,6 @@ static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
179 return 0; 187 return 0;
180} 188}
181 189
182static int mt9t031_set_bus_param(struct soc_camera_device *icd,
183 unsigned long flags)
184{
185 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
186
187 /* The caller should have queried our parameters, check anyway */
188 if (flags & ~MT9T031_BUS_PARAM)
189 return -EINVAL;
190
191 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
192 reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
193 else
194 reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
195
196 return 0;
197}
198
199static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
200{
201 struct soc_camera_link *icl = to_soc_camera_link(icd);
202
203 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
204}
205
206enum {
207 MT9T031_CTRL_VFLIP,
208 MT9T031_CTRL_HFLIP,
209 MT9T031_CTRL_GAIN,
210 MT9T031_CTRL_EXPOSURE,
211 MT9T031_CTRL_EXPOSURE_AUTO,
212};
213
214static const struct v4l2_queryctrl mt9t031_controls[] = {
215 [MT9T031_CTRL_VFLIP] = {
216 .id = V4L2_CID_VFLIP,
217 .type = V4L2_CTRL_TYPE_BOOLEAN,
218 .name = "Flip Vertically",
219 .minimum = 0,
220 .maximum = 1,
221 .step = 1,
222 .default_value = 0,
223 },
224 [MT9T031_CTRL_HFLIP] = {
225 .id = V4L2_CID_HFLIP,
226 .type = V4L2_CTRL_TYPE_BOOLEAN,
227 .name = "Flip Horizontally",
228 .minimum = 0,
229 .maximum = 1,
230 .step = 1,
231 .default_value = 0,
232 },
233 [MT9T031_CTRL_GAIN] = {
234 .id = V4L2_CID_GAIN,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 .name = "Gain",
237 .minimum = 0,
238 .maximum = 127,
239 .step = 1,
240 .default_value = 64,
241 .flags = V4L2_CTRL_FLAG_SLIDER,
242 },
243 [MT9T031_CTRL_EXPOSURE] = {
244 .id = V4L2_CID_EXPOSURE,
245 .type = V4L2_CTRL_TYPE_INTEGER,
246 .name = "Exposure",
247 .minimum = 1,
248 .maximum = 255,
249 .step = 1,
250 .default_value = 255,
251 .flags = V4L2_CTRL_FLAG_SLIDER,
252 },
253 [MT9T031_CTRL_EXPOSURE_AUTO] = {
254 .id = V4L2_CID_EXPOSURE_AUTO,
255 .type = V4L2_CTRL_TYPE_BOOLEAN,
256 .name = "Automatic Exposure",
257 .minimum = 0,
258 .maximum = 1,
259 .step = 1,
260 .default_value = 1,
261 }
262};
263
264static struct soc_camera_ops mt9t031_ops = {
265 .set_bus_param = mt9t031_set_bus_param,
266 .query_bus_param = mt9t031_query_bus_param,
267 .controls = mt9t031_controls,
268 .num_controls = ARRAY_SIZE(mt9t031_controls),
269};
270
271/* target must be _even_ */ 190/* target must be _even_ */
272static u16 mt9t031_skip(s32 *source, s32 target, s32 max) 191static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
273{ 192{
@@ -353,7 +272,7 @@ static int mt9t031_set_params(struct i2c_client *client,
353 272
354 /* 273 /*
355 * The caller provides a supported format, as guaranteed by 274 * The caller provides a supported format, as guaranteed by
356 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() 275 * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap()
357 */ 276 */
358 if (ret >= 0) 277 if (ret >= 0)
359 ret = reg_write(client, MT9T031_COLUMN_START, rect->left); 278 ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
@@ -364,17 +283,10 @@ static int mt9t031_set_params(struct i2c_client *client,
364 if (ret >= 0) 283 if (ret >= 0)
365 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 284 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
366 rect->height + mt9t031->y_skip_top - 1); 285 rect->height + mt9t031->y_skip_top - 1);
367 if (ret >= 0 && mt9t031->autoexposure) { 286 if (ret >= 0 && v4l2_ctrl_g_ctrl(mt9t031->autoexposure) == V4L2_EXPOSURE_AUTO) {
368 unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank; 287 mt9t031->total_h = rect->height + mt9t031->y_skip_top + vblank;
369 ret = set_shutter(client, total_h); 288
370 if (ret >= 0) { 289 ret = set_shutter(client, mt9t031->total_h);
371 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
372 const struct v4l2_queryctrl *qctrl =
373 &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
374 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
375 (qctrl->maximum - qctrl->minimum)) /
376 shutter_max + qctrl->minimum;
377 }
378 } 290 }
379 291
380 /* Re-enable register update, commit all changes */ 292 /* Re-enable register update, commit all changes */
@@ -543,71 +455,57 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
543} 455}
544#endif 456#endif
545 457
546static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 458static int mt9t031_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
547{ 459{
548 struct i2c_client *client = v4l2_get_subdevdata(sd); 460 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
549 struct mt9t031 *mt9t031 = to_mt9t031(client); 461 struct mt9t031, hdl);
550 int data; 462 const u32 shutter_max = MT9T031_MAX_HEIGHT + MT9T031_VERTICAL_BLANK;
463 s32 min, max;
551 464
552 switch (ctrl->id) { 465 switch (ctrl->id) {
553 case V4L2_CID_VFLIP:
554 data = reg_read(client, MT9T031_READ_MODE_2);
555 if (data < 0)
556 return -EIO;
557 ctrl->value = !!(data & 0x8000);
558 break;
559 case V4L2_CID_HFLIP:
560 data = reg_read(client, MT9T031_READ_MODE_2);
561 if (data < 0)
562 return -EIO;
563 ctrl->value = !!(data & 0x4000);
564 break;
565 case V4L2_CID_EXPOSURE_AUTO: 466 case V4L2_CID_EXPOSURE_AUTO:
566 ctrl->value = mt9t031->autoexposure; 467 min = mt9t031->exposure->minimum;
567 break; 468 max = mt9t031->exposure->maximum;
568 case V4L2_CID_GAIN: 469 mt9t031->exposure->val =
569 ctrl->value = mt9t031->gain; 470 (shutter_max / 2 + (mt9t031->total_h - 1) * (max - min))
570 break; 471 / shutter_max + min;
571 case V4L2_CID_EXPOSURE:
572 ctrl->value = mt9t031->exposure;
573 break; 472 break;
574 } 473 }
575 return 0; 474 return 0;
576} 475}
577 476
578static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 477static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
579{ 478{
479 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
480 struct mt9t031, hdl);
481 struct v4l2_subdev *sd = &mt9t031->subdev;
580 struct i2c_client *client = v4l2_get_subdevdata(sd); 482 struct i2c_client *client = v4l2_get_subdevdata(sd);
581 struct mt9t031 *mt9t031 = to_mt9t031(client); 483 struct v4l2_ctrl *exp = mt9t031->exposure;
582 const struct v4l2_queryctrl *qctrl;
583 int data; 484 int data;
584 485
585 switch (ctrl->id) { 486 switch (ctrl->id) {
586 case V4L2_CID_VFLIP: 487 case V4L2_CID_VFLIP:
587 if (ctrl->value) 488 if (ctrl->val)
588 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000); 489 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
589 else 490 else
590 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000); 491 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
591 if (data < 0) 492 if (data < 0)
592 return -EIO; 493 return -EIO;
593 break; 494 return 0;
594 case V4L2_CID_HFLIP: 495 case V4L2_CID_HFLIP:
595 if (ctrl->value) 496 if (ctrl->val)
596 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000); 497 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
597 else 498 else
598 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000); 499 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
599 if (data < 0) 500 if (data < 0)
600 return -EIO; 501 return -EIO;
601 break; 502 return 0;
602 case V4L2_CID_GAIN: 503 case V4L2_CID_GAIN:
603 qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
604 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
605 return -EINVAL;
606 /* See Datasheet Table 7, Gain settings. */ 504 /* See Datasheet Table 7, Gain settings. */
607 if (ctrl->value <= qctrl->default_value) { 505 if (ctrl->val <= ctrl->default_value) {
608 /* Pack it into 0..1 step 0.125, register values 0..8 */ 506 /* Pack it into 0..1 step 0.125, register values 0..8 */
609 unsigned long range = qctrl->default_value - qctrl->minimum; 507 unsigned long range = ctrl->default_value - ctrl->minimum;
610 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 508 data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
611 509
612 dev_dbg(&client->dev, "Setting gain %d\n", data); 510 dev_dbg(&client->dev, "Setting gain %d\n", data);
613 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 511 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@@ -616,9 +514,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
616 } else { 514 } else {
617 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */ 515 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
618 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ 516 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
619 unsigned long range = qctrl->maximum - qctrl->default_value - 1; 517 unsigned long range = ctrl->maximum - ctrl->default_value - 1;
620 /* calculated gain: map 65..127 to 9..1024 step 0.125 */ 518 /* calculated gain: map 65..127 to 9..1024 step 0.125 */
621 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * 519 unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
622 1015 + range / 2) / range + 9; 520 1015 + range / 2) / range + 9;
623 521
624 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */ 522 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
@@ -635,19 +533,13 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
635 if (data < 0) 533 if (data < 0)
636 return -EIO; 534 return -EIO;
637 } 535 }
536 return 0;
638 537
639 /* Success */ 538 case V4L2_CID_EXPOSURE_AUTO:
640 mt9t031->gain = ctrl->value; 539 if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
641 break; 540 unsigned int range = exp->maximum - exp->minimum;
642 case V4L2_CID_EXPOSURE: 541 unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
643 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 542 range / 2) / range + 1;
644 /* mt9t031 has maximum == default */
645 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
646 return -EINVAL;
647 else {
648 const unsigned long range = qctrl->maximum - qctrl->minimum;
649 const u32 shutter = ((ctrl->value - qctrl->minimum) * 1048 +
650 range / 2) / range + 1;
651 u32 old; 543 u32 old;
652 544
653 get_shutter(client, &old); 545 get_shutter(client, &old);
@@ -655,27 +547,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
655 old, shutter); 547 old, shutter);
656 if (set_shutter(client, shutter) < 0) 548 if (set_shutter(client, shutter) < 0)
657 return -EIO; 549 return -EIO;
658 mt9t031->exposure = ctrl->value; 550 } else {
659 mt9t031->autoexposure = 0;
660 }
661 break;
662 case V4L2_CID_EXPOSURE_AUTO:
663 if (ctrl->value) {
664 const u16 vblank = MT9T031_VERTICAL_BLANK; 551 const u16 vblank = MT9T031_VERTICAL_BLANK;
665 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 552 mt9t031->total_h = mt9t031->rect.height +
666 unsigned int total_h = mt9t031->rect.height +
667 mt9t031->y_skip_top + vblank; 553 mt9t031->y_skip_top + vblank;
668 554
669 if (set_shutter(client, total_h) < 0) 555 if (set_shutter(client, mt9t031->total_h) < 0)
670 return -EIO; 556 return -EIO;
671 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 557 }
672 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * 558 return 0;
673 (qctrl->maximum - qctrl->minimum)) /
674 shutter_max + qctrl->minimum;
675 mt9t031->autoexposure = 1;
676 } else
677 mt9t031->autoexposure = 0;
678 break;
679 default: 559 default:
680 return -EINVAL; 560 return -EINVAL;
681 } 561 }
@@ -700,8 +580,7 @@ static int mt9t031_runtime_suspend(struct device *dev)
700static int mt9t031_runtime_resume(struct device *dev) 580static int mt9t031_runtime_resume(struct device *dev)
701{ 581{
702 struct video_device *vdev = to_video_device(dev); 582 struct video_device *vdev = to_video_device(dev);
703 struct soc_camera_device *icd = dev_get_drvdata(vdev->parent); 583 struct v4l2_subdev *sd = soc_camera_vdev_to_subdev(vdev);
704 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
705 struct i2c_client *client = v4l2_get_subdevdata(sd); 584 struct i2c_client *client = v4l2_get_subdevdata(sd);
706 struct mt9t031 *mt9t031 = to_mt9t031(client); 585 struct mt9t031 *mt9t031 = to_mt9t031(client);
707 586
@@ -734,6 +613,19 @@ static struct device_type mt9t031_dev_type = {
734 .pm = &mt9t031_dev_pm_ops, 613 .pm = &mt9t031_dev_pm_ops,
735}; 614};
736 615
616static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
617{
618 struct i2c_client *client = v4l2_get_subdevdata(sd);
619 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
620
621 if (on)
622 vdev->dev.type = &mt9t031_dev_type;
623 else
624 vdev->dev.type = NULL;
625
626 return 0;
627}
628
737/* 629/*
738 * Interface active, can use i2c. If it fails, it can indeed mean, that 630 * Interface active, can use i2c. If it fails, it can indeed mean, that
739 * this wasn't our capture interface, so, we wait for the right one 631 * this wasn't our capture interface, so, we wait for the right one
@@ -741,7 +633,6 @@ static struct device_type mt9t031_dev_type = {
741static int mt9t031_video_probe(struct i2c_client *client) 633static int mt9t031_video_probe(struct i2c_client *client)
742{ 634{
743 struct mt9t031 *mt9t031 = to_mt9t031(client); 635 struct mt9t031 *mt9t031 = to_mt9t031(client);
744 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
745 s32 data; 636 s32 data;
746 int ret; 637 int ret;
747 638
@@ -768,11 +659,7 @@ static int mt9t031_video_probe(struct i2c_client *client)
768 if (ret < 0) 659 if (ret < 0)
769 dev_err(&client->dev, "Failed to initialise the camera\n"); 660 dev_err(&client->dev, "Failed to initialise the camera\n");
770 else 661 else
771 vdev->dev.type = &mt9t031_dev_type; 662 v4l2_ctrl_handler_setup(&mt9t031->hdl);
772
773 /* mt9t031_idle() has reset the chip to default. */
774 mt9t031->exposure = 255;
775 mt9t031->gain = 64;
776 663
777 return ret; 664 return ret;
778} 665}
@@ -787,10 +674,14 @@ static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
787 return 0; 674 return 0;
788} 675}
789 676
677static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
678 .g_volatile_ctrl = mt9t031_g_volatile_ctrl,
679 .s_ctrl = mt9t031_s_ctrl,
680};
681
790static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 682static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
791 .g_ctrl = mt9t031_g_ctrl,
792 .s_ctrl = mt9t031_s_ctrl,
793 .g_chip_ident = mt9t031_g_chip_ident, 683 .g_chip_ident = mt9t031_g_chip_ident,
684 .s_power = mt9t031_s_power,
794#ifdef CONFIG_VIDEO_ADV_DEBUG 685#ifdef CONFIG_VIDEO_ADV_DEBUG
795 .g_register = mt9t031_g_register, 686 .g_register = mt9t031_g_register,
796 .s_register = mt9t031_s_register, 687 .s_register = mt9t031_s_register,
@@ -807,6 +698,34 @@ static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
807 return 0; 698 return 0;
808} 699}
809 700
701static int mt9t031_g_mbus_config(struct v4l2_subdev *sd,
702 struct v4l2_mbus_config *cfg)
703{
704 struct i2c_client *client = v4l2_get_subdevdata(sd);
705 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
706
707 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
708 V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
709 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH;
710 cfg->type = V4L2_MBUS_PARALLEL;
711 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
712
713 return 0;
714}
715
716static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
717 const struct v4l2_mbus_config *cfg)
718{
719 struct i2c_client *client = v4l2_get_subdevdata(sd);
720 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
721
722 if (soc_camera_apply_board_flags(icl, cfg) &
723 V4L2_MBUS_PCLK_SAMPLE_FALLING)
724 return reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
725 else
726 return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
727}
728
810static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { 729static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
811 .s_stream = mt9t031_s_stream, 730 .s_stream = mt9t031_s_stream,
812 .s_mbus_fmt = mt9t031_s_fmt, 731 .s_mbus_fmt = mt9t031_s_fmt,
@@ -816,6 +735,8 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
816 .g_crop = mt9t031_g_crop, 735 .g_crop = mt9t031_g_crop,
817 .cropcap = mt9t031_cropcap, 736 .cropcap = mt9t031_cropcap,
818 .enum_mbus_fmt = mt9t031_enum_fmt, 737 .enum_mbus_fmt = mt9t031_enum_fmt,
738 .g_mbus_config = mt9t031_g_mbus_config,
739 .s_mbus_config = mt9t031_s_mbus_config,
819}; 740};
820 741
821static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { 742static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
@@ -832,18 +753,13 @@ static int mt9t031_probe(struct i2c_client *client,
832 const struct i2c_device_id *did) 753 const struct i2c_device_id *did)
833{ 754{
834 struct mt9t031 *mt9t031; 755 struct mt9t031 *mt9t031;
835 struct soc_camera_device *icd = client->dev.platform_data; 756 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
836 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 757 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
837 int ret; 758 int ret;
838 759
839 if (icd) { 760 if (!icl) {
840 struct soc_camera_link *icl = to_soc_camera_link(icd); 761 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
841 if (!icl) { 762 return -EINVAL;
842 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
843 return -EINVAL;
844 }
845
846 icd->ops = &mt9t031_ops;
847 } 763 }
848 764
849 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 765 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -857,6 +773,33 @@ static int mt9t031_probe(struct i2c_client *client,
857 return -ENOMEM; 773 return -ENOMEM;
858 774
859 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); 775 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
776 v4l2_ctrl_handler_init(&mt9t031->hdl, 5);
777 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
778 V4L2_CID_VFLIP, 0, 1, 1, 0);
779 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
780 V4L2_CID_HFLIP, 0, 1, 1, 0);
781 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
782 V4L2_CID_GAIN, 0, 127, 1, 64);
783
784 /*
785 * Simulated autoexposure. If enabled, we calculate shutter width
786 * ourselves in the driver based on vertical blanking and frame width
787 */
788 mt9t031->autoexposure = v4l2_ctrl_new_std_menu(&mt9t031->hdl,
789 &mt9t031_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
790 V4L2_EXPOSURE_AUTO);
791 mt9t031->exposure = v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
792 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
793
794 mt9t031->subdev.ctrl_handler = &mt9t031->hdl;
795 if (mt9t031->hdl.error) {
796 int err = mt9t031->hdl.error;
797
798 kfree(mt9t031);
799 return err;
800 }
801 v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure,
802 V4L2_EXPOSURE_MANUAL, true);
860 803
861 mt9t031->y_skip_top = 0; 804 mt9t031->y_skip_top = 0;
862 mt9t031->rect.left = MT9T031_COLUMN_SKIP; 805 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
@@ -864,12 +807,6 @@ static int mt9t031_probe(struct i2c_client *client,
864 mt9t031->rect.width = MT9T031_MAX_WIDTH; 807 mt9t031->rect.width = MT9T031_MAX_WIDTH;
865 mt9t031->rect.height = MT9T031_MAX_HEIGHT; 808 mt9t031->rect.height = MT9T031_MAX_HEIGHT;
866 809
867 /*
868 * Simulated autoexposure. If enabled, we calculate shutter width
869 * ourselves in the driver based on vertical blanking and frame width
870 */
871 mt9t031->autoexposure = 1;
872
873 mt9t031->xskip = 1; 810 mt9t031->xskip = 1;
874 mt9t031->yskip = 1; 811 mt9t031->yskip = 1;
875 812
@@ -880,8 +817,7 @@ static int mt9t031_probe(struct i2c_client *client,
880 mt9t031_disable(client); 817 mt9t031_disable(client);
881 818
882 if (ret) { 819 if (ret) {
883 if (icd) 820 v4l2_ctrl_handler_free(&mt9t031->hdl);
884 icd->ops = NULL;
885 kfree(mt9t031); 821 kfree(mt9t031);
886 } 822 }
887 823
@@ -891,10 +827,9 @@ static int mt9t031_probe(struct i2c_client *client,
891static int mt9t031_remove(struct i2c_client *client) 827static int mt9t031_remove(struct i2c_client *client)
892{ 828{
893 struct mt9t031 *mt9t031 = to_mt9t031(client); 829 struct mt9t031 *mt9t031 = to_mt9t031(client);
894 struct soc_camera_device *icd = client->dev.platform_data;
895 830
896 if (icd) 831 v4l2_device_unregister_subdev(&mt9t031->subdev);
897 icd->ops = NULL; 832 v4l2_ctrl_handler_free(&mt9t031->hdl);
898 kfree(mt9t031); 833 kfree(mt9t031);
899 834
900 return 0; 835 return 0;
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index d2e0a50063a2..32114a3c0ca7 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -22,11 +22,11 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/v4l2-mediabus.h>
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26 27
27#include <media/mt9t112.h> 28#include <media/mt9t112.h>
28#include <media/soc_camera.h> 29#include <media/soc_camera.h>
29#include <media/soc_mediabus.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32 32
@@ -34,11 +34,7 @@
34/* #define EXT_CLOCK 24000000 */ 34/* #define EXT_CLOCK 24000000 */
35 35
36/************************************************************************ 36/************************************************************************
37
38
39 macro 37 macro
40
41
42************************************************************************/ 38************************************************************************/
43/* 39/*
44 * frame size 40 * frame size
@@ -80,17 +76,8 @@
80#define VAR8(id, offset) _VAR(id, offset, 0x8000) 76#define VAR8(id, offset) _VAR(id, offset, 0x8000)
81 77
82/************************************************************************ 78/************************************************************************
83
84
85 struct 79 struct
86
87
88************************************************************************/ 80************************************************************************/
89struct mt9t112_frame_size {
90 u16 width;
91 u16 height;
92};
93
94struct mt9t112_format { 81struct mt9t112_format {
95 enum v4l2_mbus_pixelcode code; 82 enum v4l2_mbus_pixelcode code;
96 enum v4l2_colorspace colorspace; 83 enum v4l2_colorspace colorspace;
@@ -102,21 +89,17 @@ struct mt9t112_priv {
102 struct v4l2_subdev subdev; 89 struct v4l2_subdev subdev;
103 struct mt9t112_camera_info *info; 90 struct mt9t112_camera_info *info;
104 struct i2c_client *client; 91 struct i2c_client *client;
105 struct soc_camera_device icd; 92 struct v4l2_rect frame;
106 struct mt9t112_frame_size frame;
107 const struct mt9t112_format *format; 93 const struct mt9t112_format *format;
108 int model; 94 int model;
109 u32 flags; 95 u32 flags;
110/* for flags */ 96/* for flags */
111#define INIT_DONE (1<<0) 97#define INIT_DONE (1 << 0)
98#define PCLK_RISING (1 << 1)
112}; 99};
113 100
114/************************************************************************ 101/************************************************************************
115
116
117 supported format 102 supported format
118
119
120************************************************************************/ 103************************************************************************/
121 104
122static const struct mt9t112_format mt9t112_cfmts[] = { 105static const struct mt9t112_format mt9t112_cfmts[] = {
@@ -154,11 +137,7 @@ static const struct mt9t112_format mt9t112_cfmts[] = {
154}; 137};
155 138
156/************************************************************************ 139/************************************************************************
157
158
159 general function 140 general function
160
161
162************************************************************************/ 141************************************************************************/
163static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) 142static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
164{ 143{
@@ -326,50 +305,47 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
326 n = (n >> 8) & 0x003f; 305 n = (n >> 8) & 0x003f;
327 306
328 enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; 307 enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
329 dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); 308 dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable);
330 309
331 vco = 2 * m * ext / (n+1); 310 vco = 2 * m * ext / (n+1);
332 enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; 311 enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
333 dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable); 312 dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable);
334 313
335 clk = vco / (p1+1) / (p2+1); 314 clk = vco / (p1+1) / (p2+1);
336 enable = (96000 < clk) ? "X" : ""; 315 enable = (96000 < clk) ? "X" : "";
337 dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); 316 dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable);
338 317
339 clk = vco / (p3+1); 318 clk = vco / (p3+1);
340 enable = (768000 < clk) ? "X" : ""; 319 enable = (768000 < clk) ? "X" : "";
341 dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); 320 dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable);
342 321
343 clk = vco / (p6+1); 322 clk = vco / (p6+1);
344 enable = (96000 < clk) ? "X" : ""; 323 enable = (96000 < clk) ? "X" : "";
345 dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); 324 dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable);
346 325
347 clk = vco / (p5+1); 326 clk = vco / (p5+1);
348 enable = (54000 < clk) ? "X" : ""; 327 enable = (54000 < clk) ? "X" : "";
349 dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); 328 dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable);
350 329
351 clk = vco / (p4+1); 330 clk = vco / (p4+1);
352 enable = (70000 < clk) ? "X" : ""; 331 enable = (70000 < clk) ? "X" : "";
353 dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); 332 dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable);
354 333
355 clk = vco / (p7+1); 334 clk = vco / (p7+1);
356 dev_info(&client->dev, "External sensor : %10u K\n", clk); 335 dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
357 336
358 clk = ext / (n+1); 337 clk = ext / (n+1);
359 enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; 338 enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
360 dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable); 339 dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable);
361 340
362 return 0; 341 return 0;
363} 342}
364#endif 343#endif
365 344
366static void mt9t112_frame_check(u32 *width, u32 *height) 345static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
367{ 346{
368 if (*width > MAX_WIDTH) 347 soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
369 *width = MAX_WIDTH; 348 soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
370
371 if (*height > MAX_HEIGHT)
372 *height = MAX_HEIGHT;
373} 349}
374 350
375static int mt9t112_set_a_frame_size(const struct i2c_client *client, 351static int mt9t112_set_a_frame_size(const struct i2c_client *client,
@@ -758,48 +734,7 @@ static int mt9t112_init_camera(const struct i2c_client *client)
758} 734}
759 735
760/************************************************************************ 736/************************************************************************
761
762
763 soc_camera_ops
764
765
766************************************************************************/
767static int mt9t112_set_bus_param(struct soc_camera_device *icd,
768 unsigned long flags)
769{
770 return 0;
771}
772
773static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
774{
775 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
776 struct mt9t112_priv *priv = to_mt9t112(client);
777 struct soc_camera_link *icl = to_soc_camera_link(icd);
778 unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
779 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
780
781 flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
782 SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
783
784 if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
785 flags |= SOCAM_DATAWIDTH_8;
786 else
787 flags |= SOCAM_DATAWIDTH_10;
788
789 return soc_camera_apply_sensor_flags(icl, flags);
790}
791
792static struct soc_camera_ops mt9t112_ops = {
793 .set_bus_param = mt9t112_set_bus_param,
794 .query_bus_param = mt9t112_query_bus_param,
795};
796
797/************************************************************************
798
799
800 v4l2_subdev_core_ops 737 v4l2_subdev_core_ops
801
802
803************************************************************************/ 738************************************************************************/
804static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, 739static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
805 struct v4l2_dbg_chip_ident *id) 740 struct v4l2_dbg_chip_ident *id)
@@ -850,11 +785,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
850 785
851 786
852/************************************************************************ 787/************************************************************************
853
854
855 v4l2_subdev_video_ops 788 v4l2_subdev_video_ops
856
857
858************************************************************************/ 789************************************************************************/
859static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) 790static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
860{ 791{
@@ -877,8 +808,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
877 } 808 }
878 809
879 if (!(priv->flags & INIT_DONE)) { 810 if (!(priv->flags & INIT_DONE)) {
880 u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE & 811 u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
881 priv->info->flags) ? 0x0001 : 0x0000;
882 812
883 ECHECKER(ret, mt9t112_init_camera(client)); 813 ECHECKER(ret, mt9t112_init_camera(client));
884 814
@@ -910,19 +840,12 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
910 return ret; 840 return ret;
911} 841}
912 842
913static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, 843static int mt9t112_set_params(struct mt9t112_priv *priv,
844 const struct v4l2_rect *rect,
914 enum v4l2_mbus_pixelcode code) 845 enum v4l2_mbus_pixelcode code)
915{ 846{
916 struct mt9t112_priv *priv = to_mt9t112(client);
917 int i; 847 int i;
918 848
919 priv->format = NULL;
920
921 /*
922 * frame size check
923 */
924 mt9t112_frame_check(&width, &height);
925
926 /* 849 /*
927 * get color format 850 * get color format
928 */ 851 */
@@ -933,8 +856,13 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
933 if (i == ARRAY_SIZE(mt9t112_cfmts)) 856 if (i == ARRAY_SIZE(mt9t112_cfmts))
934 return -EINVAL; 857 return -EINVAL;
935 858
936 priv->frame.width = (u16)width; 859 priv->frame = *rect;
937 priv->frame.height = (u16)height; 860
861 /*
862 * frame size check
863 */
864 mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
865 &priv->frame.left, &priv->frame.top);
938 866
939 priv->format = mt9t112_cfmts + i; 867 priv->format = mt9t112_cfmts + i;
940 868
@@ -945,9 +873,12 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
945{ 873{
946 a->bounds.left = 0; 874 a->bounds.left = 0;
947 a->bounds.top = 0; 875 a->bounds.top = 0;
948 a->bounds.width = VGA_WIDTH; 876 a->bounds.width = MAX_WIDTH;
949 a->bounds.height = VGA_HEIGHT; 877 a->bounds.height = MAX_HEIGHT;
950 a->defrect = a->bounds; 878 a->defrect.left = 0;
879 a->defrect.top = 0;
880 a->defrect.width = VGA_WIDTH;
881 a->defrect.height = VGA_HEIGHT;
951 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 882 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
952 a->pixelaspect.numerator = 1; 883 a->pixelaspect.numerator = 1;
953 a->pixelaspect.denominator = 1; 884 a->pixelaspect.denominator = 1;
@@ -957,11 +888,11 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
957 888
958static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 889static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
959{ 890{
960 a->c.left = 0; 891 struct i2c_client *client = v4l2_get_subdevdata(sd);
961 a->c.top = 0; 892 struct mt9t112_priv *priv = to_mt9t112(client);
962 a->c.width = VGA_WIDTH; 893
963 a->c.height = VGA_HEIGHT; 894 a->c = priv->frame;
964 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 895 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
965 896
966 return 0; 897 return 0;
967} 898}
@@ -969,10 +900,10 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
969static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 900static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
970{ 901{
971 struct i2c_client *client = v4l2_get_subdevdata(sd); 902 struct i2c_client *client = v4l2_get_subdevdata(sd);
903 struct mt9t112_priv *priv = to_mt9t112(client);
972 struct v4l2_rect *rect = &a->c; 904 struct v4l2_rect *rect = &a->c;
973 905
974 return mt9t112_set_params(client, rect->width, rect->height, 906 return mt9t112_set_params(priv, rect, priv->format->code);
975 V4L2_MBUS_FMT_UYVY8_2X8);
976} 907}
977 908
978static int mt9t112_g_fmt(struct v4l2_subdev *sd, 909static int mt9t112_g_fmt(struct v4l2_subdev *sd,
@@ -981,16 +912,9 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd,
981 struct i2c_client *client = v4l2_get_subdevdata(sd); 912 struct i2c_client *client = v4l2_get_subdevdata(sd);
982 struct mt9t112_priv *priv = to_mt9t112(client); 913 struct mt9t112_priv *priv = to_mt9t112(client);
983 914
984 if (!priv->format) {
985 int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
986 V4L2_MBUS_FMT_UYVY8_2X8);
987 if (ret < 0)
988 return ret;
989 }
990
991 mf->width = priv->frame.width; 915 mf->width = priv->frame.width;
992 mf->height = priv->frame.height; 916 mf->height = priv->frame.height;
993 /* TODO: set colorspace */ 917 mf->colorspace = priv->format->colorspace;
994 mf->code = priv->format->code; 918 mf->code = priv->format->code;
995 mf->field = V4L2_FIELD_NONE; 919 mf->field = V4L2_FIELD_NONE;
996 920
@@ -1001,17 +925,42 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd,
1001 struct v4l2_mbus_framefmt *mf) 925 struct v4l2_mbus_framefmt *mf)
1002{ 926{
1003 struct i2c_client *client = v4l2_get_subdevdata(sd); 927 struct i2c_client *client = v4l2_get_subdevdata(sd);
928 struct mt9t112_priv *priv = to_mt9t112(client);
929 struct v4l2_rect rect = {
930 .width = mf->width,
931 .height = mf->height,
932 .left = priv->frame.left,
933 .top = priv->frame.top,
934 };
935 int ret;
936
937 ret = mt9t112_set_params(priv, &rect, mf->code);
938
939 if (!ret)
940 mf->colorspace = priv->format->colorspace;
1004 941
1005 /* TODO: set colorspace */ 942 return ret;
1006 return mt9t112_set_params(client, mf->width, mf->height, mf->code);
1007} 943}
1008 944
1009static int mt9t112_try_fmt(struct v4l2_subdev *sd, 945static int mt9t112_try_fmt(struct v4l2_subdev *sd,
1010 struct v4l2_mbus_framefmt *mf) 946 struct v4l2_mbus_framefmt *mf)
1011{ 947{
1012 mt9t112_frame_check(&mf->width, &mf->height); 948 unsigned int top, left;
949 int i;
950
951 for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
952 if (mt9t112_cfmts[i].code == mf->code)
953 break;
954
955 if (i == ARRAY_SIZE(mt9t112_cfmts)) {
956 mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
957 mf->colorspace = V4L2_COLORSPACE_JPEG;
958 } else {
959 mf->colorspace = mt9t112_cfmts[i].colorspace;
960 }
961
962 mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
1013 963
1014 /* TODO: set colorspace */
1015 mf->field = V4L2_FIELD_NONE; 964 mf->field = V4L2_FIELD_NONE;
1016 965
1017 return 0; 966 return 0;
@@ -1024,6 +973,35 @@ static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1024 return -EINVAL; 973 return -EINVAL;
1025 974
1026 *code = mt9t112_cfmts[index].code; 975 *code = mt9t112_cfmts[index].code;
976
977 return 0;
978}
979
980static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
981 struct v4l2_mbus_config *cfg)
982{
983 struct i2c_client *client = v4l2_get_subdevdata(sd);
984 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
985
986 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
987 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
988 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
989 cfg->type = V4L2_MBUS_PARALLEL;
990 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
991
992 return 0;
993}
994
995static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
996 const struct v4l2_mbus_config *cfg)
997{
998 struct i2c_client *client = v4l2_get_subdevdata(sd);
999 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1000 struct mt9t112_priv *priv = to_mt9t112(client);
1001
1002 if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
1003 priv->flags |= PCLK_RISING;
1004
1027 return 0; 1005 return 0;
1028} 1006}
1029 1007
@@ -1036,31 +1014,24 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
1036 .g_crop = mt9t112_g_crop, 1014 .g_crop = mt9t112_g_crop,
1037 .s_crop = mt9t112_s_crop, 1015 .s_crop = mt9t112_s_crop,
1038 .enum_mbus_fmt = mt9t112_enum_fmt, 1016 .enum_mbus_fmt = mt9t112_enum_fmt,
1017 .g_mbus_config = mt9t112_g_mbus_config,
1018 .s_mbus_config = mt9t112_s_mbus_config,
1039}; 1019};
1040 1020
1041/************************************************************************ 1021/************************************************************************
1042
1043
1044 i2c driver 1022 i2c driver
1045
1046
1047************************************************************************/ 1023************************************************************************/
1048static struct v4l2_subdev_ops mt9t112_subdev_ops = { 1024static struct v4l2_subdev_ops mt9t112_subdev_ops = {
1049 .core = &mt9t112_subdev_core_ops, 1025 .core = &mt9t112_subdev_core_ops,
1050 .video = &mt9t112_subdev_video_ops, 1026 .video = &mt9t112_subdev_video_ops,
1051}; 1027};
1052 1028
1053static int mt9t112_camera_probe(struct soc_camera_device *icd, 1029static int mt9t112_camera_probe(struct i2c_client *client)
1054 struct i2c_client *client)
1055{ 1030{
1056 struct mt9t112_priv *priv = to_mt9t112(client); 1031 struct mt9t112_priv *priv = to_mt9t112(client);
1057 const char *devname; 1032 const char *devname;
1058 int chipid; 1033 int chipid;
1059 1034
1060 /* We must have a parent by now. And it cannot be a wrong one. */
1061 BUG_ON(!icd->parent ||
1062 to_soc_camera_host(icd->parent)->nr != icd->iface);
1063
1064 /* 1035 /*
1065 * check and show chip ID 1036 * check and show chip ID
1066 */ 1037 */
@@ -1088,20 +1059,21 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
1088static int mt9t112_probe(struct i2c_client *client, 1059static int mt9t112_probe(struct i2c_client *client,
1089 const struct i2c_device_id *did) 1060 const struct i2c_device_id *did)
1090{ 1061{
1091 struct mt9t112_priv *priv; 1062 struct mt9t112_priv *priv;
1092 struct soc_camera_device *icd = client->dev.platform_data; 1063 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1093 struct soc_camera_link *icl; 1064 struct v4l2_rect rect = {
1094 int ret; 1065 .width = VGA_WIDTH,
1066 .height = VGA_HEIGHT,
1067 .left = (MAX_WIDTH - VGA_WIDTH) / 2,
1068 .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
1069 };
1070 int ret;
1095 1071
1096 if (!icd) { 1072 if (!icl || !icl->priv) {
1097 dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); 1073 dev_err(&client->dev, "mt9t112: missing platform data!\n");
1098 return -EINVAL; 1074 return -EINVAL;
1099 } 1075 }
1100 1076
1101 icl = to_soc_camera_link(icd);
1102 if (!icl || !icl->priv)
1103 return -EINVAL;
1104
1105 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1077 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1106 if (!priv) 1078 if (!priv)
1107 return -ENOMEM; 1079 return -ENOMEM;
@@ -1110,13 +1082,12 @@ static int mt9t112_probe(struct i2c_client *client,
1110 1082
1111 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); 1083 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
1112 1084
1113 icd->ops = &mt9t112_ops; 1085 ret = mt9t112_camera_probe(client);
1114 1086 if (ret)
1115 ret = mt9t112_camera_probe(icd, client);
1116 if (ret) {
1117 icd->ops = NULL;
1118 kfree(priv); 1087 kfree(priv);
1119 } 1088
1089 /* Cannot fail: using the default supported pixel code */
1090 mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
1120 1091
1121 return ret; 1092 return ret;
1122} 1093}
@@ -1124,9 +1095,7 @@ static int mt9t112_probe(struct i2c_client *client,
1124static int mt9t112_remove(struct i2c_client *client) 1095static int mt9t112_remove(struct i2c_client *client)
1125{ 1096{
1126 struct mt9t112_priv *priv = to_mt9t112(client); 1097 struct mt9t112_priv *priv = to_mt9t112(client);
1127 struct soc_camera_device *icd = client->dev.platform_data;
1128 1098
1129 icd->ops = NULL;
1130 kfree(priv); 1099 kfree(priv);
1131 return 0; 1100 return 0;
1132} 1101}
@@ -1147,11 +1116,7 @@ static struct i2c_driver mt9t112_i2c_driver = {
1147}; 1116};
1148 1117
1149/************************************************************************ 1118/************************************************************************
1150
1151
1152 module function 1119 module function
1153
1154
1155************************************************************************/ 1120************************************************************************/
1156static int __init mt9t112_module_init(void) 1121static int __init mt9t112_module_init(void)
1157{ 1122{
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 51b0fccbfe70..b6a29f7de82c 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,9 +14,11 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/soc_camera.h>
18#include <media/soc_mediabus.h>
17#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 21#include <media/v4l2-ctrls.h>
20 22
21/* 23/*
22 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 24 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
@@ -100,6 +102,17 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
100 102
101struct mt9v022 { 103struct mt9v022 {
102 struct v4l2_subdev subdev; 104 struct v4l2_subdev subdev;
105 struct v4l2_ctrl_handler hdl;
106 struct {
107 /* exposure/auto-exposure cluster */
108 struct v4l2_ctrl *autoexposure;
109 struct v4l2_ctrl *exposure;
110 };
111 struct {
112 /* gain/auto-gain cluster */
113 struct v4l2_ctrl *autogain;
114 struct v4l2_ctrl *gain;
115 };
103 struct v4l2_rect rect; /* Sensor window */ 116 struct v4l2_rect rect; /* Sensor window */
104 const struct mt9v022_datafmt *fmt; 117 const struct mt9v022_datafmt *fmt;
105 const struct mt9v022_datafmt *fmts; 118 const struct mt9v022_datafmt *fmts;
@@ -178,6 +191,8 @@ static int mt9v022_init(struct i2c_client *client)
178 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); 191 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
179 if (!ret) 192 if (!ret)
180 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); 193 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
194 if (!ret)
195 return v4l2_ctrl_handler_setup(&mt9v022->hdl);
181 196
182 return ret; 197 return ret;
183} 198}
@@ -199,78 +214,6 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
199 return 0; 214 return 0;
200} 215}
201 216
202static int mt9v022_set_bus_param(struct soc_camera_device *icd,
203 unsigned long flags)
204{
205 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
206 struct mt9v022 *mt9v022 = to_mt9v022(client);
207 struct soc_camera_link *icl = to_soc_camera_link(icd);
208 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
209 int ret;
210 u16 pixclk = 0;
211
212 /* Only one width bit may be set */
213 if (!is_power_of_2(width_flag))
214 return -EINVAL;
215
216 if (icl->set_bus_param) {
217 ret = icl->set_bus_param(icl, width_flag);
218 if (ret)
219 return ret;
220 } else {
221 /*
222 * Without board specific bus width settings we only support the
223 * sensors native bus width
224 */
225 if (width_flag != SOCAM_DATAWIDTH_10)
226 return -EINVAL;
227 }
228
229 flags = soc_camera_apply_sensor_flags(icl, flags);
230
231 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
232 pixclk |= 0x10;
233
234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
235 pixclk |= 0x1;
236
237 if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
238 pixclk |= 0x2;
239
240 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
241 if (ret < 0)
242 return ret;
243
244 if (!(flags & SOCAM_MASTER))
245 mt9v022->chip_control &= ~0x8;
246
247 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
248 if (ret < 0)
249 return ret;
250
251 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
252 pixclk, mt9v022->chip_control);
253
254 return 0;
255}
256
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{
259 struct soc_camera_link *icl = to_soc_camera_link(icd);
260 unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264 SOCAM_DATA_ACTIVE_HIGH;
265
266 if (icl->query_bus_param)
267 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
268 else
269 flags |= SOCAM_DATAWIDTH_10;
270
271 return soc_camera_apply_sensor_flags(icl, flags);
272}
273
274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 217static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
275{ 218{
276 struct i2c_client *client = v4l2_get_subdevdata(sd); 219 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -389,7 +332,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
389 332
390 /* 333 /*
391 * The caller provides a supported format, as verified per call to 334 * The caller provides a supported format, as verified per call to
392 * icd->try_fmt(), datawidth is from our supported format list 335 * .try_mbus_fmt(), datawidth is from our supported format list
393 */ 336 */
394 switch (mf->code) { 337 switch (mf->code) {
395 case V4L2_MBUS_FMT_Y8_1X8: 338 case V4L2_MBUS_FMT_Y8_1X8:
@@ -502,236 +445,131 @@ static int mt9v022_s_register(struct v4l2_subdev *sd,
502} 445}
503#endif 446#endif
504 447
505static const struct v4l2_queryctrl mt9v022_controls[] = { 448static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
506 {
507 .id = V4L2_CID_VFLIP,
508 .type = V4L2_CTRL_TYPE_BOOLEAN,
509 .name = "Flip Vertically",
510 .minimum = 0,
511 .maximum = 1,
512 .step = 1,
513 .default_value = 0,
514 }, {
515 .id = V4L2_CID_HFLIP,
516 .type = V4L2_CTRL_TYPE_BOOLEAN,
517 .name = "Flip Horizontally",
518 .minimum = 0,
519 .maximum = 1,
520 .step = 1,
521 .default_value = 0,
522 }, {
523 .id = V4L2_CID_GAIN,
524 .type = V4L2_CTRL_TYPE_INTEGER,
525 .name = "Analog Gain",
526 .minimum = 64,
527 .maximum = 127,
528 .step = 1,
529 .default_value = 64,
530 .flags = V4L2_CTRL_FLAG_SLIDER,
531 }, {
532 .id = V4L2_CID_EXPOSURE,
533 .type = V4L2_CTRL_TYPE_INTEGER,
534 .name = "Exposure",
535 .minimum = 1,
536 .maximum = 255,
537 .step = 1,
538 .default_value = 255,
539 .flags = V4L2_CTRL_FLAG_SLIDER,
540 }, {
541 .id = V4L2_CID_AUTOGAIN,
542 .type = V4L2_CTRL_TYPE_BOOLEAN,
543 .name = "Automatic Gain",
544 .minimum = 0,
545 .maximum = 1,
546 .step = 1,
547 .default_value = 1,
548 }, {
549 .id = V4L2_CID_EXPOSURE_AUTO,
550 .type = V4L2_CTRL_TYPE_BOOLEAN,
551 .name = "Automatic Exposure",
552 .minimum = 0,
553 .maximum = 1,
554 .step = 1,
555 .default_value = 1,
556 }
557};
558
559static struct soc_camera_ops mt9v022_ops = {
560 .set_bus_param = mt9v022_set_bus_param,
561 .query_bus_param = mt9v022_query_bus_param,
562 .controls = mt9v022_controls,
563 .num_controls = ARRAY_SIZE(mt9v022_controls),
564};
565
566static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
567{ 449{
450 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
451 struct mt9v022, hdl);
452 struct v4l2_subdev *sd = &mt9v022->subdev;
568 struct i2c_client *client = v4l2_get_subdevdata(sd); 453 struct i2c_client *client = v4l2_get_subdevdata(sd);
569 const struct v4l2_queryctrl *qctrl; 454 struct v4l2_ctrl *gain = mt9v022->gain;
455 struct v4l2_ctrl *exp = mt9v022->exposure;
570 unsigned long range; 456 unsigned long range;
571 int data; 457 int data;
572 458
573 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
574
575 switch (ctrl->id) { 459 switch (ctrl->id) {
576 case V4L2_CID_VFLIP:
577 data = reg_read(client, MT9V022_READ_MODE);
578 if (data < 0)
579 return -EIO;
580 ctrl->value = !!(data & 0x10);
581 break;
582 case V4L2_CID_HFLIP:
583 data = reg_read(client, MT9V022_READ_MODE);
584 if (data < 0)
585 return -EIO;
586 ctrl->value = !!(data & 0x20);
587 break;
588 case V4L2_CID_EXPOSURE_AUTO:
589 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
590 if (data < 0)
591 return -EIO;
592 ctrl->value = !!(data & 0x1);
593 break;
594 case V4L2_CID_AUTOGAIN: 460 case V4L2_CID_AUTOGAIN:
595 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
596 if (data < 0)
597 return -EIO;
598 ctrl->value = !!(data & 0x2);
599 break;
600 case V4L2_CID_GAIN:
601 data = reg_read(client, MT9V022_ANALOG_GAIN); 461 data = reg_read(client, MT9V022_ANALOG_GAIN);
602 if (data < 0) 462 if (data < 0)
603 return -EIO; 463 return -EIO;
604 464
605 range = qctrl->maximum - qctrl->minimum; 465 range = gain->maximum - gain->minimum;
606 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum; 466 gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
607 467 return 0;
608 break; 468 case V4L2_CID_EXPOSURE_AUTO:
609 case V4L2_CID_EXPOSURE:
610 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH); 469 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
611 if (data < 0) 470 if (data < 0)
612 return -EIO; 471 return -EIO;
613 472
614 range = qctrl->maximum - qctrl->minimum; 473 range = exp->maximum - exp->minimum;
615 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum; 474 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
616 475 return 0;
617 break;
618 } 476 }
619 return 0; 477 return -EINVAL;
620} 478}
621 479
622static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 480static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
623{ 481{
624 int data; 482 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
483 struct mt9v022, hdl);
484 struct v4l2_subdev *sd = &mt9v022->subdev;
625 struct i2c_client *client = v4l2_get_subdevdata(sd); 485 struct i2c_client *client = v4l2_get_subdevdata(sd);
626 const struct v4l2_queryctrl *qctrl; 486 int data;
627
628 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
629 if (!qctrl)
630 return -EINVAL;
631 487
632 switch (ctrl->id) { 488 switch (ctrl->id) {
633 case V4L2_CID_VFLIP: 489 case V4L2_CID_VFLIP:
634 if (ctrl->value) 490 if (ctrl->val)
635 data = reg_set(client, MT9V022_READ_MODE, 0x10); 491 data = reg_set(client, MT9V022_READ_MODE, 0x10);
636 else 492 else
637 data = reg_clear(client, MT9V022_READ_MODE, 0x10); 493 data = reg_clear(client, MT9V022_READ_MODE, 0x10);
638 if (data < 0) 494 if (data < 0)
639 return -EIO; 495 return -EIO;
640 break; 496 return 0;
641 case V4L2_CID_HFLIP: 497 case V4L2_CID_HFLIP:
642 if (ctrl->value) 498 if (ctrl->val)
643 data = reg_set(client, MT9V022_READ_MODE, 0x20); 499 data = reg_set(client, MT9V022_READ_MODE, 0x20);
644 else 500 else
645 data = reg_clear(client, MT9V022_READ_MODE, 0x20); 501 data = reg_clear(client, MT9V022_READ_MODE, 0x20);
646 if (data < 0) 502 if (data < 0)
647 return -EIO; 503 return -EIO;
648 break; 504 return 0;
649 case V4L2_CID_GAIN: 505 case V4L2_CID_AUTOGAIN:
650 /* mt9v022 has minimum == default */ 506 if (ctrl->val) {
651 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 507 if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
652 return -EINVAL; 508 return -EIO;
653 else { 509 } else {
654 unsigned long range = qctrl->maximum - qctrl->minimum; 510 struct v4l2_ctrl *gain = mt9v022->gain;
511 /* mt9v022 has minimum == default */
512 unsigned long range = gain->maximum - gain->minimum;
655 /* Valid values 16 to 64, 32 to 64 must be even. */ 513 /* Valid values 16 to 64, 32 to 64 must be even. */
656 unsigned long gain = ((ctrl->value - qctrl->minimum) * 514 unsigned long gain_val = ((gain->val - gain->minimum) *
657 48 + range / 2) / range + 16; 515 48 + range / 2) / range + 16;
658 if (gain >= 32) 516
659 gain &= ~1; 517 if (gain_val >= 32)
518 gain_val &= ~1;
519
660 /* 520 /*
661 * The user wants to set gain manually, hope, she 521 * The user wants to set gain manually, hope, she
662 * knows, what she's doing... Switch AGC off. 522 * knows, what she's doing... Switch AGC off.
663 */ 523 */
664
665 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 524 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
666 return -EIO; 525 return -EIO;
667 526
668 dev_dbg(&client->dev, "Setting gain from %d to %lu\n", 527 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
669 reg_read(client, MT9V022_ANALOG_GAIN), gain); 528 reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
670 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 529 if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
671 return -EIO; 530 return -EIO;
672 } 531 }
673 break; 532 return 0;
674 case V4L2_CID_EXPOSURE: 533 case V4L2_CID_EXPOSURE_AUTO:
675 /* mt9v022 has maximum == default */ 534 if (ctrl->val == V4L2_EXPOSURE_AUTO) {
676 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 535 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
677 return -EINVAL; 536 } else {
678 else { 537 struct v4l2_ctrl *exp = mt9v022->exposure;
679 unsigned long range = qctrl->maximum - qctrl->minimum; 538 unsigned long range = exp->maximum - exp->minimum;
680 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 539 unsigned long shutter = ((exp->val - exp->minimum) *
681 479 + range / 2) / range + 1; 540 479 + range / 2) / range + 1;
541
682 /* 542 /*
683 * The user wants to set shutter width manually, hope, 543 * The user wants to set shutter width manually, hope,
684 * she knows, what she's doing... Switch AEC off. 544 * she knows, what she's doing... Switch AEC off.
685 */ 545 */
686 546 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
687 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 547 if (data < 0)
688 return -EIO; 548 return -EIO;
689
690 dev_dbg(&client->dev, "Shutter width from %d to %lu\n", 549 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
691 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 550 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
692 shutter); 551 shutter);
693 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 552 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
694 shutter) < 0) 553 shutter) < 0)
695 return -EIO; 554 return -EIO;
696 } 555 }
697 break; 556 return 0;
698 case V4L2_CID_AUTOGAIN:
699 if (ctrl->value)
700 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
701 else
702 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
703 if (data < 0)
704 return -EIO;
705 break;
706 case V4L2_CID_EXPOSURE_AUTO:
707 if (ctrl->value)
708 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
709 else
710 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
711 if (data < 0)
712 return -EIO;
713 break;
714 } 557 }
715 return 0; 558 return -EINVAL;
716} 559}
717 560
718/* 561/*
719 * Interface active, can use i2c. If it fails, it can indeed mean, that 562 * Interface active, can use i2c. If it fails, it can indeed mean, that
720 * this wasn't our capture interface, so, we wait for the right one 563 * this wasn't our capture interface, so, we wait for the right one
721 */ 564 */
722static int mt9v022_video_probe(struct soc_camera_device *icd, 565static int mt9v022_video_probe(struct i2c_client *client)
723 struct i2c_client *client)
724{ 566{
725 struct mt9v022 *mt9v022 = to_mt9v022(client); 567 struct mt9v022 *mt9v022 = to_mt9v022(client);
726 struct soc_camera_link *icl = to_soc_camera_link(icd); 568 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
727 s32 data; 569 s32 data;
728 int ret; 570 int ret;
729 unsigned long flags; 571 unsigned long flags;
730 572
731 /* We must have a parent by now. And it cannot be a wrong one. */
732 BUG_ON(!icd->parent ||
733 to_soc_camera_host(icd->parent)->nr != icd->iface);
734
735 /* Read out the chip version register */ 573 /* Read out the chip version register */
736 data = reg_read(client, MT9V022_CHIP_VERSION); 574 data = reg_read(client, MT9V022_CHIP_VERSION);
737 575
@@ -805,16 +643,6 @@ ei2c:
805 return ret; 643 return ret;
806} 644}
807 645
808static void mt9v022_video_remove(struct soc_camera_device *icd)
809{
810 struct soc_camera_link *icl = to_soc_camera_link(icd);
811
812 dev_dbg(icd->pdev, "Video removed: %p, %p\n",
813 icd->parent, icd->vdev);
814 if (icl->free_bus)
815 icl->free_bus(icl);
816}
817
818static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) 646static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
819{ 647{
820 struct i2c_client *client = v4l2_get_subdevdata(sd); 648 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -825,9 +653,12 @@ static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
825 return 0; 653 return 0;
826} 654}
827 655
656static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
657 .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
658 .s_ctrl = mt9v022_s_ctrl,
659};
660
828static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { 661static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
829 .g_ctrl = mt9v022_g_ctrl,
830 .s_ctrl = mt9v022_s_ctrl,
831 .g_chip_ident = mt9v022_g_chip_ident, 662 .g_chip_ident = mt9v022_g_chip_ident,
832#ifdef CONFIG_VIDEO_ADV_DEBUG 663#ifdef CONFIG_VIDEO_ADV_DEBUG
833 .g_register = mt9v022_g_register, 664 .g_register = mt9v022_g_register,
@@ -848,6 +679,72 @@ static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
848 return 0; 679 return 0;
849} 680}
850 681
682static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
683 struct v4l2_mbus_config *cfg)
684{
685 struct i2c_client *client = v4l2_get_subdevdata(sd);
686 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
687
688 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
689 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
690 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
691 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
692 V4L2_MBUS_DATA_ACTIVE_HIGH;
693 cfg->type = V4L2_MBUS_PARALLEL;
694 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
695
696 return 0;
697}
698
699static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
700 const struct v4l2_mbus_config *cfg)
701{
702 struct i2c_client *client = v4l2_get_subdevdata(sd);
703 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
704 struct mt9v022 *mt9v022 = to_mt9v022(client);
705 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
706 unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
707 int ret;
708 u16 pixclk = 0;
709
710 if (icl->set_bus_param) {
711 ret = icl->set_bus_param(icl, 1 << (bps - 1));
712 if (ret)
713 return ret;
714 } else if (bps != 10) {
715 /*
716 * Without board specific bus width settings we only support the
717 * sensors native bus width
718 */
719 return -EINVAL;
720 }
721
722 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
723 pixclk |= 0x10;
724
725 if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
726 pixclk |= 0x1;
727
728 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
729 pixclk |= 0x2;
730
731 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
732 if (ret < 0)
733 return ret;
734
735 if (!(flags & V4L2_MBUS_MASTER))
736 mt9v022->chip_control &= ~0x8;
737
738 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
739 if (ret < 0)
740 return ret;
741
742 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
743 pixclk, mt9v022->chip_control);
744
745 return 0;
746}
747
851static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 748static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
852 .s_stream = mt9v022_s_stream, 749 .s_stream = mt9v022_s_stream,
853 .s_mbus_fmt = mt9v022_s_fmt, 750 .s_mbus_fmt = mt9v022_s_fmt,
@@ -857,6 +754,8 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
857 .g_crop = mt9v022_g_crop, 754 .g_crop = mt9v022_g_crop,
858 .cropcap = mt9v022_cropcap, 755 .cropcap = mt9v022_cropcap,
859 .enum_mbus_fmt = mt9v022_enum_fmt, 756 .enum_mbus_fmt = mt9v022_enum_fmt,
757 .g_mbus_config = mt9v022_g_mbus_config,
758 .s_mbus_config = mt9v022_s_mbus_config,
860}; 759};
861 760
862static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { 761static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
@@ -873,17 +772,10 @@ static int mt9v022_probe(struct i2c_client *client,
873 const struct i2c_device_id *did) 772 const struct i2c_device_id *did)
874{ 773{
875 struct mt9v022 *mt9v022; 774 struct mt9v022 *mt9v022;
876 struct soc_camera_device *icd = client->dev.platform_data; 775 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
877 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 776 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
878 struct soc_camera_link *icl;
879 int ret; 777 int ret;
880 778
881 if (!icd) {
882 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
883 return -EINVAL;
884 }
885
886 icl = to_soc_camera_link(icd);
887 if (!icl) { 779 if (!icl) {
888 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 780 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
889 return -EINVAL; 781 return -EINVAL;
@@ -900,10 +792,39 @@ static int mt9v022_probe(struct i2c_client *client,
900 return -ENOMEM; 792 return -ENOMEM;
901 793
902 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops); 794 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
795 v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
796 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
797 V4L2_CID_VFLIP, 0, 1, 1, 0);
798 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
799 V4L2_CID_HFLIP, 0, 1, 1, 0);
800 mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
801 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
802 mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
803 V4L2_CID_GAIN, 0, 127, 1, 64);
804
805 /*
806 * Simulated autoexposure. If enabled, we calculate shutter width
807 * ourselves in the driver based on vertical blanking and frame width
808 */
809 mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
810 &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
811 V4L2_EXPOSURE_AUTO);
812 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
813 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
814
815 mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
816 if (mt9v022->hdl.error) {
817 int err = mt9v022->hdl.error;
818
819 kfree(mt9v022);
820 return err;
821 }
822 v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
823 V4L2_EXPOSURE_MANUAL, true);
824 v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
903 825
904 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 826 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
905 827
906 icd->ops = &mt9v022_ops;
907 /* 828 /*
908 * MT9V022 _really_ corrupts the first read out line. 829 * MT9V022 _really_ corrupts the first read out line.
909 * TODO: verify on i.MX31 830 * TODO: verify on i.MX31
@@ -914,9 +835,9 @@ static int mt9v022_probe(struct i2c_client *client,
914 mt9v022->rect.width = MT9V022_MAX_WIDTH; 835 mt9v022->rect.width = MT9V022_MAX_WIDTH;
915 mt9v022->rect.height = MT9V022_MAX_HEIGHT; 836 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
916 837
917 ret = mt9v022_video_probe(icd, client); 838 ret = mt9v022_video_probe(client);
918 if (ret) { 839 if (ret) {
919 icd->ops = NULL; 840 v4l2_ctrl_handler_free(&mt9v022->hdl);
920 kfree(mt9v022); 841 kfree(mt9v022);
921 } 842 }
922 843
@@ -926,10 +847,12 @@ static int mt9v022_probe(struct i2c_client *client,
926static int mt9v022_remove(struct i2c_client *client) 847static int mt9v022_remove(struct i2c_client *client)
927{ 848{
928 struct mt9v022 *mt9v022 = to_mt9v022(client); 849 struct mt9v022 *mt9v022 = to_mt9v022(client);
929 struct soc_camera_device *icd = client->dev.platform_data; 850 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
930 851
931 icd->ops = NULL; 852 v4l2_device_unregister_subdev(&mt9v022->subdev);
932 mt9v022_video_remove(icd); 853 if (icl->free_bus)
854 icl->free_bus(icl);
855 v4l2_ctrl_handler_free(&mt9v022->hdl);
933 kfree(mt9v022); 856 kfree(mt9v022);
934 857
935 return 0; 858 return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 087db12a3a67..18e94c7d2be8 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -78,11 +78,10 @@
78#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \ 78#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
79 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT) 79 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
80 80
81#define CSI_BUS_FLAGS (SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \ 81#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
82 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \ 82 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
83 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \ 83 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
84 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \ 84 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
85 SOCAM_DATAWIDTH_8)
86 85
87#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */ 86#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
88 87
@@ -490,59 +489,73 @@ static int mx1_camera_set_crop(struct soc_camera_device *icd,
490 489
491static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 490static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
492{ 491{
492 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
493 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 493 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
494 struct mx1_camera_dev *pcdev = ici->priv; 494 struct mx1_camera_dev *pcdev = ici->priv;
495 unsigned long camera_flags, common_flags; 495 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
496 unsigned long common_flags;
496 unsigned int csicr1; 497 unsigned int csicr1;
497 int ret; 498 int ret;
498 499
499 camera_flags = icd->ops->query_bus_param(icd);
500
501 /* MX1 supports only 8bit buswidth */ 500 /* MX1 supports only 8bit buswidth */
502 common_flags = soc_camera_bus_param_compatible(camera_flags, 501 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
503 CSI_BUS_FLAGS); 502 if (!ret) {
504 if (!common_flags) 503 common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
505 return -EINVAL; 504 if (!common_flags) {
505 dev_warn(icd->parent,
506 "Flags incompatible: camera 0x%x, host 0x%x\n",
507 cfg.flags, CSI_BUS_FLAGS);
508 return -EINVAL;
509 }
510 } else if (ret != -ENOIOCTLCMD) {
511 return ret;
512 } else {
513 common_flags = CSI_BUS_FLAGS;
514 }
506 515
507 /* Make choises, based on platform choice */ 516 /* Make choises, based on platform choice */
508 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 517 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
509 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 518 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
510 if (!pcdev->pdata || 519 if (!pcdev->pdata ||
511 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH) 520 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
512 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 521 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
513 else 522 else
514 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 523 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
515 } 524 }
516 525
517 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 526 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
518 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 527 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
519 if (!pcdev->pdata || 528 if (!pcdev->pdata ||
520 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING) 529 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
521 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 530 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
522 else 531 else
523 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 532 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
524 } 533 }
525 534
526 if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && 535 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
527 (common_flags & SOCAM_DATA_ACTIVE_LOW)) { 536 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
528 if (!pcdev->pdata || 537 if (!pcdev->pdata ||
529 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH) 538 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
530 common_flags &= ~SOCAM_DATA_ACTIVE_LOW; 539 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
531 else 540 else
532 common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; 541 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
533 } 542 }
534 543
535 ret = icd->ops->set_bus_param(icd, common_flags); 544 cfg.flags = common_flags;
536 if (ret < 0) 545 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
546 if (ret < 0 && ret != -ENOIOCTLCMD) {
547 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
548 common_flags, ret);
537 return ret; 549 return ret;
550 }
538 551
539 csicr1 = __raw_readl(pcdev->base + CSICR1); 552 csicr1 = __raw_readl(pcdev->base + CSICR1);
540 553
541 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) 554 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
542 csicr1 |= CSICR1_REDGE; 555 csicr1 |= CSICR1_REDGE;
543 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) 556 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
544 csicr1 |= CSICR1_SOF_POL; 557 csicr1 |= CSICR1_SOF_POL;
545 if (common_flags & SOCAM_DATA_ACTIVE_LOW) 558 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
546 csicr1 |= CSICR1_DATA_POL; 559 csicr1 |= CSICR1_DATA_POL;
547 560
548 __raw_writel(csicr1, pcdev->base + CSICR1); 561 __raw_writel(csicr1, pcdev->base + CSICR1);
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index ec2410c0c806..a803d9ea8fd6 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -686,16 +686,15 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q,
686 icd, &icd->video_lock); 686 icd, &icd->video_lock);
687} 687}
688 688
689#define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ 689#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
690 SOCAM_MASTER | \ 690 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
691 SOCAM_VSYNC_ACTIVE_HIGH | \ 691 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
692 SOCAM_VSYNC_ACTIVE_LOW | \ 692 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
693 SOCAM_HSYNC_ACTIVE_HIGH | \ 693 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
694 SOCAM_HSYNC_ACTIVE_LOW | \ 694 V4L2_MBUS_PCLK_SAMPLE_RISING | \
695 SOCAM_PCLK_SAMPLE_RISING | \ 695 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
696 SOCAM_PCLK_SAMPLE_FALLING | \ 696 V4L2_MBUS_DATA_ACTIVE_HIGH | \
697 SOCAM_DATA_ACTIVE_HIGH | \ 697 V4L2_MBUS_DATA_ACTIVE_LOW)
698 SOCAM_DATA_ACTIVE_LOW)
699 698
700static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev) 699static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
701{ 700{
@@ -770,46 +769,59 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
770static int mx2_camera_set_bus_param(struct soc_camera_device *icd, 769static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
771 __u32 pixfmt) 770 __u32 pixfmt)
772{ 771{
773 struct soc_camera_host *ici = 772 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
774 to_soc_camera_host(icd->parent); 773 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
775 struct mx2_camera_dev *pcdev = ici->priv; 774 struct mx2_camera_dev *pcdev = ici->priv;
776 unsigned long camera_flags, common_flags; 775 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
777 int ret = 0; 776 unsigned long common_flags;
777 int ret;
778 int bytesperline; 778 int bytesperline;
779 u32 csicr1 = pcdev->csicr1; 779 u32 csicr1 = pcdev->csicr1;
780 780
781 camera_flags = icd->ops->query_bus_param(icd); 781 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
782 782 if (!ret) {
783 common_flags = soc_camera_bus_param_compatible(camera_flags, 783 common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
784 MX2_BUS_FLAGS); 784 if (!common_flags) {
785 if (!common_flags) 785 dev_warn(icd->parent,
786 return -EINVAL; 786 "Flags incompatible: camera 0x%x, host 0x%x\n",
787 cfg.flags, MX2_BUS_FLAGS);
788 return -EINVAL;
789 }
790 } else if (ret != -ENOIOCTLCMD) {
791 return ret;
792 } else {
793 common_flags = MX2_BUS_FLAGS;
794 }
787 795
788 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 796 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
789 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 797 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
790 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH) 798 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
791 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 799 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
792 else 800 else
793 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 801 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
794 } 802 }
795 803
796 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 804 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
797 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 805 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
798 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING) 806 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
799 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 807 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
800 else 808 else
801 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 809 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
802 } 810 }
803 811
804 ret = icd->ops->set_bus_param(icd, common_flags); 812 cfg.flags = common_flags;
805 if (ret < 0) 813 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
814 if (ret < 0 && ret != -ENOIOCTLCMD) {
815 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
816 common_flags, ret);
806 return ret; 817 return ret;
818 }
807 819
808 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) 820 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
809 csicr1 |= CSICR1_REDGE; 821 csicr1 |= CSICR1_REDGE;
810 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) 822 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
811 csicr1 |= CSICR1_SOF_POL; 823 csicr1 |= CSICR1_SOF_POL;
812 if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) 824 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
813 csicr1 |= CSICR1_HSYNC_POL; 825 csicr1 |= CSICR1_HSYNC_POL;
814 if (pcdev->platform_flags & MX2_CAMERA_SWAP16) 826 if (pcdev->platform_flags & MX2_CAMERA_SWAP16)
815 csicr1 |= CSICR1_SWAP16_EN; 827 csicr1 |= CSICR1_SWAP16_EN;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index c8e958a07e91..f96f92f00f92 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -109,10 +109,12 @@ struct mx3_camera_dev {
109 109
110 unsigned long platform_flags; 110 unsigned long platform_flags;
111 unsigned long mclk; 111 unsigned long mclk;
112 u16 width_flags; /* max 15 bits */
112 113
113 struct list_head capture; 114 struct list_head capture;
114 spinlock_t lock; /* Protects video buffer lists */ 115 spinlock_t lock; /* Protects video buffer lists */
115 struct mx3_camera_buffer *active; 116 struct mx3_camera_buffer *active;
117 size_t buf_total;
116 struct vb2_alloc_ctx *alloc_ctx; 118 struct vb2_alloc_ctx *alloc_ctx;
117 enum v4l2_field field; 119 enum v4l2_field field;
118 int sequence; 120 int sequence;
@@ -190,79 +192,53 @@ static void mx3_cam_dma_done(void *arg)
190 * Calculate the __buffer__ (not data) size and number of buffers. 192 * Calculate the __buffer__ (not data) size and number of buffers.
191 */ 193 */
192static int mx3_videobuf_setup(struct vb2_queue *vq, 194static int mx3_videobuf_setup(struct vb2_queue *vq,
195 const struct v4l2_format *fmt,
193 unsigned int *count, unsigned int *num_planes, 196 unsigned int *count, unsigned int *num_planes,
194 unsigned int sizes[], void *alloc_ctxs[]) 197 unsigned int sizes[], void *alloc_ctxs[])
195{ 198{
196 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 199 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
197 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 200 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
198 struct mx3_camera_dev *mx3_cam = ici->priv; 201 struct mx3_camera_dev *mx3_cam = ici->priv;
199 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 202 int bytes_per_line;
200 icd->current_fmt->host_fmt); 203 unsigned int height;
201
202 if (bytes_per_line < 0)
203 return bytes_per_line;
204 204
205 if (!mx3_cam->idmac_channel[0]) 205 if (!mx3_cam->idmac_channel[0])
206 return -EINVAL; 206 return -EINVAL;
207 207
208 *num_planes = 1; 208 if (fmt) {
209 209 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
210 mx3_cam->sequence = 0; 210 fmt->fmt.pix.pixelformat);
211 sizes[0] = bytes_per_line * icd->user_height; 211 if (!xlate)
212 alloc_ctxs[0] = mx3_cam->alloc_ctx; 212 return -EINVAL;
213 213 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
214 if (!*count) 214 xlate->host_fmt);
215 *count = 32; 215 height = fmt->fmt.pix.height;
216 216 } else {
217 if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024) 217 /* Called from VIDIOC_REQBUFS or in compatibility mode */
218 *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0]; 218 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
219
220 return 0;
221}
222
223static int mx3_videobuf_prepare(struct vb2_buffer *vb)
224{
225 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
226 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
227 struct mx3_camera_dev *mx3_cam = ici->priv;
228 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
229 struct scatterlist *sg;
230 struct mx3_camera_buffer *buf;
231 size_t new_size;
232 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
233 icd->current_fmt->host_fmt); 219 icd->current_fmt->host_fmt);
234 220 height = icd->user_height;
221 }
235 if (bytes_per_line < 0) 222 if (bytes_per_line < 0)
236 return bytes_per_line; 223 return bytes_per_line;
237 224
238 buf = to_mx3_vb(vb); 225 sizes[0] = bytes_per_line * height;
239 sg = &buf->sg;
240
241 new_size = bytes_per_line * icd->user_height;
242 226
243 if (vb2_plane_size(vb, 0) < new_size) { 227 alloc_ctxs[0] = mx3_cam->alloc_ctx;
244 dev_err(icd->parent, "Buffer too small (%lu < %zu)\n",
245 vb2_plane_size(vb, 0), new_size);
246 return -ENOBUFS;
247 }
248 228
249 if (buf->state == CSI_BUF_NEEDS_INIT) { 229 if (!vq->num_buffers)
250 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); 230 mx3_cam->sequence = 0;
251 sg_dma_len(sg) = new_size;
252 231
253 buf->txd = ichan->dma_chan.device->device_prep_slave_sg( 232 if (!*count)
254 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, 233 *count = 2;
255 DMA_PREP_INTERRUPT);
256 if (!buf->txd)
257 return -EIO;
258
259 buf->txd->callback_param = buf->txd;
260 buf->txd->callback = mx3_cam_dma_done;
261 234
262 buf->state = CSI_BUF_PREPARED; 235 /* If *num_planes != 0, we have already verified *count. */
263 } 236 if (!*num_planes &&
237 sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
238 *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
239 sizes[0];
264 240
265 vb2_set_plane_payload(vb, 0, new_size); 241 *num_planes = 1;
266 242
267 return 0; 243 return 0;
268} 244}
@@ -286,28 +262,58 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
286 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 262 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
287 struct mx3_camera_dev *mx3_cam = ici->priv; 263 struct mx3_camera_dev *mx3_cam = ici->priv;
288 struct mx3_camera_buffer *buf = to_mx3_vb(vb); 264 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
289 struct dma_async_tx_descriptor *txd = buf->txd; 265 struct scatterlist *sg = &buf->sg;
290 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 266 struct dma_async_tx_descriptor *txd;
267 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
291 struct idmac_video_param *video = &ichan->params.video; 268 struct idmac_video_param *video = &ichan->params.video;
292 dma_cookie_t cookie; 269 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
293 u32 fourcc = icd->current_fmt->host_fmt->fourcc; 270 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt);
294 unsigned long flags; 271 unsigned long flags;
272 dma_cookie_t cookie;
273 size_t new_size;
274
275 BUG_ON(bytes_per_line <= 0);
276
277 new_size = bytes_per_line * icd->user_height;
278
279 if (vb2_plane_size(vb, 0) < new_size) {
280 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
281 vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
282 goto error;
283 }
284
285 if (buf->state == CSI_BUF_NEEDS_INIT) {
286 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
287 sg_dma_len(sg) = new_size;
288
289 txd = ichan->dma_chan.device->device_prep_slave_sg(
290 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
291 DMA_PREP_INTERRUPT);
292 if (!txd)
293 goto error;
294
295 txd->callback_param = txd;
296 txd->callback = mx3_cam_dma_done;
297
298 buf->state = CSI_BUF_PREPARED;
299 buf->txd = txd;
300 } else {
301 txd = buf->txd;
302 }
303
304 vb2_set_plane_payload(vb, 0, new_size);
295 305
296 /* This is the configuration of one sg-element */ 306 /* This is the configuration of one sg-element */
297 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 307 video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
298 308
299 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) { 309 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
300 /* 310 /*
301 * If the IPU DMA channel is configured to transport 311 * If the IPU DMA channel is configured to transfer generic
302 * generic 8-bit data, we have to set up correctly the 312 * 8-bit data, we have to set up the geometry parameters
303 * geometry parameters upon the current pixel format. 313 * correctly, according to the current pixel format. The DMA
304 * So, since the DMA horizontal parameters are expressed 314 * horizontal parameters in this case are expressed in bytes,
305 * in bytes not pixels, convert these in the right unit. 315 * not in pixels.
306 */ 316 */
307 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
308 icd->current_fmt->host_fmt);
309 BUG_ON(bytes_per_line <= 0);
310
311 video->out_width = bytes_per_line; 317 video->out_width = bytes_per_line;
312 video->out_height = icd->user_height; 318 video->out_height = icd->user_height;
313 video->out_stride = bytes_per_line; 319 video->out_stride = bytes_per_line;
@@ -351,6 +357,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
351 mx3_cam->active = NULL; 357 mx3_cam->active = NULL;
352 358
353 spin_unlock_irqrestore(&mx3_cam->lock, flags); 359 spin_unlock_irqrestore(&mx3_cam->lock, flags);
360error:
354 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 361 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
355} 362}
356 363
@@ -384,17 +391,24 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
384 } 391 }
385 392
386 spin_unlock_irqrestore(&mx3_cam->lock, flags); 393 spin_unlock_irqrestore(&mx3_cam->lock, flags);
394
395 mx3_cam->buf_total -= vb2_plane_size(vb, 0);
387} 396}
388 397
389static int mx3_videobuf_init(struct vb2_buffer *vb) 398static int mx3_videobuf_init(struct vb2_buffer *vb)
390{ 399{
400 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
401 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
402 struct mx3_camera_dev *mx3_cam = ici->priv;
391 struct mx3_camera_buffer *buf = to_mx3_vb(vb); 403 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
404
392 /* This is for locking debugging only */ 405 /* This is for locking debugging only */
393 INIT_LIST_HEAD(&buf->queue); 406 INIT_LIST_HEAD(&buf->queue);
394 sg_init_table(&buf->sg, 1); 407 sg_init_table(&buf->sg, 1);
395 408
396 buf->state = CSI_BUF_NEEDS_INIT; 409 buf->state = CSI_BUF_NEEDS_INIT;
397 buf->txd = NULL; 410
411 mx3_cam->buf_total += vb2_plane_size(vb, 0);
398 412
399 return 0; 413 return 0;
400} 414}
@@ -405,13 +419,12 @@ static int mx3_stop_streaming(struct vb2_queue *q)
405 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 419 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
406 struct mx3_camera_dev *mx3_cam = ici->priv; 420 struct mx3_camera_dev *mx3_cam = ici->priv;
407 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 421 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
408 struct dma_chan *chan;
409 struct mx3_camera_buffer *buf, *tmp; 422 struct mx3_camera_buffer *buf, *tmp;
410 unsigned long flags; 423 unsigned long flags;
411 424
412 if (ichan) { 425 if (ichan) {
413 chan = &ichan->dma_chan; 426 struct dma_chan *chan = &ichan->dma_chan;
414 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); 427 chan->device->device_control(chan, DMA_PAUSE, 0);
415 } 428 }
416 429
417 spin_lock_irqsave(&mx3_cam->lock, flags); 430 spin_lock_irqsave(&mx3_cam->lock, flags);
@@ -419,8 +432,8 @@ static int mx3_stop_streaming(struct vb2_queue *q)
419 mx3_cam->active = NULL; 432 mx3_cam->active = NULL;
420 433
421 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) { 434 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
422 buf->state = CSI_BUF_NEEDS_INIT;
423 list_del_init(&buf->queue); 435 list_del_init(&buf->queue);
436 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
424 } 437 }
425 438
426 spin_unlock_irqrestore(&mx3_cam->lock, flags); 439 spin_unlock_irqrestore(&mx3_cam->lock, flags);
@@ -430,7 +443,6 @@ static int mx3_stop_streaming(struct vb2_queue *q)
430 443
431static struct vb2_ops mx3_videobuf_ops = { 444static struct vb2_ops mx3_videobuf_ops = {
432 .queue_setup = mx3_videobuf_setup, 445 .queue_setup = mx3_videobuf_setup,
433 .buf_prepare = mx3_videobuf_prepare,
434 .buf_queue = mx3_videobuf_queue, 446 .buf_queue = mx3_videobuf_queue,
435 .buf_cleanup = mx3_videobuf_release, 447 .buf_cleanup = mx3_videobuf_release,
436 .buf_init = mx3_videobuf_init, 448 .buf_init = mx3_videobuf_init,
@@ -514,6 +526,7 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
514 526
515 mx3_camera_activate(mx3_cam, icd); 527 mx3_camera_activate(mx3_cam, icd);
516 528
529 mx3_cam->buf_total = 0;
517 mx3_cam->icd = icd; 530 mx3_cam->icd = icd;
518 531
519 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n", 532 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
@@ -548,58 +561,27 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
548 unsigned char buswidth, unsigned long *flags) 561 unsigned char buswidth, unsigned long *flags)
549{ 562{
550 /* 563 /*
564 * If requested data width is supported by the platform, use it or any
565 * possible lower value - i.MX31 is smart enough to shift bits
566 */
567 if (buswidth > fls(mx3_cam->width_flags))
568 return -EINVAL;
569
570 /*
551 * Platform specified synchronization and pixel clock polarities are 571 * Platform specified synchronization and pixel clock polarities are
552 * only a recommendation and are only used during probing. MX3x 572 * only a recommendation and are only used during probing. MX3x
553 * camera interface only works in master mode, i.e., uses HSYNC and 573 * camera interface only works in master mode, i.e., uses HSYNC and
554 * VSYNC signals from the sensor 574 * VSYNC signals from the sensor
555 */ 575 */
556 *flags = SOCAM_MASTER | 576 *flags = V4L2_MBUS_MASTER |
557 SOCAM_HSYNC_ACTIVE_HIGH | 577 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
558 SOCAM_HSYNC_ACTIVE_LOW | 578 V4L2_MBUS_HSYNC_ACTIVE_LOW |
559 SOCAM_VSYNC_ACTIVE_HIGH | 579 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
560 SOCAM_VSYNC_ACTIVE_LOW | 580 V4L2_MBUS_VSYNC_ACTIVE_LOW |
561 SOCAM_PCLK_SAMPLE_RISING | 581 V4L2_MBUS_PCLK_SAMPLE_RISING |
562 SOCAM_PCLK_SAMPLE_FALLING | 582 V4L2_MBUS_PCLK_SAMPLE_FALLING |
563 SOCAM_DATA_ACTIVE_HIGH | 583 V4L2_MBUS_DATA_ACTIVE_HIGH |
564 SOCAM_DATA_ACTIVE_LOW; 584 V4L2_MBUS_DATA_ACTIVE_LOW;
565
566 /*
567 * If requested data width is supported by the platform, use it or any
568 * possible lower value - i.MX31 is smart enough to schift bits
569 */
570 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
571 *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
572 SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
573 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
574 *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
575 SOCAM_DATAWIDTH_4;
576 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
577 *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
578 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
579 *flags |= SOCAM_DATAWIDTH_4;
580
581 switch (buswidth) {
582 case 15:
583 if (!(*flags & SOCAM_DATAWIDTH_15))
584 return -EINVAL;
585 break;
586 case 10:
587 if (!(*flags & SOCAM_DATAWIDTH_10))
588 return -EINVAL;
589 break;
590 case 8:
591 if (!(*flags & SOCAM_DATAWIDTH_8))
592 return -EINVAL;
593 break;
594 case 4:
595 if (!(*flags & SOCAM_DATAWIDTH_4))
596 return -EINVAL;
597 break;
598 default:
599 dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
600 "Unsupported bus width %d\n", buswidth);
601 return -EINVAL;
602 }
603 585
604 return 0; 586 return 0;
605} 587}
@@ -607,9 +589,11 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
607static int mx3_camera_try_bus_param(struct soc_camera_device *icd, 589static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
608 const unsigned int depth) 590 const unsigned int depth)
609{ 591{
592 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
610 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 593 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
611 struct mx3_camera_dev *mx3_cam = ici->priv; 594 struct mx3_camera_dev *mx3_cam = ici->priv;
612 unsigned long bus_flags, camera_flags; 595 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
596 unsigned long bus_flags, common_flags;
613 int ret = test_platform_param(mx3_cam, depth, &bus_flags); 597 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
614 598
615 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret); 599 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
@@ -617,15 +601,21 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
617 if (ret < 0) 601 if (ret < 0)
618 return ret; 602 return ret;
619 603
620 camera_flags = icd->ops->query_bus_param(icd); 604 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
621 605 if (!ret) {
622 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); 606 common_flags = soc_mbus_config_compatible(&cfg,
623 if (ret < 0) 607 bus_flags);
624 dev_warn(icd->parent, 608 if (!common_flags) {
625 "Flags incompatible: camera %lx, host %lx\n", 609 dev_warn(icd->parent,
626 camera_flags, bus_flags); 610 "Flags incompatible: camera 0x%x, host 0x%lx\n",
611 cfg.flags, bus_flags);
612 return -EINVAL;
613 }
614 } else if (ret != -ENOIOCTLCMD) {
615 return ret;
616 }
627 617
628 return ret; 618 return 0;
629} 619}
630 620
631static bool chan_filter(struct dma_chan *chan, void *arg) 621static bool chan_filter(struct dma_chan *chan, void *arg)
@@ -994,9 +984,11 @@ static int mx3_camera_querycap(struct soc_camera_host *ici,
994 984
995static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 985static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
996{ 986{
987 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
997 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 988 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
998 struct mx3_camera_dev *mx3_cam = ici->priv; 989 struct mx3_camera_dev *mx3_cam = ici->priv;
999 unsigned long bus_flags, camera_flags, common_flags; 990 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
991 unsigned long bus_flags, common_flags;
1000 u32 dw, sens_conf; 992 u32 dw, sens_conf;
1001 const struct soc_mbus_pixelfmt *fmt; 993 const struct soc_mbus_pixelfmt *fmt;
1002 int buswidth; 994 int buswidth;
@@ -1008,83 +1000,76 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1008 if (!fmt) 1000 if (!fmt)
1009 return -EINVAL; 1001 return -EINVAL;
1010 1002
1011 buswidth = fmt->bits_per_sample;
1012 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1013
1014 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1003 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1015 if (!xlate) { 1004 if (!xlate) {
1016 dev_warn(dev, "Format %x not found\n", pixfmt); 1005 dev_warn(dev, "Format %x not found\n", pixfmt);
1017 return -EINVAL; 1006 return -EINVAL;
1018 } 1007 }
1019 1008
1009 buswidth = fmt->bits_per_sample;
1010 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1011
1020 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); 1012 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
1021 1013
1022 if (ret < 0) 1014 if (ret < 0)
1023 return ret; 1015 return ret;
1024 1016
1025 camera_flags = icd->ops->query_bus_param(icd); 1017 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1026 1018 if (!ret) {
1027 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 1019 common_flags = soc_mbus_config_compatible(&cfg,
1028 dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n", 1020 bus_flags);
1029 camera_flags, bus_flags, common_flags); 1021 if (!common_flags) {
1030 if (!common_flags) { 1022 dev_warn(icd->parent,
1031 dev_dbg(dev, "no common flags"); 1023 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1032 return -EINVAL; 1024 cfg.flags, bus_flags);
1025 return -EINVAL;
1026 }
1027 } else if (ret != -ENOIOCTLCMD) {
1028 return ret;
1029 } else {
1030 common_flags = bus_flags;
1033 } 1031 }
1034 1032
1033 dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
1034 cfg.flags, bus_flags, common_flags);
1035
1035 /* Make choices, based on platform preferences */ 1036 /* Make choices, based on platform preferences */
1036 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 1037 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1037 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 1038 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1038 if (mx3_cam->platform_flags & MX3_CAMERA_HSP) 1039 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
1039 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 1040 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1040 else 1041 else
1041 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 1042 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1042 } 1043 }
1043 1044
1044 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 1045 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1045 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 1046 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1046 if (mx3_cam->platform_flags & MX3_CAMERA_VSP) 1047 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
1047 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 1048 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1048 else 1049 else
1049 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 1050 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1050 } 1051 }
1051 1052
1052 if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && 1053 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
1053 (common_flags & SOCAM_DATA_ACTIVE_LOW)) { 1054 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
1054 if (mx3_cam->platform_flags & MX3_CAMERA_DP) 1055 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
1055 common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; 1056 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
1056 else 1057 else
1057 common_flags &= ~SOCAM_DATA_ACTIVE_LOW; 1058 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
1058 } 1059 }
1059 1060
1060 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1061 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1061 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1062 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1062 if (mx3_cam->platform_flags & MX3_CAMERA_PCP) 1063 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
1063 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1064 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1064 else 1065 else
1065 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1066 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1066 } 1067 }
1067 1068
1068 /* 1069 cfg.flags = common_flags;
1069 * Make the camera work in widest common mode, we'll take care of 1070 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1070 * the rest 1071 if (ret < 0 && ret != -ENOIOCTLCMD) {
1071 */ 1072 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1072 if (common_flags & SOCAM_DATAWIDTH_15)
1073 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1074 SOCAM_DATAWIDTH_15;
1075 else if (common_flags & SOCAM_DATAWIDTH_10)
1076 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1077 SOCAM_DATAWIDTH_10;
1078 else if (common_flags & SOCAM_DATAWIDTH_8)
1079 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1080 SOCAM_DATAWIDTH_8;
1081 else
1082 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1083 SOCAM_DATAWIDTH_4;
1084
1085 ret = icd->ops->set_bus_param(icd, common_flags);
1086 if (ret < 0) {
1087 dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
1088 common_flags, ret); 1073 common_flags, ret);
1089 return ret; 1074 return ret;
1090 } 1075 }
@@ -1108,13 +1093,13 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1108 /* This has been set in mx3_camera_activate(), but we clear it above */ 1093 /* This has been set in mx3_camera_activate(), but we clear it above */
1109 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; 1094 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
1110 1095
1111 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 1096 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1112 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; 1097 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
1113 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 1098 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1114 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; 1099 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
1115 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 1100 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1116 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; 1101 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
1117 if (common_flags & SOCAM_DATA_ACTIVE_LOW) 1102 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
1118 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; 1103 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1119 1104
1120 /* Just do what we're asked to do */ 1105 /* Just do what we're asked to do */
@@ -1199,6 +1184,14 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1199 "data widths, using default 8 bit\n"); 1184 "data widths, using default 8 bit\n");
1200 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; 1185 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
1201 } 1186 }
1187 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
1188 mx3_cam->width_flags = 1 << 3;
1189 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
1190 mx3_cam->width_flags |= 1 << 7;
1191 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
1192 mx3_cam->width_flags |= 1 << 9;
1193 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
1194 mx3_cam->width_flags |= 1 << 14;
1202 1195
1203 mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; 1196 mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
1204 if (!mx3_cam->mclk) { 1197 if (!mx3_cam->mclk) {
@@ -1281,8 +1274,6 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
1281 1274
1282 dmaengine_put(); 1275 dmaengine_put();
1283 1276
1284 dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
1285
1286 return 0; 1277 return 0;
1287} 1278}
1288 1279
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 30d8896bb710..9c5c19f142de 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -833,6 +833,15 @@ static void omap_vout_buffer_release(struct videobuf_queue *q,
833/* 833/*
834 * File operations 834 * File operations
835 */ 835 */
836static unsigned int omap_vout_poll(struct file *file,
837 struct poll_table_struct *wait)
838{
839 struct omap_vout_device *vout = file->private_data;
840 struct videobuf_queue *q = &vout->vbq;
841
842 return videobuf_poll_stream(file, q, wait);
843}
844
836static void omap_vout_vm_open(struct vm_area_struct *vma) 845static void omap_vout_vm_open(struct vm_area_struct *vma)
837{ 846{
838 struct omap_vout_device *vout = vma->vm_private_data; 847 struct omap_vout_device *vout = vma->vm_private_data;
@@ -1861,6 +1870,7 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1861 1870
1862static const struct v4l2_file_operations omap_vout_fops = { 1871static const struct v4l2_file_operations omap_vout_fops = {
1863 .owner = THIS_MODULE, 1872 .owner = THIS_MODULE,
1873 .poll = omap_vout_poll,
1864 .unlocked_ioctl = video_ioctl2, 1874 .unlocked_ioctl = video_ioctl2,
1865 .mmap = omap_vout_mmap, 1875 .mmap = omap_vout_mmap,
1866 .open = omap_vout_open, 1876 .open = omap_vout_open,
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 8a947e603aca..e87ae2f634b2 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -102,10 +102,10 @@
102/* end of OMAP1 Camera Interface registers */ 102/* end of OMAP1 Camera Interface registers */
103 103
104 104
105#define SOCAM_BUS_FLAGS (SOCAM_MASTER | \ 105#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
106 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | \ 106 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
107 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \ 107 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
108 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8) 108 V4L2_MBUS_DATA_ACTIVE_HIGH)
109 109
110 110
111#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1) 111#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
@@ -1438,41 +1438,55 @@ static int omap1_cam_querycap(struct soc_camera_host *ici,
1438static int omap1_cam_set_bus_param(struct soc_camera_device *icd, 1438static int omap1_cam_set_bus_param(struct soc_camera_device *icd,
1439 __u32 pixfmt) 1439 __u32 pixfmt)
1440{ 1440{
1441 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1441 struct device *dev = icd->parent; 1442 struct device *dev = icd->parent;
1442 struct soc_camera_host *ici = to_soc_camera_host(dev); 1443 struct soc_camera_host *ici = to_soc_camera_host(dev);
1443 struct omap1_cam_dev *pcdev = ici->priv; 1444 struct omap1_cam_dev *pcdev = ici->priv;
1444 const struct soc_camera_format_xlate *xlate; 1445 const struct soc_camera_format_xlate *xlate;
1445 const struct soc_mbus_pixelfmt *fmt; 1446 const struct soc_mbus_pixelfmt *fmt;
1446 unsigned long camera_flags, common_flags; 1447 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1448 unsigned long common_flags;
1447 u32 ctrlclock, mode; 1449 u32 ctrlclock, mode;
1448 int ret; 1450 int ret;
1449 1451
1450 camera_flags = icd->ops->query_bus_param(icd); 1452 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1451 1453 if (!ret) {
1452 common_flags = soc_camera_bus_param_compatible(camera_flags, 1454 common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
1453 SOCAM_BUS_FLAGS); 1455 if (!common_flags) {
1454 if (!common_flags) 1456 dev_warn(dev,
1455 return -EINVAL; 1457 "Flags incompatible: camera 0x%x, host 0x%x\n",
1458 cfg.flags, SOCAM_BUS_FLAGS);
1459 return -EINVAL;
1460 }
1461 } else if (ret != -ENOIOCTLCMD) {
1462 return ret;
1463 } else {
1464 common_flags = SOCAM_BUS_FLAGS;
1465 }
1456 1466
1457 /* Make choices, possibly based on platform configuration */ 1467 /* Make choices, possibly based on platform configuration */
1458 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1468 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1459 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1469 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1460 if (!pcdev->pdata || 1470 if (!pcdev->pdata ||
1461 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING) 1471 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
1462 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1472 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1463 else 1473 else
1464 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1474 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1465 } 1475 }
1466 1476
1467 ret = icd->ops->set_bus_param(icd, common_flags); 1477 cfg.flags = common_flags;
1468 if (ret < 0) 1478 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1479 if (ret < 0 && ret != -ENOIOCTLCMD) {
1480 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1481 common_flags, ret);
1469 return ret; 1482 return ret;
1483 }
1470 1484
1471 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); 1485 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
1472 if (ctrlclock & LCLK_EN) 1486 if (ctrlclock & LCLK_EN)
1473 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); 1487 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1474 1488
1475 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) { 1489 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
1476 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n"); 1490 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
1477 ctrlclock |= POLCLK; 1491 ctrlclock |= POLCLK;
1478 } else { 1492 } else {
@@ -1565,10 +1579,10 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1565 pcdev->clk = clk; 1579 pcdev->clk = clk;
1566 1580
1567 pcdev->pdata = pdev->dev.platform_data; 1581 pcdev->pdata = pdev->dev.platform_data;
1568 pcdev->pflags = pcdev->pdata->flags; 1582 if (pcdev->pdata) {
1569 1583 pcdev->pflags = pcdev->pdata->flags;
1570 if (pcdev->pdata)
1571 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000; 1584 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
1585 }
1572 1586
1573 switch (pcdev->camexclk) { 1587 switch (pcdev->camexclk) {
1574 case 6000000: 1588 case 6000000:
@@ -1578,6 +1592,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1578 case 24000000: 1592 case 24000000:
1579 break; 1593 break;
1580 default: 1594 default:
1595 /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
1581 dev_warn(&pdev->dev, 1596 dev_warn(&pdev->dev,
1582 "Incorrect sensor clock frequency %ld kHz, " 1597 "Incorrect sensor clock frequency %ld kHz, "
1583 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, " 1598 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
@@ -1585,8 +1600,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1585 pcdev->pdata->camexclk_khz); 1600 pcdev->pdata->camexclk_khz);
1586 pcdev->camexclk = 0; 1601 pcdev->camexclk = 0;
1587 case 0: 1602 case 0:
1588 dev_info(&pdev->dev, 1603 dev_info(&pdev->dev, "Not providing sensor clock\n");
1589 "Not providing sensor clock\n");
1590 } 1604 }
1591 1605
1592 INIT_LIST_HEAD(&pcdev->capture); 1606 INIT_LIST_HEAD(&pcdev->capture);
@@ -1716,5 +1730,5 @@ MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
1716MODULE_DESCRIPTION("OMAP1 Camera Interface driver"); 1730MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
1717MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); 1731MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
1718MODULE_LICENSE("GPL v2"); 1732MODULE_LICENSE("GPL v2");
1719MODULE_LICENSE(DRIVER_VERSION); 1733MODULE_VERSION(DRIVER_VERSION);
1720MODULE_ALIAS("platform:" DRIVER_NAME); 1734MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
index 678e1252047a..b818cacf420f 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/video/omap3isp/isp.c
@@ -1704,6 +1704,7 @@ static int isp_register_entities(struct isp_device *isp)
1704 isp->media_dev.dev = isp->dev; 1704 isp->media_dev.dev = isp->dev;
1705 strlcpy(isp->media_dev.model, "TI OMAP3 ISP", 1705 strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
1706 sizeof(isp->media_dev.model)); 1706 sizeof(isp->media_dev.model));
1707 isp->media_dev.hw_revision = isp->revision;
1707 isp->media_dev.link_notify = isp_pipeline_link_notify; 1708 isp->media_dev.link_notify = isp_pipeline_link_notify;
1708 ret = media_device_register(&isp->media_dev); 1709 ret = media_device_register(&isp->media_dev);
1709 if (ret < 0) { 1710 if (ret < 0) {
@@ -2210,6 +2211,8 @@ error:
2210 regulator_put(isp->isp_csiphy2.vdd); 2211 regulator_put(isp->isp_csiphy2.vdd);
2211 regulator_put(isp->isp_csiphy1.vdd); 2212 regulator_put(isp->isp_csiphy1.vdd);
2212 platform_set_drvdata(pdev, NULL); 2213 platform_set_drvdata(pdev, NULL);
2214
2215 mutex_destroy(&isp->isp_mutex);
2213 kfree(isp); 2216 kfree(isp);
2214 2217
2215 return ret; 2218 return ret;
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index 253fdcce2df2..b0b0fa5a3572 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1836,7 +1836,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1836 * callers to request an output size bigger than the input size 1836 * callers to request an output size bigger than the input size
1837 * up to the nearest multiple of 16. 1837 * up to the nearest multiple of 16.
1838 */ 1838 */
1839 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15); 1839 fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
1840 fmt->width &= ~15; 1840 fmt->width &= ~15;
1841 fmt->height = clamp_t(u32, height, 32, fmt->height); 1841 fmt->height = clamp_t(u32, height, 32, fmt->height);
1842 break; 1842 break;
@@ -2152,6 +2152,37 @@ static const struct media_entity_operations ccdc_media_ops = {
2152 .link_setup = ccdc_link_setup, 2152 .link_setup = ccdc_link_setup,
2153}; 2153};
2154 2154
2155void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2156{
2157 v4l2_device_unregister_subdev(&ccdc->subdev);
2158 omap3isp_video_unregister(&ccdc->video_out);
2159}
2160
2161int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2162 struct v4l2_device *vdev)
2163{
2164 int ret;
2165
2166 /* Register the subdev and video node. */
2167 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2168 if (ret < 0)
2169 goto error;
2170
2171 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2172 if (ret < 0)
2173 goto error;
2174
2175 return 0;
2176
2177error:
2178 omap3isp_ccdc_unregister_entities(ccdc);
2179 return ret;
2180}
2181
2182/* -----------------------------------------------------------------------------
2183 * ISP CCDC initialisation and cleanup
2184 */
2185
2155/* 2186/*
2156 * ccdc_init_entities - Initialize V4L2 subdev and media entity 2187 * ccdc_init_entities - Initialize V4L2 subdev and media entity
2157 * @ccdc: ISP CCDC module 2188 * @ccdc: ISP CCDC module
@@ -2193,50 +2224,23 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2193 2224
2194 ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); 2225 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2195 if (ret < 0) 2226 if (ret < 0)
2196 return ret; 2227 goto error_video;
2197 2228
2198 /* Connect the CCDC subdev to the video node. */ 2229 /* Connect the CCDC subdev to the video node. */
2199 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, 2230 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2200 &ccdc->video_out.video.entity, 0, 0); 2231 &ccdc->video_out.video.entity, 0, 0);
2201 if (ret < 0) 2232 if (ret < 0)
2202 return ret; 2233 goto error_link;
2203
2204 return 0;
2205}
2206
2207void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2208{
2209 media_entity_cleanup(&ccdc->subdev.entity);
2210
2211 v4l2_device_unregister_subdev(&ccdc->subdev);
2212 omap3isp_video_unregister(&ccdc->video_out);
2213}
2214
2215int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2216 struct v4l2_device *vdev)
2217{
2218 int ret;
2219
2220 /* Register the subdev and video node. */
2221 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2222 if (ret < 0)
2223 goto error;
2224
2225 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2226 if (ret < 0)
2227 goto error;
2228 2234
2229 return 0; 2235 return 0;
2230 2236
2231error: 2237error_link:
2232 omap3isp_ccdc_unregister_entities(ccdc); 2238 omap3isp_video_cleanup(&ccdc->video_out);
2239error_video:
2240 media_entity_cleanup(me);
2233 return ret; 2241 return ret;
2234} 2242}
2235 2243
2236/* -----------------------------------------------------------------------------
2237 * ISP CCDC initialisation and cleanup
2238 */
2239
2240/* 2244/*
2241 * omap3isp_ccdc_init - CCDC module initialization. 2245 * omap3isp_ccdc_init - CCDC module initialization.
2242 * @dev: Device pointer specific to the OMAP3 ISP. 2246 * @dev: Device pointer specific to the OMAP3 ISP.
@@ -2248,6 +2252,7 @@ error:
2248int omap3isp_ccdc_init(struct isp_device *isp) 2252int omap3isp_ccdc_init(struct isp_device *isp)
2249{ 2253{
2250 struct isp_ccdc_device *ccdc = &isp->isp_ccdc; 2254 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2255 int ret;
2251 2256
2252 spin_lock_init(&ccdc->lock); 2257 spin_lock_init(&ccdc->lock);
2253 init_waitqueue_head(&ccdc->wait); 2258 init_waitqueue_head(&ccdc->wait);
@@ -2276,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp)
2276 ccdc->update = OMAP3ISP_CCDC_BLCLAMP; 2281 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2277 ccdc_apply_controls(ccdc); 2282 ccdc_apply_controls(ccdc);
2278 2283
2279 return ccdc_init_entities(ccdc); 2284 ret = ccdc_init_entities(ccdc);
2285 if (ret < 0) {
2286 mutex_destroy(&ccdc->ioctl_lock);
2287 return ret;
2288 }
2289
2290 return 0;
2280} 2291}
2281 2292
2282/* 2293/*
@@ -2287,6 +2298,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
2287{ 2298{
2288 struct isp_ccdc_device *ccdc = &isp->isp_ccdc; 2299 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2289 2300
2301 omap3isp_video_cleanup(&ccdc->video_out);
2302 media_entity_cleanup(&ccdc->subdev.entity);
2303
2290 /* Free LSC requests. As the CCDC is stopped there's no active request, 2304 /* Free LSC requests. As the CCDC is stopped there's no active request,
2291 * so only the pending request and the free queue need to be handled. 2305 * so only the pending request and the free queue need to be handled.
2292 */ 2306 */
@@ -2296,4 +2310,6 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
2296 2310
2297 if (ccdc->fpc.fpcaddr != 0) 2311 if (ccdc->fpc.fpcaddr != 0)
2298 omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr); 2312 omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr);
2313
2314 mutex_destroy(&ccdc->ioctl_lock);
2299} 2315}
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
index fa1d09b0ad98..904ca8c8b17f 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -1032,6 +1032,48 @@ static const struct media_entity_operations ccp2_media_ops = {
1032}; 1032};
1033 1033
1034/* 1034/*
1035 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1036 * @ccp2: Pointer to ISP CCP2 device
1037 */
1038void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1039{
1040 v4l2_device_unregister_subdev(&ccp2->subdev);
1041 omap3isp_video_unregister(&ccp2->video_in);
1042}
1043
1044/*
1045 * omap3isp_ccp2_register_entities - Register the subdev media entity
1046 * @ccp2: Pointer to ISP CCP2 device
1047 * @vdev: Pointer to v4l device
1048 * return negative error code or zero on success
1049 */
1050
1051int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1052 struct v4l2_device *vdev)
1053{
1054 int ret;
1055
1056 /* Register the subdev and video nodes. */
1057 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1058 if (ret < 0)
1059 goto error;
1060
1061 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1062 if (ret < 0)
1063 goto error;
1064
1065 return 0;
1066
1067error:
1068 omap3isp_ccp2_unregister_entities(ccp2);
1069 return ret;
1070}
1071
1072/* -----------------------------------------------------------------------------
1073 * ISP ccp2 initialisation and cleanup
1074 */
1075
1076/*
1035 * ccp2_init_entities - Initialize ccp2 subdev and media entity. 1077 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1036 * @ccp2: Pointer to ISP CCP2 device 1078 * @ccp2: Pointer to ISP CCP2 device
1037 * return negative error code or zero on success 1079 * return negative error code or zero on success
@@ -1083,72 +1125,23 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1083 1125
1084 ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); 1126 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1085 if (ret < 0) 1127 if (ret < 0)
1086 return ret; 1128 goto error_video;
1087 1129
1088 /* Connect the video node to the ccp2 subdev. */ 1130 /* Connect the video node to the ccp2 subdev. */
1089 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, 1131 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1090 &ccp2->subdev.entity, CCP2_PAD_SINK, 0); 1132 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1091 if (ret < 0) 1133 if (ret < 0)
1092 return ret; 1134 goto error_link;
1093 1135
1094 return 0; 1136 return 0;
1095}
1096 1137
1097/* 1138error_link:
1098 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev 1139 omap3isp_video_cleanup(&ccp2->video_in);
1099 * @ccp2: Pointer to ISP CCP2 device 1140error_video:
1100 */
1101void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1102{
1103 media_entity_cleanup(&ccp2->subdev.entity); 1141 media_entity_cleanup(&ccp2->subdev.entity);
1104
1105 v4l2_device_unregister_subdev(&ccp2->subdev);
1106 omap3isp_video_unregister(&ccp2->video_in);
1107}
1108
1109/*
1110 * omap3isp_ccp2_register_entities - Register the subdev media entity
1111 * @ccp2: Pointer to ISP CCP2 device
1112 * @vdev: Pointer to v4l device
1113 * return negative error code or zero on success
1114 */
1115
1116int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1117 struct v4l2_device *vdev)
1118{
1119 int ret;
1120
1121 /* Register the subdev and video nodes. */
1122 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1123 if (ret < 0)
1124 goto error;
1125
1126 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1127 if (ret < 0)
1128 goto error;
1129
1130 return 0;
1131
1132error:
1133 omap3isp_ccp2_unregister_entities(ccp2);
1134 return ret; 1142 return ret;
1135} 1143}
1136 1144
1137/* -----------------------------------------------------------------------------
1138 * ISP ccp2 initialisation and cleanup
1139 */
1140
1141/*
1142 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1143 * @isp : Pointer to ISP device
1144 */
1145void omap3isp_ccp2_cleanup(struct isp_device *isp)
1146{
1147 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1148
1149 regulator_put(ccp2->vdds_csib);
1150}
1151
1152/* 1145/*
1153 * omap3isp_ccp2_init - CCP2 initialization. 1146 * omap3isp_ccp2_init - CCP2 initialization.
1154 * @isp : Pointer to ISP device 1147 * @isp : Pointer to ISP device
@@ -1184,13 +1177,25 @@ int omap3isp_ccp2_init(struct isp_device *isp)
1184 } 1177 }
1185 1178
1186 ret = ccp2_init_entities(ccp2); 1179 ret = ccp2_init_entities(ccp2);
1187 if (ret < 0) 1180 if (ret < 0) {
1188 goto out; 1181 regulator_put(ccp2->vdds_csib);
1182 return ret;
1183 }
1189 1184
1190 ccp2_reset(ccp2); 1185 ccp2_reset(ccp2);
1191out: 1186 return 0;
1192 if (ret) 1187}
1193 omap3isp_ccp2_cleanup(isp);
1194 1188
1195 return ret; 1189/*
1190 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1191 * @isp : Pointer to ISP device
1192 */
1193void omap3isp_ccp2_cleanup(struct isp_device *isp)
1194{
1195 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1196
1197 omap3isp_video_cleanup(&ccp2->video_in);
1198 media_entity_cleanup(&ccp2->subdev.entity);
1199
1200 regulator_put(ccp2->vdds_csib);
1196} 1201}
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
index 69161a682b3d..0c5f1cb9d99d 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -1187,6 +1187,37 @@ static const struct media_entity_operations csi2_media_ops = {
1187 .link_setup = csi2_link_setup, 1187 .link_setup = csi2_link_setup,
1188}; 1188};
1189 1189
1190void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
1191{
1192 v4l2_device_unregister_subdev(&csi2->subdev);
1193 omap3isp_video_unregister(&csi2->video_out);
1194}
1195
1196int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1197 struct v4l2_device *vdev)
1198{
1199 int ret;
1200
1201 /* Register the subdev and video nodes. */
1202 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1203 if (ret < 0)
1204 goto error;
1205
1206 ret = omap3isp_video_register(&csi2->video_out, vdev);
1207 if (ret < 0)
1208 goto error;
1209
1210 return 0;
1211
1212error:
1213 omap3isp_csi2_unregister_entities(csi2);
1214 return ret;
1215}
1216
1217/* -----------------------------------------------------------------------------
1218 * ISP CSI2 initialisation and cleanup
1219 */
1220
1190/* 1221/*
1191 * csi2_init_entities - Initialize subdev and media entity. 1222 * csi2_init_entities - Initialize subdev and media entity.
1192 * @csi2: Pointer to csi2 structure. 1223 * @csi2: Pointer to csi2 structure.
@@ -1228,57 +1259,23 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1228 1259
1229 ret = omap3isp_video_init(&csi2->video_out, "CSI2a"); 1260 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1230 if (ret < 0) 1261 if (ret < 0)
1231 return ret; 1262 goto error_video;
1232 1263
1233 /* Connect the CSI2 subdev to the video node. */ 1264 /* Connect the CSI2 subdev to the video node. */
1234 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, 1265 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1235 &csi2->video_out.video.entity, 0, 0); 1266 &csi2->video_out.video.entity, 0, 0);
1236 if (ret < 0) 1267 if (ret < 0)
1237 return ret; 1268 goto error_link;
1238 1269
1239 return 0; 1270 return 0;
1240}
1241 1271
1242void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2) 1272error_link:
1243{ 1273 omap3isp_video_cleanup(&csi2->video_out);
1274error_video:
1244 media_entity_cleanup(&csi2->subdev.entity); 1275 media_entity_cleanup(&csi2->subdev.entity);
1245
1246 v4l2_device_unregister_subdev(&csi2->subdev);
1247 omap3isp_video_unregister(&csi2->video_out);
1248}
1249
1250int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1251 struct v4l2_device *vdev)
1252{
1253 int ret;
1254
1255 /* Register the subdev and video nodes. */
1256 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1257 if (ret < 0)
1258 goto error;
1259
1260 ret = omap3isp_video_register(&csi2->video_out, vdev);
1261 if (ret < 0)
1262 goto error;
1263
1264 return 0;
1265
1266error:
1267 omap3isp_csi2_unregister_entities(csi2);
1268 return ret; 1276 return ret;
1269} 1277}
1270 1278
1271/* -----------------------------------------------------------------------------
1272 * ISP CSI2 initialisation and cleanup
1273 */
1274
1275/*
1276 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1277 */
1278void omap3isp_csi2_cleanup(struct isp_device *isp)
1279{
1280}
1281
1282/* 1279/*
1283 * omap3isp_csi2_init - Routine for module driver init 1280 * omap3isp_csi2_init - Routine for module driver init
1284 */ 1281 */
@@ -1298,7 +1295,7 @@ int omap3isp_csi2_init(struct isp_device *isp)
1298 1295
1299 ret = csi2_init_entities(csi2a); 1296 ret = csi2_init_entities(csi2a);
1300 if (ret < 0) 1297 if (ret < 0)
1301 goto fail; 1298 return ret;
1302 1299
1303 if (isp->revision == ISP_REVISION_15_0) { 1300 if (isp->revision == ISP_REVISION_15_0) {
1304 csi2c->isp = isp; 1301 csi2c->isp = isp;
@@ -1311,7 +1308,15 @@ int omap3isp_csi2_init(struct isp_device *isp)
1311 } 1308 }
1312 1309
1313 return 0; 1310 return 0;
1314fail: 1311}
1315 omap3isp_csi2_cleanup(isp); 1312
1316 return ret; 1313/*
1314 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1315 */
1316void omap3isp_csi2_cleanup(struct isp_device *isp)
1317{
1318 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1319
1320 omap3isp_video_cleanup(&csi2a->video_out);
1321 media_entity_cleanup(&csi2a->subdev.entity);
1317} 1322}
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
index 8068cefd8d89..a3c76bf18175 100644
--- a/drivers/media/video/omap3isp/isph3a_aewb.c
+++ b/drivers/media/video/omap3isp/isph3a_aewb.c
@@ -370,5 +370,5 @@ void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
370{ 370{
371 kfree(isp->isp_aewb.priv); 371 kfree(isp->isp_aewb.priv);
372 kfree(isp->isp_aewb.recover_priv); 372 kfree(isp->isp_aewb.recover_priv);
373 omap3isp_stat_free(&isp->isp_aewb); 373 omap3isp_stat_cleanup(&isp->isp_aewb);
374} 374}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
index ba54d0acdecf..58e0bc414899 100644
--- a/drivers/media/video/omap3isp/isph3a_af.c
+++ b/drivers/media/video/omap3isp/isph3a_af.c
@@ -425,5 +425,5 @@ void omap3isp_h3a_af_cleanup(struct isp_device *isp)
425{ 425{
426 kfree(isp->isp_af.priv); 426 kfree(isp->isp_af.priv);
427 kfree(isp->isp_af.recover_priv); 427 kfree(isp->isp_af.recover_priv);
428 omap3isp_stat_free(&isp->isp_af); 428 omap3isp_stat_cleanup(&isp->isp_af);
429} 429}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
index 1743856b30d1..1163907bcddc 100644
--- a/drivers/media/video/omap3isp/isphist.c
+++ b/drivers/media/video/omap3isp/isphist.c
@@ -516,5 +516,5 @@ void omap3isp_hist_cleanup(struct isp_device *isp)
516 if (HIST_USING_DMA(&isp->isp_hist)) 516 if (HIST_USING_DMA(&isp->isp_hist))
517 omap_free_dma(isp->isp_hist.dma_ch); 517 omap_free_dma(isp->isp_hist.dma_ch);
518 kfree(isp->isp_hist.priv); 518 kfree(isp->isp_hist.priv);
519 omap3isp_stat_free(&isp->isp_hist); 519 omap3isp_stat_cleanup(&isp->isp_hist);
520} 520}
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index aba537af87e4..ccb876fe023f 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -76,9 +76,51 @@ static struct omap3isp_prev_csc flr_prev_csc = {
76 76
77#define DEF_DETECT_CORRECT_VAL 0xe 77#define DEF_DETECT_CORRECT_VAL 0xe
78 78
79#define PREV_MIN_WIDTH 64 79/*
80#define PREV_MIN_HEIGHT 8 80 * Margins and image size limits.
81#define PREV_MAX_HEIGHT 16384 81 *
82 * The preview engine crops several rows and columns internally depending on
83 * which filters are enabled. To avoid format changes when the filters are
84 * enabled or disabled (which would prevent them from being turned on or off
85 * during streaming), the driver assumes all the filters are enabled when
86 * computing sink crop and source format limits.
87 *
88 * If a filter is disabled, additional cropping is automatically added at the
89 * preview engine input by the driver to avoid overflow at line and frame end.
90 * This is completely transparent for applications.
91 *
92 * Median filter 4 pixels
93 * Noise filter,
94 * Faulty pixels correction 4 pixels, 4 lines
95 * CFA filter 4 pixels, 4 lines in Bayer mode
96 * 2 lines in other modes
97 * Color suppression 2 pixels
98 * or luma enhancement
99 * -------------------------------------------------------------
100 * Maximum total 14 pixels, 8 lines
101 *
102 * The color suppression and luma enhancement filters are applied after bayer to
103 * YUV conversion. They thus can crop one pixel on the left and one pixel on the
104 * right side of the image without changing the color pattern. When both those
105 * filters are disabled, the driver must crop the two pixels on the same side of
106 * the image to avoid changing the bayer pattern. The left margin is thus set to
107 * 8 pixels and the right margin to 6 pixels.
108 */
109
110#define PREV_MARGIN_LEFT 8
111#define PREV_MARGIN_RIGHT 6
112#define PREV_MARGIN_TOP 4
113#define PREV_MARGIN_BOTTOM 4
114
115#define PREV_MIN_IN_WIDTH 64
116#define PREV_MIN_IN_HEIGHT 8
117#define PREV_MAX_IN_HEIGHT 16384
118
119#define PREV_MIN_OUT_WIDTH 0
120#define PREV_MIN_OUT_HEIGHT 0
121#define PREV_MAX_OUT_WIDTH 1280
122#define PREV_MAX_OUT_WIDTH_ES2 3300
123#define PREV_MAX_OUT_WIDTH_3630 4096
82 124
83/* 125/*
84 * Coeficient Tables for the submodules in Preview. 126 * Coeficient Tables for the submodules in Preview.
@@ -979,52 +1021,36 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
979 * enabled when reporting source pad formats to userspace. If this assumption is 1021 * enabled when reporting source pad formats to userspace. If this assumption is
980 * not true, rows and columns must be manually cropped at the preview engine 1022 * not true, rows and columns must be manually cropped at the preview engine
981 * input to avoid overflows at the end of lines and frames. 1023 * input to avoid overflows at the end of lines and frames.
1024 *
1025 * See the explanation at the PREV_MARGIN_* definitions for more details.
982 */ 1026 */
983static void preview_config_input_size(struct isp_prev_device *prev) 1027static void preview_config_input_size(struct isp_prev_device *prev)
984{ 1028{
985 struct isp_device *isp = to_isp_device(prev); 1029 struct isp_device *isp = to_isp_device(prev);
986 struct prev_params *params = &prev->params; 1030 struct prev_params *params = &prev->params;
987 struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK]; 1031 unsigned int sph = prev->crop.left;
988 unsigned int sph = 0; 1032 unsigned int eph = prev->crop.left + prev->crop.width - 1;
989 unsigned int eph = format->width - 1; 1033 unsigned int slv = prev->crop.top;
990 unsigned int slv = 0; 1034 unsigned int elv = prev->crop.top + prev->crop.height - 1;
991 unsigned int elv = format->height - 1; 1035
992 1036 if (params->features & PREV_CFA) {
993 if (prev->input == PREVIEW_INPUT_CCDC) { 1037 sph -= 2;
994 sph += 2; 1038 eph += 2;
995 eph -= 2; 1039 slv -= 2;
1040 elv += 2;
996 } 1041 }
997 1042 if (params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER)) {
998 /* 1043 sph -= 2;
999 * Median filter 4 pixels 1044 eph += 2;
1000 * Noise filter 4 pixels, 4 lines 1045 slv -= 2;
1001 * or faulty pixels correction 1046 elv += 2;
1002 * CFA filter 4 pixels, 4 lines in Bayer mode
1003 * 2 lines in other modes
1004 * Color suppression 2 pixels
1005 * or luma enhancement
1006 * -------------------------------------------------------------
1007 * Maximum total 14 pixels, 8 lines
1008 */
1009
1010 if (!(params->features & PREV_CFA)) {
1011 sph += 2;
1012 eph -= 2;
1013 slv += 2;
1014 elv -= 2;
1015 } 1047 }
1016 if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) { 1048 if (params->features & PREV_HORZ_MEDIAN_FILTER) {
1017 sph += 2; 1049 sph -= 2;
1018 eph -= 2; 1050 eph += 2;
1019 slv += 2;
1020 elv -= 2;
1021 } 1051 }
1022 if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) { 1052 if (params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE))
1023 sph += 2; 1053 sph -= 2;
1024 eph -= 2;
1025 }
1026 if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)))
1027 sph += 2;
1028 1054
1029 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, 1055 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
1030 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO); 1056 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
@@ -1228,7 +1254,6 @@ static void preview_init_params(struct isp_prev_device *prev)
1228 /* Init values */ 1254 /* Init values */
1229 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS; 1255 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
1230 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS; 1256 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
1231 params->average = NO_AVE;
1232 params->cfa.format = OMAP3ISP_CFAFMT_BAYER; 1257 params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
1233 memcpy(params->cfa.table, cfa_coef_table, 1258 memcpy(params->cfa.table, cfa_coef_table,
1234 sizeof(params->cfa.table)); 1259 sizeof(params->cfa.table));
@@ -1281,14 +1306,14 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev)
1281 1306
1282 switch (isp->revision) { 1307 switch (isp->revision) {
1283 case ISP_REVISION_1_0: 1308 case ISP_REVISION_1_0:
1284 return ISPPRV_MAXOUTPUT_WIDTH; 1309 return PREV_MAX_OUT_WIDTH;
1285 1310
1286 case ISP_REVISION_2_0: 1311 case ISP_REVISION_2_0:
1287 default: 1312 default:
1288 return ISPPRV_MAXOUTPUT_WIDTH_ES2; 1313 return PREV_MAX_OUT_WIDTH_ES2;
1289 1314
1290 case ISP_REVISION_15_0: 1315 case ISP_REVISION_15_0:
1291 return ISPPRV_MAXOUTPUT_WIDTH_3630; 1316 return PREV_MAX_OUT_WIDTH_3630;
1292 } 1317 }
1293} 1318}
1294 1319
@@ -1296,8 +1321,6 @@ static void preview_configure(struct isp_prev_device *prev)
1296{ 1321{
1297 struct isp_device *isp = to_isp_device(prev); 1322 struct isp_device *isp = to_isp_device(prev);
1298 struct v4l2_mbus_framefmt *format; 1323 struct v4l2_mbus_framefmt *format;
1299 unsigned int max_out_width;
1300 unsigned int format_avg;
1301 1324
1302 preview_setup_hw(prev); 1325 preview_setup_hw(prev);
1303 1326
@@ -1335,10 +1358,7 @@ static void preview_configure(struct isp_prev_device *prev)
1335 preview_config_outlineoffset(prev, 1358 preview_config_outlineoffset(prev,
1336 ALIGN(format->width, 0x10) * 2); 1359 ALIGN(format->width, 0x10) * 2);
1337 1360
1338 max_out_width = preview_max_out_width(prev); 1361 preview_config_averager(prev, 0);
1339
1340 format_avg = fls(DIV_ROUND_UP(format->width, max_out_width) - 1);
1341 preview_config_averager(prev, format_avg);
1342 preview_config_ycpos(prev, format->code); 1362 preview_config_ycpos(prev, format->code);
1343} 1363}
1344 1364
@@ -1597,6 +1617,16 @@ __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1597 return &prev->formats[pad]; 1617 return &prev->formats[pad];
1598} 1618}
1599 1619
1620static struct v4l2_rect *
1621__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1622 enum v4l2_subdev_format_whence which)
1623{
1624 if (which == V4L2_SUBDEV_FORMAT_TRY)
1625 return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK);
1626 else
1627 return &prev->crop;
1628}
1629
1600/* previewer format descriptions */ 1630/* previewer format descriptions */
1601static const unsigned int preview_input_fmts[] = { 1631static const unsigned int preview_input_fmts[] = {
1602 V4L2_MBUS_FMT_SGRBG10_1X10, 1632 V4L2_MBUS_FMT_SGRBG10_1X10,
@@ -1611,24 +1641,25 @@ static const unsigned int preview_output_fmts[] = {
1611}; 1641};
1612 1642
1613/* 1643/*
1614 * preview_try_format - Handle try format by pad subdev method 1644 * preview_try_format - Validate a format
1615 * @prev: ISP preview device 1645 * @prev: ISP preview engine
1616 * @fh : V4L2 subdev file handle 1646 * @fh: V4L2 subdev file handle
1617 * @pad: pad num 1647 * @pad: pad number
1618 * @fmt: pointer to v4l2 format structure 1648 * @fmt: format to be validated
1649 * @which: try/active format selector
1650 *
1651 * Validate and adjust the given format for the given pad based on the preview
1652 * engine limits and the format and crop rectangles on other pads.
1619 */ 1653 */
1620static void preview_try_format(struct isp_prev_device *prev, 1654static void preview_try_format(struct isp_prev_device *prev,
1621 struct v4l2_subdev_fh *fh, unsigned int pad, 1655 struct v4l2_subdev_fh *fh, unsigned int pad,
1622 struct v4l2_mbus_framefmt *fmt, 1656 struct v4l2_mbus_framefmt *fmt,
1623 enum v4l2_subdev_format_whence which) 1657 enum v4l2_subdev_format_whence which)
1624{ 1658{
1625 struct v4l2_mbus_framefmt *format;
1626 unsigned int max_out_width;
1627 enum v4l2_mbus_pixelcode pixelcode; 1659 enum v4l2_mbus_pixelcode pixelcode;
1660 struct v4l2_rect *crop;
1628 unsigned int i; 1661 unsigned int i;
1629 1662
1630 max_out_width = preview_max_out_width(prev);
1631
1632 switch (pad) { 1663 switch (pad) {
1633 case PREV_PAD_SINK: 1664 case PREV_PAD_SINK:
1634 /* When reading data from the CCDC, the input size has already 1665 /* When reading data from the CCDC, the input size has already
@@ -1641,10 +1672,11 @@ static void preview_try_format(struct isp_prev_device *prev,
1641 * filter array interpolation. 1672 * filter array interpolation.
1642 */ 1673 */
1643 if (prev->input == PREVIEW_INPUT_MEMORY) { 1674 if (prev->input == PREVIEW_INPUT_MEMORY) {
1644 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_WIDTH, 1675 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_IN_WIDTH,
1645 max_out_width * 8); 1676 preview_max_out_width(prev));
1646 fmt->height = clamp_t(u32, fmt->height, PREV_MIN_HEIGHT, 1677 fmt->height = clamp_t(u32, fmt->height,
1647 PREV_MAX_HEIGHT); 1678 PREV_MIN_IN_HEIGHT,
1679 PREV_MAX_IN_HEIGHT);
1648 } 1680 }
1649 1681
1650 fmt->colorspace = V4L2_COLORSPACE_SRGB; 1682 fmt->colorspace = V4L2_COLORSPACE_SRGB;
@@ -1661,15 +1693,8 @@ static void preview_try_format(struct isp_prev_device *prev,
1661 1693
1662 case PREV_PAD_SOURCE: 1694 case PREV_PAD_SOURCE:
1663 pixelcode = fmt->code; 1695 pixelcode = fmt->code;
1664 format = __preview_get_format(prev, fh, PREV_PAD_SINK, which); 1696 *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which);
1665 memcpy(fmt, format, sizeof(*fmt));
1666 1697
1667 /* The preview module output size is configurable through the
1668 * input interface (horizontal and vertical cropping) and the
1669 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In
1670 * spite of this, hardcode the output size to the biggest
1671 * possible value for simplicity reasons.
1672 */
1673 switch (pixelcode) { 1698 switch (pixelcode) {
1674 case V4L2_MBUS_FMT_YUYV8_1X16: 1699 case V4L2_MBUS_FMT_YUYV8_1X16:
1675 case V4L2_MBUS_FMT_UYVY8_1X16: 1700 case V4L2_MBUS_FMT_UYVY8_1X16:
@@ -1681,31 +1706,14 @@ static void preview_try_format(struct isp_prev_device *prev,
1681 break; 1706 break;
1682 } 1707 }
1683 1708
1684 /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped 1709 /* The preview module output size is configurable through the
1685 * from the left and right sides when the input source is the 1710 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This
1686 * CCDC. This seems not to be needed in practice, investigation 1711 * is not supported yet, hardcode the output size to the crop
1687 * is required. 1712 * rectangle size.
1688 */
1689 if (prev->input == PREVIEW_INPUT_CCDC)
1690 fmt->width -= 4;
1691
1692 /* The preview module can output a maximum of 3312 pixels
1693 * horizontally due to fixed memory-line sizes. Compute the
1694 * horizontal averaging factor accordingly. Note that the limit
1695 * applies to the noise filter and CFA interpolation blocks, so
1696 * it doesn't take cropping by further blocks into account.
1697 *
1698 * ES 1.0 hardware revision is limited to 1280 pixels
1699 * horizontally.
1700 */
1701 fmt->width >>= fls(DIV_ROUND_UP(fmt->width, max_out_width) - 1);
1702
1703 /* Assume that all blocks are enabled and crop pixels and lines
1704 * accordingly. See preview_config_input_size() for more
1705 * information.
1706 */ 1713 */
1707 fmt->width -= 14; 1714 crop = __preview_get_crop(prev, fh, which);
1708 fmt->height -= 8; 1715 fmt->width = crop->width;
1716 fmt->height = crop->height;
1709 1717
1710 fmt->colorspace = V4L2_COLORSPACE_JPEG; 1718 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1711 break; 1719 break;
@@ -1715,6 +1723,49 @@ static void preview_try_format(struct isp_prev_device *prev,
1715} 1723}
1716 1724
1717/* 1725/*
1726 * preview_try_crop - Validate a crop rectangle
1727 * @prev: ISP preview engine
1728 * @sink: format on the sink pad
1729 * @crop: crop rectangle to be validated
1730 *
1731 * The preview engine crops lines and columns for its internal operation,
1732 * depending on which filters are enabled. Enforce minimum crop margins to
1733 * handle that transparently for userspace.
1734 *
1735 * See the explanation at the PREV_MARGIN_* definitions for more details.
1736 */
1737static void preview_try_crop(struct isp_prev_device *prev,
1738 const struct v4l2_mbus_framefmt *sink,
1739 struct v4l2_rect *crop)
1740{
1741 unsigned int left = PREV_MARGIN_LEFT;
1742 unsigned int right = sink->width - PREV_MARGIN_RIGHT;
1743 unsigned int top = PREV_MARGIN_TOP;
1744 unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM;
1745
1746 /* When processing data on-the-fly from the CCDC, at least 2 pixels must
1747 * be cropped from the left and right sides of the image. As we don't
1748 * know which filters will be enabled, increase the left and right
1749 * margins by two.
1750 */
1751 if (prev->input == PREVIEW_INPUT_CCDC) {
1752 left += 2;
1753 right -= 2;
1754 }
1755
1756 /* Restrict left/top to even values to keep the Bayer pattern. */
1757 crop->left &= ~1;
1758 crop->top &= ~1;
1759
1760 crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH);
1761 crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT);
1762 crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH,
1763 right - crop->left);
1764 crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT,
1765 bottom - crop->top);
1766}
1767
1768/*
1718 * preview_enum_mbus_code - Handle pixel format enumeration 1769 * preview_enum_mbus_code - Handle pixel format enumeration
1719 * @sd : pointer to v4l2 subdev structure 1770 * @sd : pointer to v4l2 subdev structure
1720 * @fh : V4L2 subdev file handle 1771 * @fh : V4L2 subdev file handle
@@ -1776,6 +1827,60 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1776} 1827}
1777 1828
1778/* 1829/*
1830 * preview_get_crop - Retrieve the crop rectangle on a pad
1831 * @sd: ISP preview V4L2 subdevice
1832 * @fh: V4L2 subdev file handle
1833 * @crop: crop rectangle
1834 *
1835 * Return 0 on success or a negative error code otherwise.
1836 */
1837static int preview_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1838 struct v4l2_subdev_crop *crop)
1839{
1840 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1841
1842 /* Cropping is only supported on the sink pad. */
1843 if (crop->pad != PREV_PAD_SINK)
1844 return -EINVAL;
1845
1846 crop->rect = *__preview_get_crop(prev, fh, crop->which);
1847 return 0;
1848}
1849
1850/*
1851 * preview_set_crop - Retrieve the crop rectangle on a pad
1852 * @sd: ISP preview V4L2 subdevice
1853 * @fh: V4L2 subdev file handle
1854 * @crop: crop rectangle
1855 *
1856 * Return 0 on success or a negative error code otherwise.
1857 */
1858static int preview_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1859 struct v4l2_subdev_crop *crop)
1860{
1861 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1862 struct v4l2_mbus_framefmt *format;
1863
1864 /* Cropping is only supported on the sink pad. */
1865 if (crop->pad != PREV_PAD_SINK)
1866 return -EINVAL;
1867
1868 /* The crop rectangle can't be changed while streaming. */
1869 if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
1870 return -EBUSY;
1871
1872 format = __preview_get_format(prev, fh, PREV_PAD_SINK, crop->which);
1873 preview_try_crop(prev, format, &crop->rect);
1874 *__preview_get_crop(prev, fh, crop->which) = crop->rect;
1875
1876 /* Update the source format. */
1877 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, crop->which);
1878 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, crop->which);
1879
1880 return 0;
1881}
1882
1883/*
1779 * preview_get_format - Handle get format by pads subdev method 1884 * preview_get_format - Handle get format by pads subdev method
1780 * @sd : pointer to v4l2 subdev structure 1885 * @sd : pointer to v4l2 subdev structure
1781 * @fh : V4L2 subdev file handle 1886 * @fh : V4L2 subdev file handle
@@ -1808,6 +1913,7 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1808{ 1913{
1809 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1914 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1810 struct v4l2_mbus_framefmt *format; 1915 struct v4l2_mbus_framefmt *format;
1916 struct v4l2_rect *crop;
1811 1917
1812 format = __preview_get_format(prev, fh, fmt->pad, fmt->which); 1918 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1813 if (format == NULL) 1919 if (format == NULL)
@@ -1818,9 +1924,18 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1818 1924
1819 /* Propagate the format from sink to source */ 1925 /* Propagate the format from sink to source */
1820 if (fmt->pad == PREV_PAD_SINK) { 1926 if (fmt->pad == PREV_PAD_SINK) {
1927 /* Reset the crop rectangle. */
1928 crop = __preview_get_crop(prev, fh, fmt->which);
1929 crop->left = 0;
1930 crop->top = 0;
1931 crop->width = fmt->format.width;
1932 crop->height = fmt->format.height;
1933
1934 preview_try_crop(prev, &fmt->format, crop);
1935
1936 /* Update the source format. */
1821 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, 1937 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
1822 fmt->which); 1938 fmt->which);
1823 *format = fmt->format;
1824 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, 1939 preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
1825 fmt->which); 1940 fmt->which);
1826 } 1941 }
@@ -1869,6 +1984,8 @@ static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
1869 .enum_frame_size = preview_enum_frame_size, 1984 .enum_frame_size = preview_enum_frame_size,
1870 .get_fmt = preview_get_format, 1985 .get_fmt = preview_get_format,
1871 .set_fmt = preview_set_format, 1986 .set_fmt = preview_set_format,
1987 .get_crop = preview_get_crop,
1988 .set_crop = preview_set_crop,
1872}; 1989};
1873 1990
1874/* subdev operations */ 1991/* subdev operations */
@@ -1966,8 +2083,44 @@ static const struct media_entity_operations preview_media_ops = {
1966 .link_setup = preview_link_setup, 2083 .link_setup = preview_link_setup,
1967}; 2084};
1968 2085
2086void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
2087{
2088 v4l2_device_unregister_subdev(&prev->subdev);
2089 omap3isp_video_unregister(&prev->video_in);
2090 omap3isp_video_unregister(&prev->video_out);
2091}
2092
2093int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2094 struct v4l2_device *vdev)
2095{
2096 int ret;
2097
2098 /* Register the subdev and video nodes. */
2099 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2100 if (ret < 0)
2101 goto error;
2102
2103 ret = omap3isp_video_register(&prev->video_in, vdev);
2104 if (ret < 0)
2105 goto error;
2106
2107 ret = omap3isp_video_register(&prev->video_out, vdev);
2108 if (ret < 0)
2109 goto error;
2110
2111 return 0;
2112
2113error:
2114 omap3isp_preview_unregister_entities(prev);
2115 return ret;
2116}
2117
2118/* -----------------------------------------------------------------------------
2119 * ISP previewer initialisation and cleanup
2120 */
2121
1969/* 2122/*
1970 * review_init_entities - Initialize subdev and media entity. 2123 * preview_init_entities - Initialize subdev and media entity.
1971 * @prev : Pointer to preview structure 2124 * @prev : Pointer to preview structure
1972 * return -ENOMEM or zero on success 2125 * return -ENOMEM or zero on success
1973 */ 2126 */
@@ -2024,69 +2177,34 @@ static int preview_init_entities(struct isp_prev_device *prev)
2024 2177
2025 ret = omap3isp_video_init(&prev->video_in, "preview"); 2178 ret = omap3isp_video_init(&prev->video_in, "preview");
2026 if (ret < 0) 2179 if (ret < 0)
2027 return ret; 2180 goto error_video_in;
2028 2181
2029 ret = omap3isp_video_init(&prev->video_out, "preview"); 2182 ret = omap3isp_video_init(&prev->video_out, "preview");
2030 if (ret < 0) 2183 if (ret < 0)
2031 return ret; 2184 goto error_video_out;
2032 2185
2033 /* Connect the video nodes to the previewer subdev. */ 2186 /* Connect the video nodes to the previewer subdev. */
2034 ret = media_entity_create_link(&prev->video_in.video.entity, 0, 2187 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2035 &prev->subdev.entity, PREV_PAD_SINK, 0); 2188 &prev->subdev.entity, PREV_PAD_SINK, 0);
2036 if (ret < 0) 2189 if (ret < 0)
2037 return ret; 2190 goto error_link;
2038 2191
2039 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE, 2192 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2040 &prev->video_out.video.entity, 0, 0); 2193 &prev->video_out.video.entity, 0, 0);
2041 if (ret < 0) 2194 if (ret < 0)
2042 return ret; 2195 goto error_link;
2043 2196
2044 return 0; 2197 return 0;
2045}
2046 2198
2047void omap3isp_preview_unregister_entities(struct isp_prev_device *prev) 2199error_link:
2048{ 2200 omap3isp_video_cleanup(&prev->video_out);
2201error_video_out:
2202 omap3isp_video_cleanup(&prev->video_in);
2203error_video_in:
2049 media_entity_cleanup(&prev->subdev.entity); 2204 media_entity_cleanup(&prev->subdev.entity);
2050
2051 v4l2_device_unregister_subdev(&prev->subdev);
2052 v4l2_ctrl_handler_free(&prev->ctrls);
2053 omap3isp_video_unregister(&prev->video_in);
2054 omap3isp_video_unregister(&prev->video_out);
2055}
2056
2057int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2058 struct v4l2_device *vdev)
2059{
2060 int ret;
2061
2062 /* Register the subdev and video nodes. */
2063 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2064 if (ret < 0)
2065 goto error;
2066
2067 ret = omap3isp_video_register(&prev->video_in, vdev);
2068 if (ret < 0)
2069 goto error;
2070
2071 ret = omap3isp_video_register(&prev->video_out, vdev);
2072 if (ret < 0)
2073 goto error;
2074
2075 return 0;
2076
2077error:
2078 omap3isp_preview_unregister_entities(prev);
2079 return ret; 2205 return ret;
2080} 2206}
2081 2207
2082/* -----------------------------------------------------------------------------
2083 * ISP previewer initialisation and cleanup
2084 */
2085
2086void omap3isp_preview_cleanup(struct isp_device *isp)
2087{
2088}
2089
2090/* 2208/*
2091 * isp_preview_init - Previewer initialization. 2209 * isp_preview_init - Previewer initialization.
2092 * @dev : Pointer to ISP device 2210 * @dev : Pointer to ISP device
@@ -2095,19 +2213,20 @@ void omap3isp_preview_cleanup(struct isp_device *isp)
2095int omap3isp_preview_init(struct isp_device *isp) 2213int omap3isp_preview_init(struct isp_device *isp)
2096{ 2214{
2097 struct isp_prev_device *prev = &isp->isp_prev; 2215 struct isp_prev_device *prev = &isp->isp_prev;
2098 int ret;
2099 2216
2100 spin_lock_init(&prev->lock); 2217 spin_lock_init(&prev->lock);
2101 init_waitqueue_head(&prev->wait); 2218 init_waitqueue_head(&prev->wait);
2102 preview_init_params(prev); 2219 preview_init_params(prev);
2103 2220
2104 ret = preview_init_entities(prev); 2221 return preview_init_entities(prev);
2105 if (ret < 0) 2222}
2106 goto out;
2107 2223
2108out: 2224void omap3isp_preview_cleanup(struct isp_device *isp)
2109 if (ret) 2225{
2110 omap3isp_preview_cleanup(isp); 2226 struct isp_prev_device *prev = &isp->isp_prev;
2111 2227
2112 return ret; 2228 v4l2_ctrl_handler_free(&prev->ctrls);
2229 omap3isp_video_cleanup(&prev->video_in);
2230 omap3isp_video_cleanup(&prev->video_out);
2231 media_entity_cleanup(&prev->subdev.entity);
2113} 2232}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
index fa943bd05c7f..f54e775c2df4 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -45,11 +45,6 @@
45#define ISPPRV_CONTRAST_HIGH 0xFF 45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1 46#define ISPPRV_CONTRAST_UNITS 0x1
47 47
48#define NO_AVE 0x0
49#define AVE_2_PIX 0x1
50#define AVE_4_PIX 0x2
51#define AVE_8_PIX 0x3
52
53/* Features list */ 48/* Features list */
54#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH 49#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH
55#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW 50#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW
@@ -106,7 +101,6 @@ enum preview_ycpos_mode {
106 * @rgb2ycbcr: RGB to ycbcr parameters. 101 * @rgb2ycbcr: RGB to ycbcr parameters.
107 * @hmed: Horizontal median filter. 102 * @hmed: Horizontal median filter.
108 * @yclimit: YC limits parameters. 103 * @yclimit: YC limits parameters.
109 * @average: Downsampling rate for averager.
110 * @contrast: Contrast. 104 * @contrast: Contrast.
111 * @brightness: Brightness. 105 * @brightness: Brightness.
112 */ 106 */
@@ -124,7 +118,6 @@ struct prev_params {
124 struct omap3isp_prev_csc rgb2ycbcr; 118 struct omap3isp_prev_csc rgb2ycbcr;
125 struct omap3isp_prev_hmed hmed; 119 struct omap3isp_prev_hmed hmed;
126 struct omap3isp_prev_yclimit yclimit; 120 struct omap3isp_prev_yclimit yclimit;
127 u8 average;
128 u8 contrast; 121 u8 contrast;
129 u8 brightness; 122 u8 brightness;
130}; 123};
@@ -159,6 +152,7 @@ struct isptables_update {
159 * @subdev: V4L2 subdevice 152 * @subdev: V4L2 subdevice
160 * @pads: Media entity pads 153 * @pads: Media entity pads
161 * @formats: Active formats at the subdev pad 154 * @formats: Active formats at the subdev pad
155 * @crop: Active crop rectangle
162 * @input: Module currently connected to the input pad 156 * @input: Module currently connected to the input pad
163 * @output: Bitmask of the active output 157 * @output: Bitmask of the active output
164 * @video_in: Input video entity 158 * @video_in: Input video entity
@@ -177,6 +171,7 @@ struct isp_prev_device {
177 struct v4l2_subdev subdev; 171 struct v4l2_subdev subdev;
178 struct media_pad pads[PREV_PADS_NUM]; 172 struct media_pad pads[PREV_PADS_NUM];
179 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM]; 173 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
174 struct v4l2_rect crop;
180 175
181 struct v4l2_ctrl_handler ctrls; 176 struct v4l2_ctrl_handler ctrls;
182 177
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
index 69f6af6f6b9c..084ea77d65a7 100644
--- a/drivers/media/video/omap3isp/ispreg.h
+++ b/drivers/media/video/omap3isp/ispreg.h
@@ -402,9 +402,6 @@
402#define ISPPRV_YENH_TABLE_ADDR 0x1000 402#define ISPPRV_YENH_TABLE_ADDR 0x1000
403#define ISPPRV_CFA_TABLE_ADDR 0x1400 403#define ISPPRV_CFA_TABLE_ADDR 0x1400
404 404
405#define ISPPRV_MAXOUTPUT_WIDTH 1280
406#define ISPPRV_MAXOUTPUT_WIDTH_ES2 3300
407#define ISPPRV_MAXOUTPUT_WIDTH_3630 4096
408#define ISPRSZ_MIN_OUTPUT 64 405#define ISPRSZ_MIN_OUTPUT 64
409#define ISPRSZ_MAX_OUTPUT 3312 406#define ISPRSZ_MAX_OUTPUT 3312
410 407
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 0bb0f8cd36f5..50e593bfcfaf 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1608,6 +1608,42 @@ static const struct media_entity_operations resizer_media_ops = {
1608 .link_setup = resizer_link_setup, 1608 .link_setup = resizer_link_setup,
1609}; 1609};
1610 1610
1611void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
1612{
1613 v4l2_device_unregister_subdev(&res->subdev);
1614 omap3isp_video_unregister(&res->video_in);
1615 omap3isp_video_unregister(&res->video_out);
1616}
1617
1618int omap3isp_resizer_register_entities(struct isp_res_device *res,
1619 struct v4l2_device *vdev)
1620{
1621 int ret;
1622
1623 /* Register the subdev and video nodes. */
1624 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1625 if (ret < 0)
1626 goto error;
1627
1628 ret = omap3isp_video_register(&res->video_in, vdev);
1629 if (ret < 0)
1630 goto error;
1631
1632 ret = omap3isp_video_register(&res->video_out, vdev);
1633 if (ret < 0)
1634 goto error;
1635
1636 return 0;
1637
1638error:
1639 omap3isp_resizer_unregister_entities(res);
1640 return ret;
1641}
1642
1643/* -----------------------------------------------------------------------------
1644 * ISP resizer initialization and cleanup
1645 */
1646
1611/* 1647/*
1612 * resizer_init_entities - Initialize resizer subdev and media entity. 1648 * resizer_init_entities - Initialize resizer subdev and media entity.
1613 * @res : Pointer to resizer device structure 1649 * @res : Pointer to resizer device structure
@@ -1652,68 +1688,34 @@ static int resizer_init_entities(struct isp_res_device *res)
1652 1688
1653 ret = omap3isp_video_init(&res->video_in, "resizer"); 1689 ret = omap3isp_video_init(&res->video_in, "resizer");
1654 if (ret < 0) 1690 if (ret < 0)
1655 return ret; 1691 goto error_video_in;
1656 1692
1657 ret = omap3isp_video_init(&res->video_out, "resizer"); 1693 ret = omap3isp_video_init(&res->video_out, "resizer");
1658 if (ret < 0) 1694 if (ret < 0)
1659 return ret; 1695 goto error_video_out;
1660 1696
1661 /* Connect the video nodes to the resizer subdev. */ 1697 /* Connect the video nodes to the resizer subdev. */
1662 ret = media_entity_create_link(&res->video_in.video.entity, 0, 1698 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1663 &res->subdev.entity, RESZ_PAD_SINK, 0); 1699 &res->subdev.entity, RESZ_PAD_SINK, 0);
1664 if (ret < 0) 1700 if (ret < 0)
1665 return ret; 1701 goto error_link;
1666 1702
1667 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE, 1703 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1668 &res->video_out.video.entity, 0, 0); 1704 &res->video_out.video.entity, 0, 0);
1669 if (ret < 0) 1705 if (ret < 0)
1670 return ret; 1706 goto error_link;
1671 1707
1672 return 0; 1708 return 0;
1673}
1674 1709
1675void omap3isp_resizer_unregister_entities(struct isp_res_device *res) 1710error_link:
1676{ 1711 omap3isp_video_cleanup(&res->video_out);
1712error_video_out:
1713 omap3isp_video_cleanup(&res->video_in);
1714error_video_in:
1677 media_entity_cleanup(&res->subdev.entity); 1715 media_entity_cleanup(&res->subdev.entity);
1678
1679 v4l2_device_unregister_subdev(&res->subdev);
1680 omap3isp_video_unregister(&res->video_in);
1681 omap3isp_video_unregister(&res->video_out);
1682}
1683
1684int omap3isp_resizer_register_entities(struct isp_res_device *res,
1685 struct v4l2_device *vdev)
1686{
1687 int ret;
1688
1689 /* Register the subdev and video nodes. */
1690 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1691 if (ret < 0)
1692 goto error;
1693
1694 ret = omap3isp_video_register(&res->video_in, vdev);
1695 if (ret < 0)
1696 goto error;
1697
1698 ret = omap3isp_video_register(&res->video_out, vdev);
1699 if (ret < 0)
1700 goto error;
1701
1702 return 0;
1703
1704error:
1705 omap3isp_resizer_unregister_entities(res);
1706 return ret; 1716 return ret;
1707} 1717}
1708 1718
1709/* -----------------------------------------------------------------------------
1710 * ISP resizer initialization and cleanup
1711 */
1712
1713void omap3isp_resizer_cleanup(struct isp_device *isp)
1714{
1715}
1716
1717/* 1719/*
1718 * isp_resizer_init - Resizer initialization. 1720 * isp_resizer_init - Resizer initialization.
1719 * @isp : Pointer to ISP device 1721 * @isp : Pointer to ISP device
@@ -1722,17 +1724,17 @@ void omap3isp_resizer_cleanup(struct isp_device *isp)
1722int omap3isp_resizer_init(struct isp_device *isp) 1724int omap3isp_resizer_init(struct isp_device *isp)
1723{ 1725{
1724 struct isp_res_device *res = &isp->isp_res; 1726 struct isp_res_device *res = &isp->isp_res;
1725 int ret;
1726 1727
1727 init_waitqueue_head(&res->wait); 1728 init_waitqueue_head(&res->wait);
1728 atomic_set(&res->stopping, 0); 1729 atomic_set(&res->stopping, 0);
1729 ret = resizer_init_entities(res); 1730 return resizer_init_entities(res);
1730 if (ret < 0) 1731}
1731 goto out;
1732 1732
1733out: 1733void omap3isp_resizer_cleanup(struct isp_device *isp)
1734 if (ret) 1734{
1735 omap3isp_resizer_cleanup(isp); 1735 struct isp_res_device *res = &isp->isp_res;
1736 1736
1737 return ret; 1737 omap3isp_video_cleanup(&res->video_in);
1738 omap3isp_video_cleanup(&res->video_out);
1739 media_entity_cleanup(&res->subdev.entity);
1738} 1740}
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
index 732905552261..68d539456c55 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1023,24 +1023,6 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
1023 __stat_isr(stat, 1); 1023 __stat_isr(stat, 1);
1024} 1024}
1025 1025
1026static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1027 const struct v4l2_subdev_ops *sd_ops)
1028{
1029 struct v4l2_subdev *subdev = &stat->subdev;
1030 struct media_entity *me = &subdev->entity;
1031
1032 v4l2_subdev_init(subdev, sd_ops);
1033 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1034 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1035 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1036 v4l2_set_subdevdata(subdev, stat);
1037
1038 stat->pad.flags = MEDIA_PAD_FL_SINK;
1039 me->ops = NULL;
1040
1041 return media_entity_init(me, 1, &stat->pad, 0);
1042}
1043
1044int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, 1026int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1045 struct v4l2_fh *fh, 1027 struct v4l2_fh *fh,
1046 struct v4l2_event_subscription *sub) 1028 struct v4l2_event_subscription *sub)
@@ -1062,7 +1044,6 @@ int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
1062 1044
1063void omap3isp_stat_unregister_entities(struct ispstat *stat) 1045void omap3isp_stat_unregister_entities(struct ispstat *stat)
1064{ 1046{
1065 media_entity_cleanup(&stat->subdev.entity);
1066 v4l2_device_unregister_subdev(&stat->subdev); 1047 v4l2_device_unregister_subdev(&stat->subdev);
1067} 1048}
1068 1049
@@ -1072,21 +1053,50 @@ int omap3isp_stat_register_entities(struct ispstat *stat,
1072 return v4l2_device_register_subdev(vdev, &stat->subdev); 1053 return v4l2_device_register_subdev(vdev, &stat->subdev);
1073} 1054}
1074 1055
1056static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1057 const struct v4l2_subdev_ops *sd_ops)
1058{
1059 struct v4l2_subdev *subdev = &stat->subdev;
1060 struct media_entity *me = &subdev->entity;
1061
1062 v4l2_subdev_init(subdev, sd_ops);
1063 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1064 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1065 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1066 v4l2_set_subdevdata(subdev, stat);
1067
1068 stat->pad.flags = MEDIA_PAD_FL_SINK;
1069 me->ops = NULL;
1070
1071 return media_entity_init(me, 1, &stat->pad, 0);
1072}
1073
1075int omap3isp_stat_init(struct ispstat *stat, const char *name, 1074int omap3isp_stat_init(struct ispstat *stat, const char *name,
1076 const struct v4l2_subdev_ops *sd_ops) 1075 const struct v4l2_subdev_ops *sd_ops)
1077{ 1076{
1077 int ret;
1078
1078 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL); 1079 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1079 if (!stat->buf) 1080 if (!stat->buf)
1080 return -ENOMEM; 1081 return -ENOMEM;
1082
1081 isp_stat_buf_clear(stat); 1083 isp_stat_buf_clear(stat);
1082 mutex_init(&stat->ioctl_lock); 1084 mutex_init(&stat->ioctl_lock);
1083 atomic_set(&stat->buf_err, 0); 1085 atomic_set(&stat->buf_err, 0);
1084 1086
1085 return isp_stat_init_entities(stat, name, sd_ops); 1087 ret = isp_stat_init_entities(stat, name, sd_ops);
1088 if (ret < 0) {
1089 mutex_destroy(&stat->ioctl_lock);
1090 kfree(stat->buf);
1091 }
1092
1093 return ret;
1086} 1094}
1087 1095
1088void omap3isp_stat_free(struct ispstat *stat) 1096void omap3isp_stat_cleanup(struct ispstat *stat)
1089{ 1097{
1098 media_entity_cleanup(&stat->subdev.entity);
1099 mutex_destroy(&stat->ioctl_lock);
1090 isp_stat_bufs_free(stat); 1100 isp_stat_bufs_free(stat);
1091 kfree(stat->buf); 1101 kfree(stat->buf);
1092} 1102}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
index d86da94fa50d..9b7c8654dc8a 100644
--- a/drivers/media/video/omap3isp/ispstat.h
+++ b/drivers/media/video/omap3isp/ispstat.h
@@ -144,7 +144,7 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
144 struct omap3isp_stat_data *data); 144 struct omap3isp_stat_data *data);
145int omap3isp_stat_init(struct ispstat *stat, const char *name, 145int omap3isp_stat_init(struct ispstat *stat, const char *name,
146 const struct v4l2_subdev_ops *sd_ops); 146 const struct v4l2_subdev_ops *sd_ops);
147void omap3isp_stat_free(struct ispstat *stat); 147void omap3isp_stat_cleanup(struct ispstat *stat);
148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, 148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
149 struct v4l2_fh *fh, 149 struct v4l2_fh *fh,
150 struct v4l2_event_subscription *sub); 150 struct v4l2_event_subscription *sub);
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
index 0cb8a9f9d675..d1000723c5ae 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -1325,6 +1325,13 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
1325 return 0; 1325 return 0;
1326} 1326}
1327 1327
1328void omap3isp_video_cleanup(struct isp_video *video)
1329{
1330 media_entity_cleanup(&video->video.entity);
1331 mutex_destroy(&video->stream_lock);
1332 mutex_destroy(&video->mutex);
1333}
1334
1328int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev) 1335int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1329{ 1336{
1330 int ret; 1337 int ret;
@@ -1341,8 +1348,6 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1341 1348
1342void omap3isp_video_unregister(struct isp_video *video) 1349void omap3isp_video_unregister(struct isp_video *video)
1343{ 1350{
1344 if (video_is_registered(&video->video)) { 1351 if (video_is_registered(&video->video))
1345 media_entity_cleanup(&video->video.entity);
1346 video_unregister_device(&video->video); 1352 video_unregister_device(&video->video);
1347 }
1348} 1353}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
index 53160aa24e6e..08cbfa144e6e 100644
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -190,6 +190,7 @@ struct isp_video_fh {
190 container_of(q, struct isp_video_fh, queue) 190 container_of(q, struct isp_video_fh, queue)
191 191
192int omap3isp_video_init(struct isp_video *video, const char *name); 192int omap3isp_video_init(struct isp_video *video, const char *name);
193void omap3isp_video_cleanup(struct isp_video *video);
193int omap3isp_video_register(struct isp_video *video, 194int omap3isp_video_register(struct isp_video *video,
194 struct v4l2_device *vdev); 195 struct v4l2_device *vdev);
195void omap3isp_video_unregister(struct isp_video *video); 196void omap3isp_video_unregister(struct isp_video *video);
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
index 9ce2fa037b94..b5247cb64fde 100644
--- a/drivers/media/video/ov2640.c
+++ b/drivers/media/video/ov2640.c
@@ -18,11 +18,13 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/v4l2-mediabus.h>
21#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23
24#include <media/soc_camera.h>
22#include <media/v4l2-chip-ident.h> 25#include <media/v4l2-chip-ident.h>
23#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
24#include <media/soc_camera.h> 27#include <media/v4l2-ctrls.h>
25#include <media/soc_mediabus.h>
26 28
27#define VAL_SET(x, mask, rshift, lshift) \ 29#define VAL_SET(x, mask, rshift, lshift) \
28 ((((x) >> rshift) & mask) << lshift) 30 ((((x) >> rshift) & mask) << lshift)
@@ -299,12 +301,10 @@ struct ov2640_win_size {
299 301
300struct ov2640_priv { 302struct ov2640_priv {
301 struct v4l2_subdev subdev; 303 struct v4l2_subdev subdev;
302 struct ov2640_camera_info *info; 304 struct v4l2_ctrl_handler hdl;
303 enum v4l2_mbus_pixelcode cfmt_code; 305 enum v4l2_mbus_pixelcode cfmt_code;
304 const struct ov2640_win_size *win; 306 const struct ov2640_win_size *win;
305 int model; 307 int model;
306 u16 flag_vflip:1;
307 u16 flag_hflip:1;
308}; 308};
309 309
310/* 310/*
@@ -610,29 +610,6 @@ static enum v4l2_mbus_pixelcode ov2640_codes[] = {
610}; 610};
611 611
612/* 612/*
613 * Supported controls
614 */
615static const struct v4l2_queryctrl ov2640_controls[] = {
616 {
617 .id = V4L2_CID_VFLIP,
618 .type = V4L2_CTRL_TYPE_BOOLEAN,
619 .name = "Flip Vertically",
620 .minimum = 0,
621 .maximum = 1,
622 .step = 1,
623 .default_value = 0,
624 }, {
625 .id = V4L2_CID_HFLIP,
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
627 .name = "Flip Horizontally",
628 .minimum = 0,
629 .maximum = 1,
630 .step = 1,
631 .default_value = 0,
632 },
633};
634
635/*
636 * General functions 613 * General functions
637 */ 614 */
638static struct ov2640_priv *to_ov2640(const struct i2c_client *client) 615static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
@@ -701,81 +678,23 @@ static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
701 return 0; 678 return 0;
702} 679}
703 680
704static int ov2640_set_bus_param(struct soc_camera_device *icd, 681static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
705 unsigned long flags)
706{
707 struct soc_camera_link *icl = to_soc_camera_link(icd);
708 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
709
710 /* Only one width bit may be set */
711 if (!is_power_of_2(width_flag))
712 return -EINVAL;
713
714 if (icl->set_bus_param)
715 return icl->set_bus_param(icl, width_flag);
716
717 /*
718 * Without board specific bus width settings we support only the
719 * sensors native bus width witch are tested working
720 */
721 if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8))
722 return 0;
723
724 return 0;
725}
726
727static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd)
728{
729 struct soc_camera_link *icl = to_soc_camera_link(icd);
730 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
731 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
732 SOCAM_DATA_ACTIVE_HIGH;
733
734 if (icl->query_bus_param)
735 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
736 else
737 flags |= SOCAM_DATAWIDTH_10;
738
739 return soc_camera_apply_sensor_flags(icl, flags);
740}
741
742static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
743{ 682{
683 struct v4l2_subdev *sd =
684 &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
744 struct i2c_client *client = v4l2_get_subdevdata(sd); 685 struct i2c_client *client = v4l2_get_subdevdata(sd);
745 struct ov2640_priv *priv = to_ov2640(client);
746
747 switch (ctrl->id) {
748 case V4L2_CID_VFLIP:
749 ctrl->value = priv->flag_vflip;
750 break;
751 case V4L2_CID_HFLIP:
752 ctrl->value = priv->flag_hflip;
753 break;
754 }
755 return 0;
756}
757
758static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
759{
760 struct i2c_client *client = v4l2_get_subdevdata(sd);
761 struct ov2640_priv *priv = to_ov2640(client);
762 int ret = 0;
763 u8 val; 686 u8 val;
764 687
765 switch (ctrl->id) { 688 switch (ctrl->id) {
766 case V4L2_CID_VFLIP: 689 case V4L2_CID_VFLIP:
767 val = ctrl->value ? REG04_VFLIP_IMG : 0x00; 690 val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
768 priv->flag_vflip = ctrl->value ? 1 : 0; 691 return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
769 ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
770 break;
771 case V4L2_CID_HFLIP: 692 case V4L2_CID_HFLIP:
772 val = ctrl->value ? REG04_HFLIP_IMG : 0x00; 693 val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
773 priv->flag_hflip = ctrl->value ? 1 : 0; 694 return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
774 ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
775 break;
776 } 695 }
777 696
778 return ret; 697 return -EINVAL;
779} 698}
780 699
781static int ov2640_g_chip_ident(struct v4l2_subdev *sd, 700static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
@@ -1023,18 +942,13 @@ static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
1023 return 0; 942 return 0;
1024} 943}
1025 944
1026static int ov2640_video_probe(struct soc_camera_device *icd, 945static int ov2640_video_probe(struct i2c_client *client)
1027 struct i2c_client *client)
1028{ 946{
1029 struct ov2640_priv *priv = to_ov2640(client); 947 struct ov2640_priv *priv = to_ov2640(client);
1030 u8 pid, ver, midh, midl; 948 u8 pid, ver, midh, midl;
1031 const char *devname; 949 const char *devname;
1032 int ret; 950 int ret;
1033 951
1034 /* We must have a parent by now. And it cannot be a wrong one. */
1035 BUG_ON(!icd->parent ||
1036 to_soc_camera_host(icd->parent)->nr != icd->iface);
1037
1038 /* 952 /*
1039 * check and show product ID and manufacturer ID 953 * check and show product ID and manufacturer ID
1040 */ 954 */
@@ -1060,22 +974,17 @@ static int ov2640_video_probe(struct soc_camera_device *icd,
1060 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 974 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1061 devname, pid, ver, midh, midl); 975 devname, pid, ver, midh, midl);
1062 976
1063 return 0; 977 return v4l2_ctrl_handler_setup(&priv->hdl);
1064 978
1065err: 979err:
1066 return ret; 980 return ret;
1067} 981}
1068 982
1069static struct soc_camera_ops ov2640_ops = { 983static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
1070 .set_bus_param = ov2640_set_bus_param, 984 .s_ctrl = ov2640_s_ctrl,
1071 .query_bus_param = ov2640_query_bus_param,
1072 .controls = ov2640_controls,
1073 .num_controls = ARRAY_SIZE(ov2640_controls),
1074}; 985};
1075 986
1076static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { 987static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1077 .g_ctrl = ov2640_g_ctrl,
1078 .s_ctrl = ov2640_s_ctrl,
1079 .g_chip_ident = ov2640_g_chip_ident, 988 .g_chip_ident = ov2640_g_chip_ident,
1080#ifdef CONFIG_VIDEO_ADV_DEBUG 989#ifdef CONFIG_VIDEO_ADV_DEBUG
1081 .g_register = ov2640_g_register, 990 .g_register = ov2640_g_register,
@@ -1083,6 +992,21 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1083#endif 992#endif
1084}; 993};
1085 994
995static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
996 struct v4l2_mbus_config *cfg)
997{
998 struct i2c_client *client = v4l2_get_subdevdata(sd);
999 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1000
1001 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1002 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1003 V4L2_MBUS_DATA_ACTIVE_HIGH;
1004 cfg->type = V4L2_MBUS_PARALLEL;
1005 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1006
1007 return 0;
1008}
1009
1086static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { 1010static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1087 .s_stream = ov2640_s_stream, 1011 .s_stream = ov2640_s_stream,
1088 .g_mbus_fmt = ov2640_g_fmt, 1012 .g_mbus_fmt = ov2640_g_fmt,
@@ -1091,6 +1015,7 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1091 .cropcap = ov2640_cropcap, 1015 .cropcap = ov2640_cropcap,
1092 .g_crop = ov2640_g_crop, 1016 .g_crop = ov2640_g_crop,
1093 .enum_mbus_fmt = ov2640_enum_fmt, 1017 .enum_mbus_fmt = ov2640_enum_fmt,
1018 .g_mbus_config = ov2640_g_mbus_config,
1094}; 1019};
1095 1020
1096static struct v4l2_subdev_ops ov2640_subdev_ops = { 1021static struct v4l2_subdev_ops ov2640_subdev_ops = {
@@ -1104,18 +1029,11 @@ static struct v4l2_subdev_ops ov2640_subdev_ops = {
1104static int ov2640_probe(struct i2c_client *client, 1029static int ov2640_probe(struct i2c_client *client,
1105 const struct i2c_device_id *did) 1030 const struct i2c_device_id *did)
1106{ 1031{
1107 struct ov2640_priv *priv; 1032 struct ov2640_priv *priv;
1108 struct soc_camera_device *icd = client->dev.platform_data; 1033 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1109 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1034 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1110 struct soc_camera_link *icl; 1035 int ret;
1111 int ret;
1112
1113 if (!icd) {
1114 dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n");
1115 return -EINVAL;
1116 }
1117 1036
1118 icl = to_soc_camera_link(icd);
1119 if (!icl) { 1037 if (!icl) {
1120 dev_err(&adapter->dev, 1038 dev_err(&adapter->dev,
1121 "OV2640: Missing platform_data for driver\n"); 1039 "OV2640: Missing platform_data for driver\n");
@@ -1135,15 +1053,23 @@ static int ov2640_probe(struct i2c_client *client,
1135 return -ENOMEM; 1053 return -ENOMEM;
1136 } 1054 }
1137 1055
1138 priv->info = icl->priv;
1139
1140 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); 1056 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1057 v4l2_ctrl_handler_init(&priv->hdl, 2);
1058 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1059 V4L2_CID_VFLIP, 0, 1, 1, 0);
1060 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1061 V4L2_CID_HFLIP, 0, 1, 1, 0);
1062 priv->subdev.ctrl_handler = &priv->hdl;
1063 if (priv->hdl.error) {
1064 int err = priv->hdl.error;
1141 1065
1142 icd->ops = &ov2640_ops; 1066 kfree(priv);
1067 return err;
1068 }
1143 1069
1144 ret = ov2640_video_probe(icd, client); 1070 ret = ov2640_video_probe(client);
1145 if (ret) { 1071 if (ret) {
1146 icd->ops = NULL; 1072 v4l2_ctrl_handler_free(&priv->hdl);
1147 kfree(priv); 1073 kfree(priv);
1148 } else { 1074 } else {
1149 dev_info(&adapter->dev, "OV2640 Probed\n"); 1075 dev_info(&adapter->dev, "OV2640 Probed\n");
@@ -1155,9 +1081,9 @@ static int ov2640_probe(struct i2c_client *client,
1155static int ov2640_remove(struct i2c_client *client) 1081static int ov2640_remove(struct i2c_client *client)
1156{ 1082{
1157 struct ov2640_priv *priv = to_ov2640(client); 1083 struct ov2640_priv *priv = to_ov2640(client);
1158 struct soc_camera_device *icd = client->dev.platform_data;
1159 1084
1160 icd->ops = NULL; 1085 v4l2_device_unregister_subdev(&priv->subdev);
1086 v4l2_ctrl_handler_free(&priv->hdl);
1161 kfree(priv); 1087 kfree(priv);
1162 return 0; 1088 return 0;
1163} 1089}
diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c
index 349a4ad3ccc1..bb37ec80f274 100644
--- a/drivers/media/video/ov5642.c
+++ b/drivers/media/video/ov5642.c
@@ -14,14 +14,16 @@
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 */ 15 */
16 16
17#include <linux/bitops.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/kernel.h>
19#include <linux/slab.h> 21#include <linux/slab.h>
20#include <linux/videodev2.h> 22#include <linux/videodev2.h>
21#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/v4l2-mediabus.h>
22 25
23#include <media/soc_camera.h> 26#include <media/soc_camera.h>
24#include <media/soc_mediabus.h>
25#include <media/v4l2-chip-ident.h> 27#include <media/v4l2-chip-ident.h>
26#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
27 29
@@ -35,7 +37,7 @@
35#define REG_WINDOW_START_Y_LOW 0x3803 37#define REG_WINDOW_START_Y_LOW 0x3803
36#define REG_WINDOW_WIDTH_HIGH 0x3804 38#define REG_WINDOW_WIDTH_HIGH 0x3804
37#define REG_WINDOW_WIDTH_LOW 0x3805 39#define REG_WINDOW_WIDTH_LOW 0x3805
38#define REG_WINDOW_HEIGHT_HIGH 0x3806 40#define REG_WINDOW_HEIGHT_HIGH 0x3806
39#define REG_WINDOW_HEIGHT_LOW 0x3807 41#define REG_WINDOW_HEIGHT_LOW 0x3807
40#define REG_OUT_WIDTH_HIGH 0x3808 42#define REG_OUT_WIDTH_HIGH 0x3808
41#define REG_OUT_WIDTH_LOW 0x3809 43#define REG_OUT_WIDTH_LOW 0x3809
@@ -45,19 +47,44 @@
45#define REG_OUT_TOTAL_WIDTH_LOW 0x380d 47#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
46#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e 48#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
47#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f 49#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
50#define REG_OUTPUT_FORMAT 0x4300
51#define REG_ISP_CTRL_01 0x5001
52#define REG_AVG_WINDOW_END_X_HIGH 0x5682
53#define REG_AVG_WINDOW_END_X_LOW 0x5683
54#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
55#define REG_AVG_WINDOW_END_Y_LOW 0x5687
56
57/* active pixel array size */
58#define OV5642_SENSOR_SIZE_X 2592
59#define OV5642_SENSOR_SIZE_Y 1944
48 60
49/* 61/*
50 * define standard resolution. 62 * About OV5642 resolution, cropping and binning:
51 * Works currently only for up to 720 lines 63 * This sensor supports it all, at least in the feature description.
52 * eg. 320x240, 640x480, 800x600, 1280x720, 2048x720 64 * Unfortunately, no combination of appropriate registers settings could make
65 * the chip work the intended way. As it works with predefined register lists,
66 * some undocumented registers are presumably changed there to achieve their
67 * goals.
68 * This driver currently only works for resolutions up to 720 lines with a
69 * 1:1 scale. Hopefully these restrictions will be removed in the future.
53 */ 70 */
71#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
72#define OV5642_MAX_HEIGHT 720
54 73
55#define OV5642_WIDTH 1280 74/* default sizes */
56#define OV5642_HEIGHT 720 75#define OV5642_DEFAULT_WIDTH 1280
57#define OV5642_TOTAL_WIDTH 3200 76#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
58#define OV5642_TOTAL_HEIGHT 2000 77
59#define OV5642_SENSOR_SIZE_X 2592 78/* minimum extra blanking */
60#define OV5642_SENSOR_SIZE_Y 1944 79#define BLANKING_EXTRA_WIDTH 500
80#define BLANKING_EXTRA_HEIGHT 20
81
82/*
83 * the sensor's autoexposure is buggy when setting total_height low.
84 * It tries to expose longer than 1 frame period without taking care of it
85 * and this leads to weird output. So we set 1000 lines as minimum.
86 */
87#define BLANKING_MIN_HEIGHT 1000
61 88
62struct regval_list { 89struct regval_list {
63 u16 reg_num; 90 u16 reg_num;
@@ -582,6 +609,11 @@ struct ov5642_datafmt {
582struct ov5642 { 609struct ov5642 {
583 struct v4l2_subdev subdev; 610 struct v4l2_subdev subdev;
584 const struct ov5642_datafmt *fmt; 611 const struct ov5642_datafmt *fmt;
612 struct v4l2_rect crop_rect;
613
614 /* blanking information */
615 int total_width;
616 int total_height;
585}; 617};
586 618
587static const struct ov5642_datafmt ov5642_colour_fmts[] = { 619static const struct ov5642_datafmt ov5642_colour_fmts[] = {
@@ -642,6 +674,21 @@ static int reg_write(struct i2c_client *client, u16 reg, u8 val)
642 674
643 return 0; 675 return 0;
644} 676}
677
678/*
679 * convenience function to write 16 bit register values that are split up
680 * into two consecutive high and low parts
681 */
682static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
683{
684 int ret;
685
686 ret = reg_write(client, reg, val16 >> 8);
687 if (ret)
688 return ret;
689 return reg_write(client, reg + 1, val16 & 0x00ff);
690}
691
645#ifdef CONFIG_VIDEO_ADV_DEBUG 692#ifdef CONFIG_VIDEO_ADV_DEBUG
646static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 693static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
647{ 694{
@@ -685,58 +732,55 @@ static int ov5642_write_array(struct i2c_client *client,
685 return 0; 732 return 0;
686} 733}
687 734
688static int ov5642_set_resolution(struct i2c_client *client) 735static int ov5642_set_resolution(struct v4l2_subdev *sd)
689{ 736{
737 struct i2c_client *client = v4l2_get_subdevdata(sd);
738 struct ov5642 *priv = to_ov5642(client);
739 int width = priv->crop_rect.width;
740 int height = priv->crop_rect.height;
741 int total_width = priv->total_width;
742 int total_height = priv->total_height;
743 int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
744 int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
690 int ret; 745 int ret;
691 u8 start_x_high = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) >> 8;
692 u8 start_x_low = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) & 0xff;
693 u8 start_y_high = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) >> 8;
694 u8 start_y_low = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) & 0xff;
695
696 u8 width_high = OV5642_WIDTH >> 8;
697 u8 width_low = OV5642_WIDTH & 0xff;
698 u8 height_high = OV5642_HEIGHT >> 8;
699 u8 height_low = OV5642_HEIGHT & 0xff;
700
701 u8 total_width_high = OV5642_TOTAL_WIDTH >> 8;
702 u8 total_width_low = OV5642_TOTAL_WIDTH & 0xff;
703 u8 total_height_high = OV5642_TOTAL_HEIGHT >> 8;
704 u8 total_height_low = OV5642_TOTAL_HEIGHT & 0xff;
705
706 ret = reg_write(client, REG_WINDOW_START_X_HIGH, start_x_high);
707 if (!ret)
708 ret = reg_write(client, REG_WINDOW_START_X_LOW, start_x_low);
709 if (!ret)
710 ret = reg_write(client, REG_WINDOW_START_Y_HIGH, start_y_high);
711 if (!ret)
712 ret = reg_write(client, REG_WINDOW_START_Y_LOW, start_y_low);
713 746
747 /*
748 * This should set the starting point for cropping.
749 * Doesn't work so far.
750 */
751 ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
714 if (!ret) 752 if (!ret)
715 ret = reg_write(client, REG_WINDOW_WIDTH_HIGH, width_high); 753 ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
716 if (!ret) 754 if (!ret) {
717 ret = reg_write(client, REG_WINDOW_WIDTH_LOW , width_low); 755 priv->crop_rect.left = start_x;
718 if (!ret) 756 priv->crop_rect.top = start_y;
719 ret = reg_write(client, REG_WINDOW_HEIGHT_HIGH, height_high); 757 }
720 if (!ret)
721 ret = reg_write(client, REG_WINDOW_HEIGHT_LOW, height_low);
722 758
723 if (!ret) 759 if (!ret)
724 ret = reg_write(client, REG_OUT_WIDTH_HIGH, width_high); 760 ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
725 if (!ret) 761 if (!ret)
726 ret = reg_write(client, REG_OUT_WIDTH_LOW , width_low); 762 ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
727 if (!ret) 763 if (ret)
728 ret = reg_write(client, REG_OUT_HEIGHT_HIGH, height_high); 764 return ret;
765 priv->crop_rect.width = width;
766 priv->crop_rect.height = height;
767
768 /* Set the output window size. Only 1:1 scale is supported so far. */
769 ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
729 if (!ret) 770 if (!ret)
730 ret = reg_write(client, REG_OUT_HEIGHT_LOW, height_low); 771 ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
731 772
773 /* Total width = output size + blanking */
732 if (!ret) 774 if (!ret)
733 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width_high); 775 ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
734 if (!ret) 776 if (!ret)
735 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_LOW, total_width_low); 777 ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
778
779 /* Sets the window for AWB calculations */
736 if (!ret) 780 if (!ret)
737 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height_high); 781 ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
738 if (!ret) 782 if (!ret)
739 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_LOW, total_height_low); 783 ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
740 784
741 return ret; 785 return ret;
742} 786}
@@ -744,18 +788,18 @@ static int ov5642_set_resolution(struct i2c_client *client)
744static int ov5642_try_fmt(struct v4l2_subdev *sd, 788static int ov5642_try_fmt(struct v4l2_subdev *sd,
745 struct v4l2_mbus_framefmt *mf) 789 struct v4l2_mbus_framefmt *mf)
746{ 790{
791 struct i2c_client *client = v4l2_get_subdevdata(sd);
792 struct ov5642 *priv = to_ov5642(client);
747 const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code); 793 const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
748 794
749 dev_dbg(sd->v4l2_dev->dev, "%s(%u) width: %u heigth: %u\n", 795 mf->width = priv->crop_rect.width;
750 __func__, mf->code, mf->width, mf->height); 796 mf->height = priv->crop_rect.height;
751 797
752 if (!fmt) { 798 if (!fmt) {
753 mf->code = ov5642_colour_fmts[0].code; 799 mf->code = ov5642_colour_fmts[0].code;
754 mf->colorspace = ov5642_colour_fmts[0].colorspace; 800 mf->colorspace = ov5642_colour_fmts[0].colorspace;
755 } 801 }
756 802
757 mf->width = OV5642_WIDTH;
758 mf->height = OV5642_HEIGHT;
759 mf->field = V4L2_FIELD_NONE; 803 mf->field = V4L2_FIELD_NONE;
760 804
761 return 0; 805 return 0;
@@ -767,20 +811,13 @@ static int ov5642_s_fmt(struct v4l2_subdev *sd,
767 struct i2c_client *client = v4l2_get_subdevdata(sd); 811 struct i2c_client *client = v4l2_get_subdevdata(sd);
768 struct ov5642 *priv = to_ov5642(client); 812 struct ov5642 *priv = to_ov5642(client);
769 813
770 dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
771
772 /* MIPI CSI could have changed the format, double-check */ 814 /* MIPI CSI could have changed the format, double-check */
773 if (!ov5642_find_datafmt(mf->code)) 815 if (!ov5642_find_datafmt(mf->code))
774 return -EINVAL; 816 return -EINVAL;
775 817
776 ov5642_try_fmt(sd, mf); 818 ov5642_try_fmt(sd, mf);
777
778 priv->fmt = ov5642_find_datafmt(mf->code); 819 priv->fmt = ov5642_find_datafmt(mf->code);
779 820
780 ov5642_write_array(client, ov5642_default_regs_init);
781 ov5642_set_resolution(client);
782 ov5642_write_array(client, ov5642_default_regs_finalise);
783
784 return 0; 821 return 0;
785} 822}
786 823
@@ -794,8 +831,8 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd,
794 831
795 mf->code = fmt->code; 832 mf->code = fmt->code;
796 mf->colorspace = fmt->colorspace; 833 mf->colorspace = fmt->colorspace;
797 mf->width = OV5642_WIDTH; 834 mf->width = priv->crop_rect.width;
798 mf->height = OV5642_HEIGHT; 835 mf->height = priv->crop_rect.height;
799 mf->field = V4L2_FIELD_NONE; 836 mf->field = V4L2_FIELD_NONE;
800 837
801 return 0; 838 return 0;
@@ -828,15 +865,44 @@ static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
828 return 0; 865 return 0;
829} 866}
830 867
868static int ov5642_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
869{
870 struct i2c_client *client = v4l2_get_subdevdata(sd);
871 struct ov5642 *priv = to_ov5642(client);
872 struct v4l2_rect *rect = &a->c;
873 int ret;
874
875 v4l_bound_align_image(&rect->width, 48, OV5642_MAX_WIDTH, 1,
876 &rect->height, 32, OV5642_MAX_HEIGHT, 1, 0);
877
878 priv->crop_rect.width = rect->width;
879 priv->crop_rect.height = rect->height;
880 priv->total_width = rect->width + BLANKING_EXTRA_WIDTH;
881 priv->total_height = max_t(int, rect->height +
882 BLANKING_EXTRA_HEIGHT,
883 BLANKING_MIN_HEIGHT);
884 priv->crop_rect.width = rect->width;
885 priv->crop_rect.height = rect->height;
886
887 ret = ov5642_write_array(client, ov5642_default_regs_init);
888 if (!ret)
889 ret = ov5642_set_resolution(sd);
890 if (!ret)
891 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
892
893 return ret;
894}
895
831static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 896static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
832{ 897{
898 struct i2c_client *client = v4l2_get_subdevdata(sd);
899 struct ov5642 *priv = to_ov5642(client);
833 struct v4l2_rect *rect = &a->c; 900 struct v4l2_rect *rect = &a->c;
834 901
835 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 902 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
836 rect->top = 0; 903 return -EINVAL;
837 rect->left = 0; 904
838 rect->width = OV5642_WIDTH; 905 *rect = priv->crop_rect;
839 rect->height = OV5642_HEIGHT;
840 906
841 return 0; 907 return 0;
842} 908}
@@ -845,8 +911,8 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
845{ 911{
846 a->bounds.left = 0; 912 a->bounds.left = 0;
847 a->bounds.top = 0; 913 a->bounds.top = 0;
848 a->bounds.width = OV5642_WIDTH; 914 a->bounds.width = OV5642_MAX_WIDTH;
849 a->bounds.height = OV5642_HEIGHT; 915 a->bounds.height = OV5642_MAX_HEIGHT;
850 a->defrect = a->bounds; 916 a->defrect = a->bounds;
851 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 917 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
852 a->pixelaspect.numerator = 1; 918 a->pixelaspect.numerator = 1;
@@ -855,16 +921,47 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
855 return 0; 921 return 0;
856} 922}
857 923
924static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
925 struct v4l2_mbus_config *cfg)
926{
927 cfg->type = V4L2_MBUS_CSI2;
928 cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
929 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
930
931 return 0;
932}
933
934static int ov5642_s_power(struct v4l2_subdev *sd, int on)
935{
936 struct i2c_client *client;
937 int ret;
938
939 if (!on)
940 return 0;
941
942 client = v4l2_get_subdevdata(sd);
943 ret = ov5642_write_array(client, ov5642_default_regs_init);
944 if (!ret)
945 ret = ov5642_set_resolution(sd);
946 if (!ret)
947 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
948
949 return ret;
950}
951
858static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { 952static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
859 .s_mbus_fmt = ov5642_s_fmt, 953 .s_mbus_fmt = ov5642_s_fmt,
860 .g_mbus_fmt = ov5642_g_fmt, 954 .g_mbus_fmt = ov5642_g_fmt,
861 .try_mbus_fmt = ov5642_try_fmt, 955 .try_mbus_fmt = ov5642_try_fmt,
862 .enum_mbus_fmt = ov5642_enum_fmt, 956 .enum_mbus_fmt = ov5642_enum_fmt,
957 .s_crop = ov5642_s_crop,
863 .g_crop = ov5642_g_crop, 958 .g_crop = ov5642_g_crop,
864 .cropcap = ov5642_cropcap, 959 .cropcap = ov5642_cropcap,
960 .g_mbus_config = ov5642_g_mbus_config,
865}; 961};
866 962
867static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { 963static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
964 .s_power = ov5642_s_power,
868 .g_chip_ident = ov5642_g_chip_ident, 965 .g_chip_ident = ov5642_g_chip_ident,
869#ifdef CONFIG_VIDEO_ADV_DEBUG 966#ifdef CONFIG_VIDEO_ADV_DEBUG
870 .g_register = ov5642_get_register, 967 .g_register = ov5642_get_register,
@@ -877,28 +974,7 @@ static struct v4l2_subdev_ops ov5642_subdev_ops = {
877 .video = &ov5642_subdev_video_ops, 974 .video = &ov5642_subdev_video_ops,
878}; 975};
879 976
880/* 977static int ov5642_video_probe(struct i2c_client *client)
881 * We have to provide soc-camera operations, but we don't have anything to say
882 * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
883 */
884static unsigned long soc_ov5642_query_bus_param(struct soc_camera_device *icd)
885{
886 return 0;
887}
888
889static int soc_ov5642_set_bus_param(struct soc_camera_device *icd,
890 unsigned long flags)
891{
892 return -EINVAL;
893}
894
895static struct soc_camera_ops soc_ov5642_ops = {
896 .query_bus_param = soc_ov5642_query_bus_param,
897 .set_bus_param = soc_ov5642_set_bus_param,
898};
899
900static int ov5642_video_probe(struct soc_camera_device *icd,
901 struct i2c_client *client)
902{ 978{
903 int ret; 979 int ret;
904 u8 id_high, id_low; 980 u8 id_high, id_low;
@@ -929,16 +1005,9 @@ static int ov5642_probe(struct i2c_client *client,
929 const struct i2c_device_id *did) 1005 const struct i2c_device_id *did)
930{ 1006{
931 struct ov5642 *priv; 1007 struct ov5642 *priv;
932 struct soc_camera_device *icd = client->dev.platform_data; 1008 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
933 struct soc_camera_link *icl;
934 int ret; 1009 int ret;
935 1010
936 if (!icd) {
937 dev_err(&client->dev, "OV5642: missing soc-camera data!\n");
938 return -EINVAL;
939 }
940
941 icl = to_soc_camera_link(icd);
942 if (!icl) { 1011 if (!icl) {
943 dev_err(&client->dev, "OV5642: missing platform data!\n"); 1012 dev_err(&client->dev, "OV5642: missing platform data!\n");
944 return -EINVAL; 1013 return -EINVAL;
@@ -950,17 +1019,24 @@ static int ov5642_probe(struct i2c_client *client,
950 1019
951 v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops); 1020 v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
952 1021
953 icd->ops = &soc_ov5642_ops; 1022 priv->fmt = &ov5642_colour_fmts[0];
954 priv->fmt = &ov5642_colour_fmts[0]; 1023
1024 priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
1025 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1026 priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
1027 priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
1028 priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
1029 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1030 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
1031 priv->total_height = BLANKING_MIN_HEIGHT;
955 1032
956 ret = ov5642_video_probe(icd, client); 1033 ret = ov5642_video_probe(client);
957 if (ret < 0) 1034 if (ret < 0)
958 goto error; 1035 goto error;
959 1036
960 return 0; 1037 return 0;
961 1038
962error: 1039error:
963 icd->ops = NULL;
964 kfree(priv); 1040 kfree(priv);
965 return ret; 1041 return ret;
966} 1042}
@@ -968,10 +1044,8 @@ error:
968static int ov5642_remove(struct i2c_client *client) 1044static int ov5642_remove(struct i2c_client *client)
969{ 1045{
970 struct ov5642 *priv = to_ov5642(client); 1046 struct ov5642 *priv = to_ov5642(client);
971 struct soc_camera_device *icd = client->dev.platform_data; 1047 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
972 struct soc_camera_link *icl = to_soc_camera_link(icd);
973 1048
974 icd->ops = NULL;
975 if (icl->free_bus) 1049 if (icl->free_bus)
976 icl->free_bus(icl); 1050 icl->free_bus(icl);
977 kfree(priv); 1051 kfree(priv);
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index 456d9ad9ae5a..d5b057207a7b 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -28,10 +28,11 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/v4l2-mediabus.h>
31 32
32#include <media/soc_camera.h> 33#include <media/soc_camera.h>
33#include <media/v4l2-chip-ident.h> 34#include <media/v4l2-chip-ident.h>
34 35#include <media/v4l2-ctrls.h>
35 36
36/* Register definitions */ 37/* Register definitions */
37#define REG_GAIN 0x00 /* range 00 - 3F */ 38#define REG_GAIN 0x00 /* range 00 - 3F */
@@ -177,20 +178,23 @@ struct ov6650_reg {
177 178
178struct ov6650 { 179struct ov6650 {
179 struct v4l2_subdev subdev; 180 struct v4l2_subdev subdev;
180 181 struct v4l2_ctrl_handler hdl;
181 int gain; 182 struct {
182 int blue; 183 /* exposure/autoexposure cluster */
183 int red; 184 struct v4l2_ctrl *autoexposure;
184 int saturation; 185 struct v4l2_ctrl *exposure;
185 int hue; 186 };
186 int brightness; 187 struct {
187 int exposure; 188 /* gain/autogain cluster */
188 int gamma; 189 struct v4l2_ctrl *autogain;
189 int aec; 190 struct v4l2_ctrl *gain;
190 bool vflip; 191 };
191 bool hflip; 192 struct {
192 bool awb; 193 /* blue/red/autowhitebalance cluster */
193 bool agc; 194 struct v4l2_ctrl *autowb;
195 struct v4l2_ctrl *blue;
196 struct v4l2_ctrl *red;
197 };
194 bool half_scale; /* scale down output by 2 */ 198 bool half_scale; /* scale down output by 2 */
195 struct v4l2_rect rect; /* sensor cropping window */ 199 struct v4l2_rect rect; /* sensor cropping window */
196 unsigned long pclk_limit; /* from host */ 200 unsigned long pclk_limit; /* from host */
@@ -210,126 +214,6 @@ static enum v4l2_mbus_pixelcode ov6650_codes[] = {
210 V4L2_MBUS_FMT_Y8_1X8, 214 V4L2_MBUS_FMT_Y8_1X8,
211}; 215};
212 216
213static const struct v4l2_queryctrl ov6650_controls[] = {
214 {
215 .id = V4L2_CID_AUTOGAIN,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "AGC",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221 .default_value = 1,
222 },
223 {
224 .id = V4L2_CID_GAIN,
225 .type = V4L2_CTRL_TYPE_INTEGER,
226 .name = "Gain",
227 .minimum = 0,
228 .maximum = 0x3f,
229 .step = 1,
230 .default_value = DEF_GAIN,
231 },
232 {
233 .id = V4L2_CID_AUTO_WHITE_BALANCE,
234 .type = V4L2_CTRL_TYPE_BOOLEAN,
235 .name = "AWB",
236 .minimum = 0,
237 .maximum = 1,
238 .step = 1,
239 .default_value = 1,
240 },
241 {
242 .id = V4L2_CID_BLUE_BALANCE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "Blue",
245 .minimum = 0,
246 .maximum = 0xff,
247 .step = 1,
248 .default_value = DEF_BLUE,
249 },
250 {
251 .id = V4L2_CID_RED_BALANCE,
252 .type = V4L2_CTRL_TYPE_INTEGER,
253 .name = "Red",
254 .minimum = 0,
255 .maximum = 0xff,
256 .step = 1,
257 .default_value = DEF_RED,
258 },
259 {
260 .id = V4L2_CID_SATURATION,
261 .type = V4L2_CTRL_TYPE_INTEGER,
262 .name = "Saturation",
263 .minimum = 0,
264 .maximum = 0xf,
265 .step = 1,
266 .default_value = 0x8,
267 },
268 {
269 .id = V4L2_CID_HUE,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "Hue",
272 .minimum = 0,
273 .maximum = HUE_MASK,
274 .step = 1,
275 .default_value = DEF_HUE,
276 },
277 {
278 .id = V4L2_CID_BRIGHTNESS,
279 .type = V4L2_CTRL_TYPE_INTEGER,
280 .name = "Brightness",
281 .minimum = 0,
282 .maximum = 0xff,
283 .step = 1,
284 .default_value = 0x80,
285 },
286 {
287 .id = V4L2_CID_EXPOSURE_AUTO,
288 .type = V4L2_CTRL_TYPE_INTEGER,
289 .name = "AEC",
290 .minimum = 0,
291 .maximum = 3,
292 .step = 1,
293 .default_value = 0,
294 },
295 {
296 .id = V4L2_CID_EXPOSURE,
297 .type = V4L2_CTRL_TYPE_INTEGER,
298 .name = "Exposure",
299 .minimum = 0,
300 .maximum = 0xff,
301 .step = 1,
302 .default_value = DEF_AECH,
303 },
304 {
305 .id = V4L2_CID_GAMMA,
306 .type = V4L2_CTRL_TYPE_INTEGER,
307 .name = "Gamma",
308 .minimum = 0,
309 .maximum = 0xff,
310 .step = 1,
311 .default_value = 0x12,
312 },
313 {
314 .id = V4L2_CID_VFLIP,
315 .type = V4L2_CTRL_TYPE_BOOLEAN,
316 .name = "Flip Vertically",
317 .minimum = 0,
318 .maximum = 1,
319 .step = 1,
320 .default_value = 0,
321 },
322 {
323 .id = V4L2_CID_HFLIP,
324 .type = V4L2_CTRL_TYPE_BOOLEAN,
325 .name = "Flip Horizontally",
326 .minimum = 0,
327 .maximum = 1,
328 .step = 1,
329 .default_value = 0,
330 },
331};
332
333/* read a register */ 217/* read a register */
334static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) 218static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
335{ 219{
@@ -419,213 +303,90 @@ static int ov6650_s_stream(struct v4l2_subdev *sd, int enable)
419 return 0; 303 return 0;
420} 304}
421 305
422/* Alter bus settings on camera side */
423static int ov6650_set_bus_param(struct soc_camera_device *icd,
424 unsigned long flags)
425{
426 struct soc_camera_link *icl = to_soc_camera_link(icd);
427 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
428 int ret;
429
430 flags = soc_camera_apply_sensor_flags(icl, flags);
431
432 if (flags & SOCAM_PCLK_SAMPLE_RISING)
433 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
434 else
435 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
436 if (ret)
437 return ret;
438
439 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
440 ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
441 else
442 ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
443 if (ret)
444 return ret;
445
446 if (flags & SOCAM_VSYNC_ACTIVE_HIGH)
447 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
448 else
449 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
450
451 return ret;
452}
453
454/* Request bus settings on camera side */
455static unsigned long ov6650_query_bus_param(struct soc_camera_device *icd)
456{
457 struct soc_camera_link *icl = to_soc_camera_link(icd);
458
459 unsigned long flags = SOCAM_MASTER |
460 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
461 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
462 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
463 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
464
465 return soc_camera_apply_sensor_flags(icl, flags);
466}
467
468/* Get status of additional camera capabilities */ 306/* Get status of additional camera capabilities */
469static int ov6650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 307static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
470{ 308{
309 struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
310 struct v4l2_subdev *sd = &priv->subdev;
471 struct i2c_client *client = v4l2_get_subdevdata(sd); 311 struct i2c_client *client = v4l2_get_subdevdata(sd);
472 struct ov6650 *priv = to_ov6650(client); 312 uint8_t reg, reg2;
473 uint8_t reg; 313 int ret;
474 int ret = 0;
475 314
476 switch (ctrl->id) { 315 switch (ctrl->id) {
477 case V4L2_CID_AUTOGAIN: 316 case V4L2_CID_AUTOGAIN:
478 ctrl->value = priv->agc; 317 ret = ov6650_reg_read(client, REG_GAIN, &reg);
479 break; 318 if (!ret)
480 case V4L2_CID_GAIN: 319 priv->gain->val = reg;
481 if (priv->agc) { 320 return ret;
482 ret = ov6650_reg_read(client, REG_GAIN, &reg);
483 ctrl->value = reg;
484 } else {
485 ctrl->value = priv->gain;
486 }
487 break;
488 case V4L2_CID_AUTO_WHITE_BALANCE: 321 case V4L2_CID_AUTO_WHITE_BALANCE:
489 ctrl->value = priv->awb; 322 ret = ov6650_reg_read(client, REG_BLUE, &reg);
490 break; 323 if (!ret)
491 case V4L2_CID_BLUE_BALANCE: 324 ret = ov6650_reg_read(client, REG_RED, &reg2);
492 if (priv->awb) { 325 if (!ret) {
493 ret = ov6650_reg_read(client, REG_BLUE, &reg); 326 priv->blue->val = reg;
494 ctrl->value = reg; 327 priv->red->val = reg2;
495 } else {
496 ctrl->value = priv->blue;
497 }
498 break;
499 case V4L2_CID_RED_BALANCE:
500 if (priv->awb) {
501 ret = ov6650_reg_read(client, REG_RED, &reg);
502 ctrl->value = reg;
503 } else {
504 ctrl->value = priv->red;
505 } 328 }
506 break; 329 return ret;
507 case V4L2_CID_SATURATION:
508 ctrl->value = priv->saturation;
509 break;
510 case V4L2_CID_HUE:
511 ctrl->value = priv->hue;
512 break;
513 case V4L2_CID_BRIGHTNESS:
514 ctrl->value = priv->brightness;
515 break;
516 case V4L2_CID_EXPOSURE_AUTO: 330 case V4L2_CID_EXPOSURE_AUTO:
517 ctrl->value = priv->aec; 331 ret = ov6650_reg_read(client, REG_AECH, &reg);
518 break; 332 if (!ret)
519 case V4L2_CID_EXPOSURE: 333 priv->exposure->val = reg;
520 if (priv->aec) { 334 return ret;
521 ret = ov6650_reg_read(client, REG_AECH, &reg);
522 ctrl->value = reg;
523 } else {
524 ctrl->value = priv->exposure;
525 }
526 break;
527 case V4L2_CID_GAMMA:
528 ctrl->value = priv->gamma;
529 break;
530 case V4L2_CID_VFLIP:
531 ctrl->value = priv->vflip;
532 break;
533 case V4L2_CID_HFLIP:
534 ctrl->value = priv->hflip;
535 break;
536 } 335 }
537 return ret; 336 return -EINVAL;
538} 337}
539 338
540/* Set status of additional camera capabilities */ 339/* Set status of additional camera capabilities */
541static int ov6650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 340static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl)
542{ 341{
342 struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
343 struct v4l2_subdev *sd = &priv->subdev;
543 struct i2c_client *client = v4l2_get_subdevdata(sd); 344 struct i2c_client *client = v4l2_get_subdevdata(sd);
544 struct ov6650 *priv = to_ov6650(client); 345 int ret;
545 int ret = 0;
546 346
547 switch (ctrl->id) { 347 switch (ctrl->id) {
548 case V4L2_CID_AUTOGAIN: 348 case V4L2_CID_AUTOGAIN:
549 ret = ov6650_reg_rmw(client, REG_COMB, 349 ret = ov6650_reg_rmw(client, REG_COMB,
550 ctrl->value ? COMB_AGC : 0, COMB_AGC); 350 ctrl->val ? COMB_AGC : 0, COMB_AGC);
551 if (!ret) 351 if (!ret && !ctrl->val)
552 priv->agc = ctrl->value; 352 ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val);
553 break; 353 return ret;
554 case V4L2_CID_GAIN:
555 ret = ov6650_reg_write(client, REG_GAIN, ctrl->value);
556 if (!ret)
557 priv->gain = ctrl->value;
558 break;
559 case V4L2_CID_AUTO_WHITE_BALANCE: 354 case V4L2_CID_AUTO_WHITE_BALANCE:
560 ret = ov6650_reg_rmw(client, REG_COMB, 355 ret = ov6650_reg_rmw(client, REG_COMB,
561 ctrl->value ? COMB_AWB : 0, COMB_AWB); 356 ctrl->val ? COMB_AWB : 0, COMB_AWB);
562 if (!ret) 357 if (!ret && !ctrl->val) {
563 priv->awb = ctrl->value; 358 ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val);
564 break; 359 if (!ret)
565 case V4L2_CID_BLUE_BALANCE: 360 ret = ov6650_reg_write(client, REG_RED,
566 ret = ov6650_reg_write(client, REG_BLUE, ctrl->value); 361 priv->red->val);
567 if (!ret) 362 }
568 priv->blue = ctrl->value; 363 return ret;
569 break;
570 case V4L2_CID_RED_BALANCE:
571 ret = ov6650_reg_write(client, REG_RED, ctrl->value);
572 if (!ret)
573 priv->red = ctrl->value;
574 break;
575 case V4L2_CID_SATURATION: 364 case V4L2_CID_SATURATION:
576 ret = ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->value), 365 return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val),
577 SAT_MASK); 366 SAT_MASK);
578 if (!ret)
579 priv->saturation = ctrl->value;
580 break;
581 case V4L2_CID_HUE: 367 case V4L2_CID_HUE:
582 ret = ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->value), 368 return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val),
583 HUE_MASK); 369 HUE_MASK);
584 if (!ret)
585 priv->hue = ctrl->value;
586 break;
587 case V4L2_CID_BRIGHTNESS: 370 case V4L2_CID_BRIGHTNESS:
588 ret = ov6650_reg_write(client, REG_BRT, ctrl->value); 371 return ov6650_reg_write(client, REG_BRT, ctrl->val);
589 if (!ret)
590 priv->brightness = ctrl->value;
591 break;
592 case V4L2_CID_EXPOSURE_AUTO: 372 case V4L2_CID_EXPOSURE_AUTO:
593 switch (ctrl->value) { 373 ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val ==
594 case V4L2_EXPOSURE_AUTO: 374 V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC);
595 ret = ov6650_reg_rmw(client, REG_COMB, COMB_AEC, 0); 375 if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL)
596 break; 376 ret = ov6650_reg_write(client, REG_AECH,
597 default: 377 priv->exposure->val);
598 ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_AEC); 378 return ret;
599 break;
600 }
601 if (!ret)
602 priv->aec = ctrl->value;
603 break;
604 case V4L2_CID_EXPOSURE:
605 ret = ov6650_reg_write(client, REG_AECH, ctrl->value);
606 if (!ret)
607 priv->exposure = ctrl->value;
608 break;
609 case V4L2_CID_GAMMA: 379 case V4L2_CID_GAMMA:
610 ret = ov6650_reg_write(client, REG_GAM1, ctrl->value); 380 return ov6650_reg_write(client, REG_GAM1, ctrl->val);
611 if (!ret)
612 priv->gamma = ctrl->value;
613 break;
614 case V4L2_CID_VFLIP: 381 case V4L2_CID_VFLIP:
615 ret = ov6650_reg_rmw(client, REG_COMB, 382 return ov6650_reg_rmw(client, REG_COMB,
616 ctrl->value ? COMB_FLIP_V : 0, COMB_FLIP_V); 383 ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V);
617 if (!ret)
618 priv->vflip = ctrl->value;
619 break;
620 case V4L2_CID_HFLIP: 384 case V4L2_CID_HFLIP:
621 ret = ov6650_reg_rmw(client, REG_COMB, 385 return ov6650_reg_rmw(client, REG_COMB,
622 ctrl->value ? COMB_FLIP_H : 0, COMB_FLIP_H); 386 ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H);
623 if (!ret)
624 priv->hflip = ctrl->value;
625 break;
626 } 387 }
627 388
628 return ret; 389 return -EINVAL;
629} 390}
630 391
631/* Get chip identification */ 392/* Get chip identification */
@@ -778,7 +539,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe,
778static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) 539static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
779{ 540{
780 struct i2c_client *client = v4l2_get_subdevdata(sd); 541 struct i2c_client *client = v4l2_get_subdevdata(sd);
781 struct soc_camera_device *icd = client->dev.platform_data; 542 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
782 struct soc_camera_sense *sense = icd->sense; 543 struct soc_camera_sense *sense = icd->sense;
783 struct ov6650 *priv = to_ov6650(client); 544 struct ov6650 *priv = to_ov6650(client);
784 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); 545 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
@@ -1057,8 +818,7 @@ static int ov6650_prog_dflt(struct i2c_client *client)
1057 return ret; 818 return ret;
1058} 819}
1059 820
1060static int ov6650_video_probe(struct soc_camera_device *icd, 821static int ov6650_video_probe(struct i2c_client *client)
1061 struct i2c_client *client)
1062{ 822{
1063 u8 pidh, pidl, midh, midl; 823 u8 pidh, pidl, midh, midl;
1064 int ret = 0; 824 int ret = 0;
@@ -1094,16 +854,12 @@ static int ov6650_video_probe(struct soc_camera_device *icd,
1094 return ret; 854 return ret;
1095} 855}
1096 856
1097static struct soc_camera_ops ov6650_ops = { 857static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
1098 .set_bus_param = ov6650_set_bus_param, 858 .g_volatile_ctrl = ov6550_g_volatile_ctrl,
1099 .query_bus_param = ov6650_query_bus_param, 859 .s_ctrl = ov6550_s_ctrl,
1100 .controls = ov6650_controls,
1101 .num_controls = ARRAY_SIZE(ov6650_controls),
1102}; 860};
1103 861
1104static struct v4l2_subdev_core_ops ov6650_core_ops = { 862static struct v4l2_subdev_core_ops ov6650_core_ops = {
1105 .g_ctrl = ov6650_g_ctrl,
1106 .s_ctrl = ov6650_s_ctrl,
1107 .g_chip_ident = ov6650_g_chip_ident, 863 .g_chip_ident = ov6650_g_chip_ident,
1108#ifdef CONFIG_VIDEO_ADV_DEBUG 864#ifdef CONFIG_VIDEO_ADV_DEBUG
1109 .g_register = ov6650_get_register, 865 .g_register = ov6650_get_register,
@@ -1111,6 +867,55 @@ static struct v4l2_subdev_core_ops ov6650_core_ops = {
1111#endif 867#endif
1112}; 868};
1113 869
870/* Request bus settings on camera side */
871static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
872 struct v4l2_mbus_config *cfg)
873{
874 struct i2c_client *client = v4l2_get_subdevdata(sd);
875 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
876
877 cfg->flags = V4L2_MBUS_MASTER |
878 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
879 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
880 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
881 V4L2_MBUS_DATA_ACTIVE_HIGH;
882 cfg->type = V4L2_MBUS_PARALLEL;
883 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
884
885 return 0;
886}
887
888/* Alter bus settings on camera side */
889static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
890 const struct v4l2_mbus_config *cfg)
891{
892 struct i2c_client *client = v4l2_get_subdevdata(sd);
893 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
894 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
895 int ret;
896
897 if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
898 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
899 else
900 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
901 if (ret)
902 return ret;
903
904 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
905 ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
906 else
907 ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
908 if (ret)
909 return ret;
910
911 if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
912 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
913 else
914 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
915
916 return ret;
917}
918
1114static struct v4l2_subdev_video_ops ov6650_video_ops = { 919static struct v4l2_subdev_video_ops ov6650_video_ops = {
1115 .s_stream = ov6650_s_stream, 920 .s_stream = ov6650_s_stream,
1116 .g_mbus_fmt = ov6650_g_fmt, 921 .g_mbus_fmt = ov6650_g_fmt,
@@ -1122,6 +927,8 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = {
1122 .s_crop = ov6650_s_crop, 927 .s_crop = ov6650_s_crop,
1123 .g_parm = ov6650_g_parm, 928 .g_parm = ov6650_g_parm,
1124 .s_parm = ov6650_s_parm, 929 .s_parm = ov6650_s_parm,
930 .g_mbus_config = ov6650_g_mbus_config,
931 .s_mbus_config = ov6650_s_mbus_config,
1125}; 932};
1126 933
1127static struct v4l2_subdev_ops ov6650_subdev_ops = { 934static struct v4l2_subdev_ops ov6650_subdev_ops = {
@@ -1136,16 +943,9 @@ static int ov6650_probe(struct i2c_client *client,
1136 const struct i2c_device_id *did) 943 const struct i2c_device_id *did)
1137{ 944{
1138 struct ov6650 *priv; 945 struct ov6650 *priv;
1139 struct soc_camera_device *icd = client->dev.platform_data; 946 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1140 struct soc_camera_link *icl;
1141 int ret; 947 int ret;
1142 948
1143 if (!icd) {
1144 dev_err(&client->dev, "Missing soc-camera data!\n");
1145 return -EINVAL;
1146 }
1147
1148 icl = to_soc_camera_link(icd);
1149 if (!icl) { 949 if (!icl) {
1150 dev_err(&client->dev, "Missing platform_data for driver\n"); 950 dev_err(&client->dev, "Missing platform_data for driver\n");
1151 return -EINVAL; 951 return -EINVAL;
@@ -1159,8 +959,46 @@ static int ov6650_probe(struct i2c_client *client,
1159 } 959 }
1160 960
1161 v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); 961 v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
962 v4l2_ctrl_handler_init(&priv->hdl, 13);
963 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
964 V4L2_CID_VFLIP, 0, 1, 1, 0);
965 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
966 V4L2_CID_HFLIP, 0, 1, 1, 0);
967 priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
968 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
969 priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
970 V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN);
971 priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
972 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
973 priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
974 V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE);
975 priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
976 V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED);
977 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
978 V4L2_CID_SATURATION, 0, 0xf, 1, 0x8);
979 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
980 V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE);
981 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
982 V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80);
983 priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl,
984 &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
985 V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
986 priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
987 V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH);
988 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
989 V4L2_CID_GAMMA, 0, 0xff, 1, 0x12);
990
991 priv->subdev.ctrl_handler = &priv->hdl;
992 if (priv->hdl.error) {
993 int err = priv->hdl.error;
1162 994
1163 icd->ops = &ov6650_ops; 995 kfree(priv);
996 return err;
997 }
998 v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true);
999 v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true);
1000 v4l2_ctrl_auto_cluster(2, &priv->autoexposure,
1001 V4L2_EXPOSURE_MANUAL, true);
1164 1002
1165 priv->rect.left = DEF_HSTRT << 1; 1003 priv->rect.left = DEF_HSTRT << 1;
1166 priv->rect.top = DEF_VSTRT << 1; 1004 priv->rect.top = DEF_VSTRT << 1;
@@ -1170,10 +1008,12 @@ static int ov6650_probe(struct i2c_client *client,
1170 priv->code = V4L2_MBUS_FMT_YUYV8_2X8; 1008 priv->code = V4L2_MBUS_FMT_YUYV8_2X8;
1171 priv->colorspace = V4L2_COLORSPACE_JPEG; 1009 priv->colorspace = V4L2_COLORSPACE_JPEG;
1172 1010
1173 ret = ov6650_video_probe(icd, client); 1011 ret = ov6650_video_probe(client);
1012 if (!ret)
1013 ret = v4l2_ctrl_handler_setup(&priv->hdl);
1174 1014
1175 if (ret) { 1015 if (ret) {
1176 icd->ops = NULL; 1016 v4l2_ctrl_handler_free(&priv->hdl);
1177 kfree(priv); 1017 kfree(priv);
1178 } 1018 }
1179 1019
@@ -1184,6 +1024,8 @@ static int ov6650_remove(struct i2c_client *client)
1184{ 1024{
1185 struct ov6650 *priv = to_ov6650(client); 1025 struct ov6650 *priv = to_ov6650(client);
1186 1026
1027 v4l2_device_unregister_subdev(&priv->subdev);
1028 v4l2_ctrl_handler_free(&priv->hdl);
1187 kfree(priv); 1029 kfree(priv);
1188 return 0; 1030 return 0;
1189} 1031}
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 397870f076c1..9f6ce3d8a29e 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -20,12 +20,14 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/v4l2-mediabus.h>
23#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25
26#include <media/ov772x.h>
27#include <media/soc_camera.h>
28#include <media/v4l2-ctrls.h>
24#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-subdev.h> 30#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h>
27#include <media/soc_mediabus.h>
28#include <media/ov772x.h>
29 31
30/* 32/*
31 * register offset 33 * register offset
@@ -400,6 +402,7 @@ struct ov772x_win_size {
400 402
401struct ov772x_priv { 403struct ov772x_priv {
402 struct v4l2_subdev subdev; 404 struct v4l2_subdev subdev;
405 struct v4l2_ctrl_handler hdl;
403 struct ov772x_camera_info *info; 406 struct ov772x_camera_info *info;
404 const struct ov772x_color_format *cfmt; 407 const struct ov772x_color_format *cfmt;
405 const struct ov772x_win_size *win; 408 const struct ov772x_win_size *win;
@@ -517,36 +520,6 @@ static const struct ov772x_win_size ov772x_win_qvga = {
517 .regs = ov772x_qvga_regs, 520 .regs = ov772x_qvga_regs,
518}; 521};
519 522
520static const struct v4l2_queryctrl ov772x_controls[] = {
521 {
522 .id = V4L2_CID_VFLIP,
523 .type = V4L2_CTRL_TYPE_BOOLEAN,
524 .name = "Flip Vertically",
525 .minimum = 0,
526 .maximum = 1,
527 .step = 1,
528 .default_value = 0,
529 },
530 {
531 .id = V4L2_CID_HFLIP,
532 .type = V4L2_CTRL_TYPE_BOOLEAN,
533 .name = "Flip Horizontally",
534 .minimum = 0,
535 .maximum = 1,
536 .step = 1,
537 .default_value = 0,
538 },
539 {
540 .id = V4L2_CID_BAND_STOP_FILTER,
541 .type = V4L2_CTRL_TYPE_INTEGER,
542 .name = "Band-stop filter",
543 .minimum = 0,
544 .maximum = 256,
545 .step = 1,
546 .default_value = 0,
547 },
548};
549
550/* 523/*
551 * general function 524 * general function
552 */ 525 */
@@ -620,75 +593,30 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
620 return 0; 593 return 0;
621} 594}
622 595
623static int ov772x_set_bus_param(struct soc_camera_device *icd, 596static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
624 unsigned long flags)
625{
626 return 0;
627}
628
629static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
630{
631 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
632 struct ov772x_priv *priv = i2c_get_clientdata(client);
633 struct soc_camera_link *icl = to_soc_camera_link(icd);
634 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
635 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
636 SOCAM_DATA_ACTIVE_HIGH;
637
638 if (priv->info->flags & OV772X_FLAG_8BIT)
639 flags |= SOCAM_DATAWIDTH_8;
640 else
641 flags |= SOCAM_DATAWIDTH_10;
642
643 return soc_camera_apply_sensor_flags(icl, flags);
644}
645
646static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
647{
648 struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
649
650 switch (ctrl->id) {
651 case V4L2_CID_VFLIP:
652 ctrl->value = priv->flag_vflip;
653 break;
654 case V4L2_CID_HFLIP:
655 ctrl->value = priv->flag_hflip;
656 break;
657 case V4L2_CID_BAND_STOP_FILTER:
658 ctrl->value = priv->band_filter;
659 break;
660 }
661 return 0;
662}
663
664static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
665{ 597{
598 struct ov772x_priv *priv = container_of(ctrl->handler,
599 struct ov772x_priv, hdl);
600 struct v4l2_subdev *sd = &priv->subdev;
666 struct i2c_client *client = v4l2_get_subdevdata(sd); 601 struct i2c_client *client = v4l2_get_subdevdata(sd);
667 struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
668 int ret = 0; 602 int ret = 0;
669 u8 val; 603 u8 val;
670 604
671 switch (ctrl->id) { 605 switch (ctrl->id) {
672 case V4L2_CID_VFLIP: 606 case V4L2_CID_VFLIP:
673 val = ctrl->value ? VFLIP_IMG : 0x00; 607 val = ctrl->val ? VFLIP_IMG : 0x00;
674 priv->flag_vflip = ctrl->value; 608 priv->flag_vflip = ctrl->val;
675 if (priv->info->flags & OV772X_FLAG_VFLIP) 609 if (priv->info->flags & OV772X_FLAG_VFLIP)
676 val ^= VFLIP_IMG; 610 val ^= VFLIP_IMG;
677 ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val); 611 return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
678 break;
679 case V4L2_CID_HFLIP: 612 case V4L2_CID_HFLIP:
680 val = ctrl->value ? HFLIP_IMG : 0x00; 613 val = ctrl->val ? HFLIP_IMG : 0x00;
681 priv->flag_hflip = ctrl->value; 614 priv->flag_hflip = ctrl->val;
682 if (priv->info->flags & OV772X_FLAG_HFLIP) 615 if (priv->info->flags & OV772X_FLAG_HFLIP)
683 val ^= HFLIP_IMG; 616 val ^= HFLIP_IMG;
684 ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val); 617 return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
685 break;
686 case V4L2_CID_BAND_STOP_FILTER: 618 case V4L2_CID_BAND_STOP_FILTER:
687 if ((unsigned)ctrl->value > 256) 619 if (!ctrl->val) {
688 ctrl->value = 256;
689 if (ctrl->value == priv->band_filter)
690 break;
691 if (!ctrl->value) {
692 /* Switch the filter off, it is on now */ 620 /* Switch the filter off, it is on now */
693 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); 621 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
694 if (!ret) 622 if (!ret)
@@ -696,7 +624,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
696 BNDF_ON_OFF, 0); 624 BNDF_ON_OFF, 0);
697 } else { 625 } else {
698 /* Switch the filter on, set AEC low limit */ 626 /* Switch the filter on, set AEC low limit */
699 val = 256 - ctrl->value; 627 val = 256 - ctrl->val;
700 ret = ov772x_mask_set(client, COM8, 628 ret = ov772x_mask_set(client, COM8,
701 BNDF_ON_OFF, BNDF_ON_OFF); 629 BNDF_ON_OFF, BNDF_ON_OFF);
702 if (!ret) 630 if (!ret)
@@ -704,11 +632,11 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
704 0xff, val); 632 0xff, val);
705 } 633 }
706 if (!ret) 634 if (!ret)
707 priv->band_filter = ctrl->value; 635 priv->band_filter = ctrl->val;
708 break; 636 return ret;
709 } 637 }
710 638
711 return ret; 639 return -EINVAL;
712} 640}
713 641
714static int ov772x_g_chip_ident(struct v4l2_subdev *sd, 642static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
@@ -822,13 +750,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
822 goto ov772x_set_fmt_error; 750 goto ov772x_set_fmt_error;
823 751
824 ret = ov772x_mask_set(client, 752 ret = ov772x_mask_set(client,
825 EDGE_TRSHLD, EDGE_THRESHOLD_MASK, 753 EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
826 priv->info->edgectrl.threshold); 754 priv->info->edgectrl.threshold);
827 if (ret < 0) 755 if (ret < 0)
828 goto ov772x_set_fmt_error; 756 goto ov772x_set_fmt_error;
829 757
830 ret = ov772x_mask_set(client, 758 ret = ov772x_mask_set(client,
831 EDGE_STRNGT, EDGE_STRENGTH_MASK, 759 EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
832 priv->info->edgectrl.strength); 760 priv->info->edgectrl.strength);
833 if (ret < 0) 761 if (ret < 0)
834 goto ov772x_set_fmt_error; 762 goto ov772x_set_fmt_error;
@@ -840,13 +768,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
840 * set upper and lower limit 768 * set upper and lower limit
841 */ 769 */
842 ret = ov772x_mask_set(client, 770 ret = ov772x_mask_set(client,
843 EDGE_UPPER, EDGE_UPPER_MASK, 771 EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
844 priv->info->edgectrl.upper); 772 priv->info->edgectrl.upper);
845 if (ret < 0) 773 if (ret < 0)
846 goto ov772x_set_fmt_error; 774 goto ov772x_set_fmt_error;
847 775
848 ret = ov772x_mask_set(client, 776 ret = ov772x_mask_set(client,
849 EDGE_LOWER, EDGE_LOWER_MASK, 777 EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
850 priv->info->edgectrl.lower); 778 priv->info->edgectrl.lower);
851 if (ret < 0) 779 if (ret < 0)
852 goto ov772x_set_fmt_error; 780 goto ov772x_set_fmt_error;
@@ -1025,17 +953,12 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd,
1025 return 0; 953 return 0;
1026} 954}
1027 955
1028static int ov772x_video_probe(struct soc_camera_device *icd, 956static int ov772x_video_probe(struct i2c_client *client)
1029 struct i2c_client *client)
1030{ 957{
1031 struct ov772x_priv *priv = to_ov772x(client); 958 struct ov772x_priv *priv = to_ov772x(client);
1032 u8 pid, ver; 959 u8 pid, ver;
1033 const char *devname; 960 const char *devname;
1034 961
1035 /* We must have a parent by now. And it cannot be a wrong one. */
1036 BUG_ON(!icd->parent ||
1037 to_soc_camera_host(icd->parent)->nr != icd->iface);
1038
1039 /* 962 /*
1040 * check and show product ID and manufacturer ID 963 * check and show product ID and manufacturer ID
1041 */ 964 */
@@ -1064,20 +987,14 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1064 ver, 987 ver,
1065 i2c_smbus_read_byte_data(client, MIDH), 988 i2c_smbus_read_byte_data(client, MIDH),
1066 i2c_smbus_read_byte_data(client, MIDL)); 989 i2c_smbus_read_byte_data(client, MIDL));
1067 990 return v4l2_ctrl_handler_setup(&priv->hdl);
1068 return 0;
1069} 991}
1070 992
1071static struct soc_camera_ops ov772x_ops = { 993static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
1072 .set_bus_param = ov772x_set_bus_param, 994 .s_ctrl = ov772x_s_ctrl,
1073 .query_bus_param = ov772x_query_bus_param,
1074 .controls = ov772x_controls,
1075 .num_controls = ARRAY_SIZE(ov772x_controls),
1076}; 995};
1077 996
1078static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { 997static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1079 .g_ctrl = ov772x_g_ctrl,
1080 .s_ctrl = ov772x_s_ctrl,
1081 .g_chip_ident = ov772x_g_chip_ident, 998 .g_chip_ident = ov772x_g_chip_ident,
1082#ifdef CONFIG_VIDEO_ADV_DEBUG 999#ifdef CONFIG_VIDEO_ADV_DEBUG
1083 .g_register = ov772x_g_register, 1000 .g_register = ov772x_g_register,
@@ -1095,6 +1012,21 @@ static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1095 return 0; 1012 return 0;
1096} 1013}
1097 1014
1015static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
1016 struct v4l2_mbus_config *cfg)
1017{
1018 struct i2c_client *client = v4l2_get_subdevdata(sd);
1019 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1020
1021 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1022 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1023 V4L2_MBUS_DATA_ACTIVE_HIGH;
1024 cfg->type = V4L2_MBUS_PARALLEL;
1025 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1026
1027 return 0;
1028}
1029
1098static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1030static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1099 .s_stream = ov772x_s_stream, 1031 .s_stream = ov772x_s_stream,
1100 .g_mbus_fmt = ov772x_g_fmt, 1032 .g_mbus_fmt = ov772x_g_fmt,
@@ -1103,6 +1035,7 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1103 .cropcap = ov772x_cropcap, 1035 .cropcap = ov772x_cropcap,
1104 .g_crop = ov772x_g_crop, 1036 .g_crop = ov772x_g_crop,
1105 .enum_mbus_fmt = ov772x_enum_fmt, 1037 .enum_mbus_fmt = ov772x_enum_fmt,
1038 .g_mbus_config = ov772x_g_mbus_config,
1106}; 1039};
1107 1040
1108static struct v4l2_subdev_ops ov772x_subdev_ops = { 1041static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1117,20 +1050,15 @@ static struct v4l2_subdev_ops ov772x_subdev_ops = {
1117static int ov772x_probe(struct i2c_client *client, 1050static int ov772x_probe(struct i2c_client *client,
1118 const struct i2c_device_id *did) 1051 const struct i2c_device_id *did)
1119{ 1052{
1120 struct ov772x_priv *priv; 1053 struct ov772x_priv *priv;
1121 struct soc_camera_device *icd = client->dev.platform_data; 1054 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1122 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1055 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1123 struct soc_camera_link *icl; 1056 int ret;
1124 int ret;
1125
1126 if (!icd) {
1127 dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
1128 return -EINVAL;
1129 }
1130 1057
1131 icl = to_soc_camera_link(icd); 1058 if (!icl || !icl->priv) {
1132 if (!icl || !icl->priv) 1059 dev_err(&client->dev, "OV772X: missing platform data!\n");
1133 return -EINVAL; 1060 return -EINVAL;
1061 }
1134 1062
1135 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1063 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1136 dev_err(&adapter->dev, 1064 dev_err(&adapter->dev,
@@ -1146,12 +1074,24 @@ static int ov772x_probe(struct i2c_client *client,
1146 priv->info = icl->priv; 1074 priv->info = icl->priv;
1147 1075
1148 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1076 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1077 v4l2_ctrl_handler_init(&priv->hdl, 3);
1078 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1079 V4L2_CID_VFLIP, 0, 1, 1, 0);
1080 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1081 V4L2_CID_HFLIP, 0, 1, 1, 0);
1082 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1083 V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
1084 priv->subdev.ctrl_handler = &priv->hdl;
1085 if (priv->hdl.error) {
1086 int err = priv->hdl.error;
1149 1087
1150 icd->ops = &ov772x_ops; 1088 kfree(priv);
1089 return err;
1090 }
1151 1091
1152 ret = ov772x_video_probe(icd, client); 1092 ret = ov772x_video_probe(client);
1153 if (ret) { 1093 if (ret) {
1154 icd->ops = NULL; 1094 v4l2_ctrl_handler_free(&priv->hdl);
1155 kfree(priv); 1095 kfree(priv);
1156 } 1096 }
1157 1097
@@ -1161,9 +1101,9 @@ static int ov772x_probe(struct i2c_client *client,
1161static int ov772x_remove(struct i2c_client *client) 1101static int ov772x_remove(struct i2c_client *client)
1162{ 1102{
1163 struct ov772x_priv *priv = to_ov772x(client); 1103 struct ov772x_priv *priv = to_ov772x(client);
1164 struct soc_camera_device *icd = client->dev.platform_data;
1165 1104
1166 icd->ops = NULL; 1105 v4l2_device_unregister_subdev(&priv->subdev);
1106 v4l2_ctrl_handler_free(&priv->hdl);
1167 kfree(priv); 1107 kfree(priv);
1168 return 0; 1108 return 0;
1169} 1109}
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 3681a6ff0815..a4f99797eb56 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -24,10 +24,13 @@
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/v4l2-mediabus.h>
27#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29
30#include <media/soc_camera.h>
28#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
29#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
30#include <media/soc_camera.h> 33#include <media/v4l2-ctrls.h>
31 34
32#include "ov9640.h" 35#include "ov9640.h"
33 36
@@ -162,27 +165,6 @@ static enum v4l2_mbus_pixelcode ov9640_codes[] = {
162 V4L2_MBUS_FMT_RGB565_2X8_LE, 165 V4L2_MBUS_FMT_RGB565_2X8_LE,
163}; 166};
164 167
165static const struct v4l2_queryctrl ov9640_controls[] = {
166 {
167 .id = V4L2_CID_VFLIP,
168 .type = V4L2_CTRL_TYPE_BOOLEAN,
169 .name = "Flip Vertically",
170 .minimum = 0,
171 .maximum = 1,
172 .step = 1,
173 .default_value = 0,
174 },
175 {
176 .id = V4L2_CID_HFLIP,
177 .type = V4L2_CTRL_TYPE_BOOLEAN,
178 .name = "Flip Horizontally",
179 .minimum = 0,
180 .maximum = 1,
181 .step = 1,
182 .default_value = 0,
183 },
184};
185
186/* read a register */ 168/* read a register */
187static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val) 169static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
188{ 170{
@@ -284,75 +266,25 @@ static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
284 return 0; 266 return 0;
285} 267}
286 268
287/* Alter bus settings on camera side */
288static int ov9640_set_bus_param(struct soc_camera_device *icd,
289 unsigned long flags)
290{
291 return 0;
292}
293
294/* Request bus settings on camera side */
295static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
296{
297 struct soc_camera_link *icl = to_soc_camera_link(icd);
298
299 /*
300 * REVISIT: the camera probably can do 10 bit transfers, but I don't
301 * have those pins connected on my hardware.
302 */
303 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
304 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
305 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
306
307 return soc_camera_apply_sensor_flags(icl, flags);
308}
309
310/* Get status of additional camera capabilities */
311static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
312{
313 struct ov9640_priv *priv = to_ov9640_sensor(sd);
314
315 switch (ctrl->id) {
316 case V4L2_CID_VFLIP:
317 ctrl->value = priv->flag_vflip;
318 break;
319 case V4L2_CID_HFLIP:
320 ctrl->value = priv->flag_hflip;
321 break;
322 }
323 return 0;
324}
325
326/* Set status of additional camera capabilities */ 269/* Set status of additional camera capabilities */
327static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 270static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
328{ 271{
329 struct i2c_client *client = v4l2_get_subdevdata(sd); 272 struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
330 struct ov9640_priv *priv = to_ov9640_sensor(sd); 273 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
331
332 int ret = 0;
333 274
334 switch (ctrl->id) { 275 switch (ctrl->id) {
335 case V4L2_CID_VFLIP: 276 case V4L2_CID_VFLIP:
336 priv->flag_vflip = ctrl->value; 277 if (ctrl->val)
337 if (ctrl->value) 278 return ov9640_reg_rmw(client, OV9640_MVFP,
338 ret = ov9640_reg_rmw(client, OV9640_MVFP,
339 OV9640_MVFP_V, 0); 279 OV9640_MVFP_V, 0);
340 else 280 return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
341 ret = ov9640_reg_rmw(client, OV9640_MVFP,
342 0, OV9640_MVFP_V);
343 break;
344 case V4L2_CID_HFLIP: 281 case V4L2_CID_HFLIP:
345 priv->flag_hflip = ctrl->value; 282 if (ctrl->val)
346 if (ctrl->value) 283 return ov9640_reg_rmw(client, OV9640_MVFP,
347 ret = ov9640_reg_rmw(client, OV9640_MVFP,
348 OV9640_MVFP_H, 0); 284 OV9640_MVFP_H, 0);
349 else 285 return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
350 ret = ov9640_reg_rmw(client, OV9640_MVFP,
351 0, OV9640_MVFP_H);
352 break;
353 } 286 }
354 287 return -EINVAL;
355 return ret;
356} 288}
357 289
358/* Get chip identification */ 290/* Get chip identification */
@@ -646,10 +578,7 @@ static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
646 return 0; 578 return 0;
647} 579}
648 580
649 581static int ov9640_video_probe(struct i2c_client *client)
650
651static int ov9640_video_probe(struct soc_camera_device *icd,
652 struct i2c_client *client)
653{ 582{
654 struct v4l2_subdev *sd = i2c_get_clientdata(client); 583 struct v4l2_subdev *sd = i2c_get_clientdata(client);
655 struct ov9640_priv *priv = to_ov9640_sensor(sd); 584 struct ov9640_priv *priv = to_ov9640_sensor(sd);
@@ -657,29 +586,19 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
657 const char *devname; 586 const char *devname;
658 int ret = 0; 587 int ret = 0;
659 588
660 /* We must have a parent by now. And it cannot be a wrong one. */
661 BUG_ON(!icd->parent ||
662 to_soc_camera_host(icd->parent)->nr != icd->iface);
663
664 /* 589 /*
665 * check and show product ID and manufacturer ID 590 * check and show product ID and manufacturer ID
666 */ 591 */
667 592
668 ret = ov9640_reg_read(client, OV9640_PID, &pid); 593 ret = ov9640_reg_read(client, OV9640_PID, &pid);
594 if (!ret)
595 ret = ov9640_reg_read(client, OV9640_VER, &ver);
596 if (!ret)
597 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
598 if (!ret)
599 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
669 if (ret) 600 if (ret)
670 goto err; 601 return ret;
671
672 ret = ov9640_reg_read(client, OV9640_VER, &ver);
673 if (ret)
674 goto err;
675
676 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
677 if (ret)
678 goto err;
679
680 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
681 if (ret)
682 goto err;
683 602
684 switch (VERSION(pid, ver)) { 603 switch (VERSION(pid, ver)) {
685 case OV9640_V2: 604 case OV9640_V2:
@@ -693,27 +612,20 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
693 break; 612 break;
694 default: 613 default:
695 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver); 614 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
696 ret = -ENODEV; 615 return -ENODEV;
697 goto err;
698 } 616 }
699 617
700 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 618 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
701 devname, pid, ver, midh, midl); 619 devname, pid, ver, midh, midl);
702 620
703err: 621 return v4l2_ctrl_handler_setup(&priv->hdl);
704 return ret;
705} 622}
706 623
707static struct soc_camera_ops ov9640_ops = { 624static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
708 .set_bus_param = ov9640_set_bus_param, 625 .s_ctrl = ov9640_s_ctrl,
709 .query_bus_param = ov9640_query_bus_param,
710 .controls = ov9640_controls,
711 .num_controls = ARRAY_SIZE(ov9640_controls),
712}; 626};
713 627
714static struct v4l2_subdev_core_ops ov9640_core_ops = { 628static struct v4l2_subdev_core_ops ov9640_core_ops = {
715 .g_ctrl = ov9640_g_ctrl,
716 .s_ctrl = ov9640_s_ctrl,
717 .g_chip_ident = ov9640_g_chip_ident, 629 .g_chip_ident = ov9640_g_chip_ident,
718#ifdef CONFIG_VIDEO_ADV_DEBUG 630#ifdef CONFIG_VIDEO_ADV_DEBUG
719 .g_register = ov9640_get_register, 631 .g_register = ov9640_get_register,
@@ -722,6 +634,22 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = {
722 634
723}; 635};
724 636
637/* Request bus settings on camera side */
638static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
639 struct v4l2_mbus_config *cfg)
640{
641 struct i2c_client *client = v4l2_get_subdevdata(sd);
642 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
643
644 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
645 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
646 V4L2_MBUS_DATA_ACTIVE_HIGH;
647 cfg->type = V4L2_MBUS_PARALLEL;
648 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
649
650 return 0;
651}
652
725static struct v4l2_subdev_video_ops ov9640_video_ops = { 653static struct v4l2_subdev_video_ops ov9640_video_ops = {
726 .s_stream = ov9640_s_stream, 654 .s_stream = ov9640_s_stream,
727 .s_mbus_fmt = ov9640_s_fmt, 655 .s_mbus_fmt = ov9640_s_fmt,
@@ -729,7 +657,7 @@ static struct v4l2_subdev_video_ops ov9640_video_ops = {
729 .enum_mbus_fmt = ov9640_enum_fmt, 657 .enum_mbus_fmt = ov9640_enum_fmt,
730 .cropcap = ov9640_cropcap, 658 .cropcap = ov9640_cropcap,
731 .g_crop = ov9640_g_crop, 659 .g_crop = ov9640_g_crop,
732 660 .g_mbus_config = ov9640_g_mbus_config,
733}; 661};
734 662
735static struct v4l2_subdev_ops ov9640_subdev_ops = { 663static struct v4l2_subdev_ops ov9640_subdev_ops = {
@@ -744,16 +672,9 @@ static int ov9640_probe(struct i2c_client *client,
744 const struct i2c_device_id *did) 672 const struct i2c_device_id *did)
745{ 673{
746 struct ov9640_priv *priv; 674 struct ov9640_priv *priv;
747 struct soc_camera_device *icd = client->dev.platform_data; 675 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
748 struct soc_camera_link *icl;
749 int ret; 676 int ret;
750 677
751 if (!icd) {
752 dev_err(&client->dev, "Missing soc-camera data!\n");
753 return -EINVAL;
754 }
755
756 icl = to_soc_camera_link(icd);
757 if (!icl) { 678 if (!icl) {
758 dev_err(&client->dev, "Missing platform_data for driver\n"); 679 dev_err(&client->dev, "Missing platform_data for driver\n");
759 return -EINVAL; 680 return -EINVAL;
@@ -768,12 +689,23 @@ static int ov9640_probe(struct i2c_client *client,
768 689
769 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops); 690 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
770 691
771 icd->ops = &ov9640_ops; 692 v4l2_ctrl_handler_init(&priv->hdl, 2);
693 v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
694 V4L2_CID_VFLIP, 0, 1, 1, 0);
695 v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
696 V4L2_CID_HFLIP, 0, 1, 1, 0);
697 priv->subdev.ctrl_handler = &priv->hdl;
698 if (priv->hdl.error) {
699 int err = priv->hdl.error;
700
701 kfree(priv);
702 return err;
703 }
772 704
773 ret = ov9640_video_probe(icd, client); 705 ret = ov9640_video_probe(client);
774 706
775 if (ret) { 707 if (ret) {
776 icd->ops = NULL; 708 v4l2_ctrl_handler_free(&priv->hdl);
777 kfree(priv); 709 kfree(priv);
778 } 710 }
779 711
@@ -785,6 +717,8 @@ static int ov9640_remove(struct i2c_client *client)
785 struct v4l2_subdev *sd = i2c_get_clientdata(client); 717 struct v4l2_subdev *sd = i2c_get_clientdata(client);
786 struct ov9640_priv *priv = to_ov9640_sensor(sd); 718 struct ov9640_priv *priv = to_ov9640_sensor(sd);
787 719
720 v4l2_device_unregister_subdev(&priv->subdev);
721 v4l2_ctrl_handler_free(&priv->hdl);
788 kfree(priv); 722 kfree(priv);
789 return 0; 723 return 0;
790} 724}
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
index f8a51b70792e..6b33a972c83c 100644
--- a/drivers/media/video/ov9640.h
+++ b/drivers/media/video/ov9640.h
@@ -198,12 +198,10 @@ struct ov9640_reg {
198 198
199struct ov9640_priv { 199struct ov9640_priv {
200 struct v4l2_subdev subdev; 200 struct v4l2_subdev subdev;
201 struct v4l2_ctrl_handler hdl;
201 202
202 int model; 203 int model;
203 int revision; 204 int revision;
204
205 bool flag_vflip;
206 bool flag_hflip;
207}; 205};
208 206
209#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */ 207#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
index edd1ffcca30b..d9a9f7174f7a 100644
--- a/drivers/media/video/ov9740.c
+++ b/drivers/media/video/ov9740.c
@@ -14,8 +14,11 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <media/v4l2-chip-ident.h> 17#include <linux/v4l2-mediabus.h>
18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/v4l2-chip-ident.h>
21#include <media/v4l2-ctrls.h>
19 22
20#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev) 23#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
21 24
@@ -192,6 +195,7 @@ struct ov9740_reg {
192 195
193struct ov9740_priv { 196struct ov9740_priv {
194 struct v4l2_subdev subdev; 197 struct v4l2_subdev subdev;
198 struct v4l2_ctrl_handler hdl;
195 199
196 int ident; 200 int ident;
197 u16 model; 201 u16 model;
@@ -392,27 +396,6 @@ static enum v4l2_mbus_pixelcode ov9740_codes[] = {
392 V4L2_MBUS_FMT_YUYV8_2X8, 396 V4L2_MBUS_FMT_YUYV8_2X8,
393}; 397};
394 398
395static const struct v4l2_queryctrl ov9740_controls[] = {
396 {
397 .id = V4L2_CID_VFLIP,
398 .type = V4L2_CTRL_TYPE_BOOLEAN,
399 .name = "Flip Vertically",
400 .minimum = 0,
401 .maximum = 1,
402 .step = 1,
403 .default_value = 0,
404 },
405 {
406 .id = V4L2_CID_HFLIP,
407 .type = V4L2_CTRL_TYPE_BOOLEAN,
408 .name = "Flip Horizontally",
409 .minimum = 0,
410 .maximum = 1,
411 .step = 1,
412 .default_value = 0,
413 },
414};
415
416/* read a register */ 399/* read a register */
417static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val) 400static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
418{ 401{
@@ -560,25 +543,6 @@ static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
560 return ret; 543 return ret;
561} 544}
562 545
563/* Alter bus settings on camera side */
564static int ov9740_set_bus_param(struct soc_camera_device *icd,
565 unsigned long flags)
566{
567 return 0;
568}
569
570/* Request bus settings on camera side */
571static unsigned long ov9740_query_bus_param(struct soc_camera_device *icd)
572{
573 struct soc_camera_link *icl = to_soc_camera_link(icd);
574
575 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
576 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
577 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
578
579 return soc_camera_apply_sensor_flags(icl, flags);
580}
581
582/* select nearest higher resolution for capture */ 546/* select nearest higher resolution for capture */
583static void ov9740_res_roundup(u32 *width, u32 *height) 547static void ov9740_res_roundup(u32 *width, u32 *height)
584{ 548{
@@ -788,36 +752,18 @@ static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
788 return 0; 752 return 0;
789} 753}
790 754
791/* Get status of additional camera capabilities */
792static int ov9740_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
793{
794 struct ov9740_priv *priv = to_ov9740(sd);
795
796 switch (ctrl->id) {
797 case V4L2_CID_VFLIP:
798 ctrl->value = priv->flag_vflip;
799 break;
800 case V4L2_CID_HFLIP:
801 ctrl->value = priv->flag_hflip;
802 break;
803 default:
804 return -EINVAL;
805 }
806
807 return 0;
808}
809
810/* Set status of additional camera capabilities */ 755/* Set status of additional camera capabilities */
811static int ov9740_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 756static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
812{ 757{
813 struct ov9740_priv *priv = to_ov9740(sd); 758 struct ov9740_priv *priv =
759 container_of(ctrl->handler, struct ov9740_priv, hdl);
814 760
815 switch (ctrl->id) { 761 switch (ctrl->id) {
816 case V4L2_CID_VFLIP: 762 case V4L2_CID_VFLIP:
817 priv->flag_vflip = ctrl->value; 763 priv->flag_vflip = ctrl->val;
818 break; 764 break;
819 case V4L2_CID_HFLIP: 765 case V4L2_CID_HFLIP:
820 priv->flag_hflip = ctrl->value; 766 priv->flag_hflip = ctrl->val;
821 break; 767 break;
822 default: 768 default:
823 return -EINVAL; 769 return -EINVAL;
@@ -890,18 +836,13 @@ static int ov9740_set_register(struct v4l2_subdev *sd,
890} 836}
891#endif 837#endif
892 838
893static int ov9740_video_probe(struct soc_camera_device *icd, 839static int ov9740_video_probe(struct i2c_client *client)
894 struct i2c_client *client)
895{ 840{
896 struct v4l2_subdev *sd = i2c_get_clientdata(client); 841 struct v4l2_subdev *sd = i2c_get_clientdata(client);
897 struct ov9740_priv *priv = to_ov9740(sd); 842 struct ov9740_priv *priv = to_ov9740(sd);
898 u8 modelhi, modello; 843 u8 modelhi, modello;
899 int ret; 844 int ret;
900 845
901 /* We must have a parent by now. And it cannot be a wrong one. */
902 BUG_ON(!icd->parent ||
903 to_soc_camera_host(icd->parent)->nr != icd->iface);
904
905 /* 846 /*
906 * check and show product ID and manufacturer ID 847 * check and show product ID and manufacturer ID
907 */ 848 */
@@ -942,25 +883,33 @@ err:
942 return ret; 883 return ret;
943} 884}
944 885
945static struct soc_camera_ops ov9740_ops = { 886/* Request bus settings on camera side */
946 .set_bus_param = ov9740_set_bus_param, 887static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
947 .query_bus_param = ov9740_query_bus_param, 888 struct v4l2_mbus_config *cfg)
948 .controls = ov9740_controls, 889{
949 .num_controls = ARRAY_SIZE(ov9740_controls), 890 struct i2c_client *client = v4l2_get_subdevdata(sd);
950}; 891 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
892
893 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
894 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
895 V4L2_MBUS_DATA_ACTIVE_HIGH;
896 cfg->type = V4L2_MBUS_PARALLEL;
897 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
898
899 return 0;
900}
951 901
952static struct v4l2_subdev_video_ops ov9740_video_ops = { 902static struct v4l2_subdev_video_ops ov9740_video_ops = {
953 .s_stream = ov9740_s_stream, 903 .s_stream = ov9740_s_stream,
954 .s_mbus_fmt = ov9740_s_fmt, 904 .s_mbus_fmt = ov9740_s_fmt,
955 .try_mbus_fmt = ov9740_try_fmt, 905 .try_mbus_fmt = ov9740_try_fmt,
956 .enum_mbus_fmt = ov9740_enum_fmt, 906 .enum_mbus_fmt = ov9740_enum_fmt,
957 .cropcap = ov9740_cropcap, 907 .cropcap = ov9740_cropcap,
958 .g_crop = ov9740_g_crop, 908 .g_crop = ov9740_g_crop,
909 .g_mbus_config = ov9740_g_mbus_config,
959}; 910};
960 911
961static struct v4l2_subdev_core_ops ov9740_core_ops = { 912static struct v4l2_subdev_core_ops ov9740_core_ops = {
962 .g_ctrl = ov9740_g_ctrl,
963 .s_ctrl = ov9740_s_ctrl,
964 .g_chip_ident = ov9740_g_chip_ident, 913 .g_chip_ident = ov9740_g_chip_ident,
965 .s_power = ov9740_s_power, 914 .s_power = ov9740_s_power,
966#ifdef CONFIG_VIDEO_ADV_DEBUG 915#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -974,6 +923,10 @@ static struct v4l2_subdev_ops ov9740_subdev_ops = {
974 .video = &ov9740_video_ops, 923 .video = &ov9740_video_ops,
975}; 924};
976 925
926static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
927 .s_ctrl = ov9740_s_ctrl,
928};
929
977/* 930/*
978 * i2c_driver function 931 * i2c_driver function
979 */ 932 */
@@ -981,16 +934,9 @@ static int ov9740_probe(struct i2c_client *client,
981 const struct i2c_device_id *did) 934 const struct i2c_device_id *did)
982{ 935{
983 struct ov9740_priv *priv; 936 struct ov9740_priv *priv;
984 struct soc_camera_device *icd = client->dev.platform_data; 937 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
985 struct soc_camera_link *icl;
986 int ret; 938 int ret;
987 939
988 if (!icd) {
989 dev_err(&client->dev, "Missing soc-camera data!\n");
990 return -EINVAL;
991 }
992
993 icl = to_soc_camera_link(icd);
994 if (!icl) { 940 if (!icl) {
995 dev_err(&client->dev, "Missing platform_data for driver\n"); 941 dev_err(&client->dev, "Missing platform_data for driver\n");
996 return -EINVAL; 942 return -EINVAL;
@@ -1003,12 +949,24 @@ static int ov9740_probe(struct i2c_client *client,
1003 } 949 }
1004 950
1005 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops); 951 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
952 v4l2_ctrl_handler_init(&priv->hdl, 13);
953 v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
954 V4L2_CID_VFLIP, 0, 1, 1, 0);
955 v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
956 V4L2_CID_HFLIP, 0, 1, 1, 0);
957 priv->subdev.ctrl_handler = &priv->hdl;
958 if (priv->hdl.error) {
959 int err = priv->hdl.error;
1006 960
1007 icd->ops = &ov9740_ops; 961 kfree(priv);
962 return err;
963 }
1008 964
1009 ret = ov9740_video_probe(icd, client); 965 ret = ov9740_video_probe(client);
966 if (!ret)
967 ret = v4l2_ctrl_handler_setup(&priv->hdl);
1010 if (ret < 0) { 968 if (ret < 0) {
1011 icd->ops = NULL; 969 v4l2_ctrl_handler_free(&priv->hdl);
1012 kfree(priv); 970 kfree(priv);
1013 } 971 }
1014 972
@@ -1019,8 +977,9 @@ static int ov9740_remove(struct i2c_client *client)
1019{ 977{
1020 struct ov9740_priv *priv = i2c_get_clientdata(client); 978 struct ov9740_priv *priv = i2c_get_clientdata(client);
1021 979
980 v4l2_device_unregister_subdev(&priv->subdev);
981 v4l2_ctrl_handler_free(&priv->hdl);
1022 kfree(priv); 982 kfree(priv);
1023
1024 return 0; 983 return 0;
1025} 984}
1026 985
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 360be226718d..01ff643e682d 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -744,9 +744,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
744/***************************************************************************/ 744/***************************************************************************/
745/* Videobuf2 operations */ 745/* Videobuf2 operations */
746 746
747static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 747static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
748 unsigned int *nplanes, unsigned int sizes[], 748 unsigned int *nbuffers, unsigned int *nplanes,
749 void *alloc_ctxs[]) 749 unsigned int sizes[], void *alloc_ctxs[])
750{ 750{
751 struct pwc_device *pdev = vb2_get_drv_priv(vq); 751 struct pwc_device *pdev = vb2_get_drv_priv(vq);
752 752
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index d07df22a5ec6..79fb22c89ae9 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -214,6 +214,7 @@ struct pxa_camera_dev {
214 unsigned long ciclk; 214 unsigned long ciclk;
215 unsigned long mclk; 215 unsigned long mclk;
216 u32 mclk_divisor; 216 u32 mclk_divisor;
217 u16 width_flags; /* max 10 bits */
217 218
218 struct list_head capture; 219 struct list_head capture;
219 220
@@ -1020,37 +1021,20 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
1020 * quick capture interface supports both. 1021 * quick capture interface supports both.
1021 */ 1022 */
1022 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? 1023 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
1023 SOCAM_MASTER : SOCAM_SLAVE) | 1024 V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
1024 SOCAM_HSYNC_ACTIVE_HIGH | 1025 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1025 SOCAM_HSYNC_ACTIVE_LOW | 1026 V4L2_MBUS_HSYNC_ACTIVE_LOW |
1026 SOCAM_VSYNC_ACTIVE_HIGH | 1027 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
1027 SOCAM_VSYNC_ACTIVE_LOW | 1028 V4L2_MBUS_VSYNC_ACTIVE_LOW |
1028 SOCAM_DATA_ACTIVE_HIGH | 1029 V4L2_MBUS_DATA_ACTIVE_HIGH |
1029 SOCAM_PCLK_SAMPLE_RISING | 1030 V4L2_MBUS_PCLK_SAMPLE_RISING |
1030 SOCAM_PCLK_SAMPLE_FALLING; 1031 V4L2_MBUS_PCLK_SAMPLE_FALLING;
1031 1032
1032 /* If requested data width is supported by the platform, use it */ 1033 /* If requested data width is supported by the platform, use it */
1033 switch (buswidth) { 1034 if ((1 << (buswidth - 1)) & pcdev->width_flags)
1034 case 10: 1035 return 0;
1035 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10))
1036 return -EINVAL;
1037 *flags |= SOCAM_DATAWIDTH_10;
1038 break;
1039 case 9:
1040 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9))
1041 return -EINVAL;
1042 *flags |= SOCAM_DATAWIDTH_9;
1043 break;
1044 case 8:
1045 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8))
1046 return -EINVAL;
1047 *flags |= SOCAM_DATAWIDTH_8;
1048 break;
1049 default:
1050 return -EINVAL;
1051 }
1052 1036
1053 return 0; 1037 return -EINVAL;
1054} 1038}
1055 1039
1056static void pxa_camera_setup_cicr(struct soc_camera_device *icd, 1040static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
@@ -1070,12 +1054,12 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1070 * Datawidth is now guaranteed to be equal to one of the three values. 1054 * Datawidth is now guaranteed to be equal to one of the three values.
1071 * We fix bit-per-pixel equal to data-width... 1055 * We fix bit-per-pixel equal to data-width...
1072 */ 1056 */
1073 switch (flags & SOCAM_DATAWIDTH_MASK) { 1057 switch (icd->current_fmt->host_fmt->bits_per_sample) {
1074 case SOCAM_DATAWIDTH_10: 1058 case 10:
1075 dw = 4; 1059 dw = 4;
1076 bpp = 0x40; 1060 bpp = 0x40;
1077 break; 1061 break;
1078 case SOCAM_DATAWIDTH_9: 1062 case 9:
1079 dw = 3; 1063 dw = 3;
1080 bpp = 0x20; 1064 bpp = 0x20;
1081 break; 1065 break;
@@ -1084,7 +1068,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1084 * Actually it can only be 8 now, 1068 * Actually it can only be 8 now,
1085 * default is just to silence compiler warnings 1069 * default is just to silence compiler warnings
1086 */ 1070 */
1087 case SOCAM_DATAWIDTH_8: 1071 case 8:
1088 dw = 2; 1072 dw = 2;
1089 bpp = 0; 1073 bpp = 0;
1090 } 1074 }
@@ -1093,11 +1077,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1093 cicr4 |= CICR4_PCLK_EN; 1077 cicr4 |= CICR4_PCLK_EN;
1094 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 1078 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1095 cicr4 |= CICR4_MCLK_EN; 1079 cicr4 |= CICR4_MCLK_EN;
1096 if (flags & SOCAM_PCLK_SAMPLE_FALLING) 1080 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1097 cicr4 |= CICR4_PCP; 1081 cicr4 |= CICR4_PCP;
1098 if (flags & SOCAM_HSYNC_ACTIVE_LOW) 1082 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1099 cicr4 |= CICR4_HSP; 1083 cicr4 |= CICR4_HSP;
1100 if (flags & SOCAM_VSYNC_ACTIVE_LOW) 1084 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1101 cicr4 |= CICR4_VSP; 1085 cicr4 |= CICR4_VSP;
1102 1086
1103 cicr0 = __raw_readl(pcdev->base + CICR0); 1087 cicr0 = __raw_readl(pcdev->base + CICR0);
@@ -1151,9 +1135,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1151 1135
1152static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1136static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1153{ 1137{
1138 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1154 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1139 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1155 struct pxa_camera_dev *pcdev = ici->priv; 1140 struct pxa_camera_dev *pcdev = ici->priv;
1156 unsigned long bus_flags, camera_flags, common_flags; 1141 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1142 unsigned long bus_flags, common_flags;
1157 int ret; 1143 int ret;
1158 struct pxa_cam *cam = icd->host_priv; 1144 struct pxa_cam *cam = icd->host_priv;
1159 1145
@@ -1162,44 +1148,58 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1162 if (ret < 0) 1148 if (ret < 0)
1163 return ret; 1149 return ret;
1164 1150
1165 camera_flags = icd->ops->query_bus_param(icd); 1151 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1166 1152 if (!ret) {
1167 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 1153 common_flags = soc_mbus_config_compatible(&cfg,
1168 if (!common_flags) 1154 bus_flags);
1169 return -EINVAL; 1155 if (!common_flags) {
1156 dev_warn(icd->parent,
1157 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1158 cfg.flags, bus_flags);
1159 return -EINVAL;
1160 }
1161 } else if (ret != -ENOIOCTLCMD) {
1162 return ret;
1163 } else {
1164 common_flags = bus_flags;
1165 }
1170 1166
1171 pcdev->channels = 1; 1167 pcdev->channels = 1;
1172 1168
1173 /* Make choises, based on platform preferences */ 1169 /* Make choises, based on platform preferences */
1174 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 1170 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1175 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 1171 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1176 if (pcdev->platform_flags & PXA_CAMERA_HSP) 1172 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1177 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 1173 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1178 else 1174 else
1179 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 1175 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1180 } 1176 }
1181 1177
1182 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 1178 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1183 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 1179 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1184 if (pcdev->platform_flags & PXA_CAMERA_VSP) 1180 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1185 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 1181 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1186 else 1182 else
1187 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 1183 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1188 } 1184 }
1189 1185
1190 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1186 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1191 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1187 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1192 if (pcdev->platform_flags & PXA_CAMERA_PCP) 1188 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1193 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1189 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1194 else 1190 else
1195 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1191 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1196 } 1192 }
1197 1193
1198 cam->flags = common_flags; 1194 cfg.flags = common_flags;
1199 1195 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1200 ret = icd->ops->set_bus_param(icd, common_flags); 1196 if (ret < 0 && ret != -ENOIOCTLCMD) {
1201 if (ret < 0) 1197 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
1198 common_flags, ret);
1202 return ret; 1199 return ret;
1200 }
1201
1202 cam->flags = common_flags;
1203 1203
1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt); 1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1205 1205
@@ -1209,17 +1209,31 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd, 1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1210 unsigned char buswidth) 1210 unsigned char buswidth)
1211{ 1211{
1212 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1212 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1213 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1213 struct pxa_camera_dev *pcdev = ici->priv; 1214 struct pxa_camera_dev *pcdev = ici->priv;
1214 unsigned long bus_flags, camera_flags; 1215 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1216 unsigned long bus_flags, common_flags;
1215 int ret = test_platform_param(pcdev, buswidth, &bus_flags); 1217 int ret = test_platform_param(pcdev, buswidth, &bus_flags);
1216 1218
1217 if (ret < 0) 1219 if (ret < 0)
1218 return ret; 1220 return ret;
1219 1221
1220 camera_flags = icd->ops->query_bus_param(icd); 1222 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1223 if (!ret) {
1224 common_flags = soc_mbus_config_compatible(&cfg,
1225 bus_flags);
1226 if (!common_flags) {
1227 dev_warn(icd->parent,
1228 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1229 cfg.flags, bus_flags);
1230 return -EINVAL;
1231 }
1232 } else if (ret == -ENOIOCTLCMD) {
1233 ret = 0;
1234 }
1221 1235
1222 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1236 return ret;
1223} 1237}
1224 1238
1225static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { 1239static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
@@ -1687,6 +1701,12 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1687 "data widths, using default 10 bit\n"); 1701 "data widths, using default 10 bit\n");
1688 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; 1702 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
1689 } 1703 }
1704 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
1705 pcdev->width_flags = 1 << 7;
1706 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
1707 pcdev->width_flags |= 1 << 8;
1708 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
1709 pcdev->width_flags |= 1 << 9;
1690 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; 1710 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
1691 if (!pcdev->mclk) { 1711 if (!pcdev->mclk) {
1692 dev_warn(&pdev->dev, 1712 dev_warn(&pdev->dev,
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 847ccc067e87..6afc61689549 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -11,13 +11,14 @@
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/i2c.h> 12#include <linux/i2c.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/v4l2-mediabus.h>
14#include <linux/videodev2.h> 15#include <linux/videodev2.h>
15 16
16#include <media/rj54n1cb0c.h> 17#include <media/rj54n1cb0c.h>
17#include <media/soc_camera.h> 18#include <media/soc_camera.h>
18#include <media/soc_mediabus.h>
19#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
20#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
21#include <media/v4l2-ctrls.h>
21 22
22#define RJ54N1_DEV_CODE 0x0400 23#define RJ54N1_DEV_CODE 0x0400
23#define RJ54N1_DEV_CODE2 0x0401 24#define RJ54N1_DEV_CODE2 0x0401
@@ -148,6 +149,7 @@ struct rj54n1_clock_div {
148 149
149struct rj54n1 { 150struct rj54n1 {
150 struct v4l2_subdev subdev; 151 struct v4l2_subdev subdev;
152 struct v4l2_ctrl_handler hdl;
151 struct rj54n1_clock_div clk_div; 153 struct rj54n1_clock_div clk_div;
152 const struct rj54n1_datafmt *fmt; 154 const struct rj54n1_datafmt *fmt;
153 struct v4l2_rect rect; /* Sensor window */ 155 struct v4l2_rect rect; /* Sensor window */
@@ -499,31 +501,6 @@ static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
499 return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80); 501 return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
500} 502}
501 503
502static int rj54n1_set_bus_param(struct soc_camera_device *icd,
503 unsigned long flags)
504{
505 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
506 struct i2c_client *client = v4l2_get_subdevdata(sd);
507 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
508
509 if (flags & SOCAM_PCLK_SAMPLE_RISING)
510 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
511 else
512 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
513}
514
515static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
516{
517 struct soc_camera_link *icl = to_soc_camera_link(icd);
518 const unsigned long flags =
519 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
520 SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
521 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
522 SOCAM_DATA_ACTIVE_HIGH;
523
524 return soc_camera_apply_sensor_flags(icl, flags);
525}
526
527static int rj54n1_set_rect(struct i2c_client *client, 504static int rj54n1_set_rect(struct i2c_client *client,
528 u16 reg_x, u16 reg_y, u16 reg_xy, 505 u16 reg_x, u16 reg_y, u16 reg_xy,
529 u32 width, u32 height) 506 u32 width, u32 height)
@@ -1202,134 +1179,51 @@ static int rj54n1_s_register(struct v4l2_subdev *sd,
1202} 1179}
1203#endif 1180#endif
1204 1181
1205static const struct v4l2_queryctrl rj54n1_controls[] = { 1182static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
1206 {
1207 .id = V4L2_CID_VFLIP,
1208 .type = V4L2_CTRL_TYPE_BOOLEAN,
1209 .name = "Flip Vertically",
1210 .minimum = 0,
1211 .maximum = 1,
1212 .step = 1,
1213 .default_value = 0,
1214 }, {
1215 .id = V4L2_CID_HFLIP,
1216 .type = V4L2_CTRL_TYPE_BOOLEAN,
1217 .name = "Flip Horizontally",
1218 .minimum = 0,
1219 .maximum = 1,
1220 .step = 1,
1221 .default_value = 0,
1222 }, {
1223 .id = V4L2_CID_GAIN,
1224 .type = V4L2_CTRL_TYPE_INTEGER,
1225 .name = "Gain",
1226 .minimum = 0,
1227 .maximum = 127,
1228 .step = 1,
1229 .default_value = 66,
1230 .flags = V4L2_CTRL_FLAG_SLIDER,
1231 }, {
1232 .id = V4L2_CID_AUTO_WHITE_BALANCE,
1233 .type = V4L2_CTRL_TYPE_BOOLEAN,
1234 .name = "Auto white balance",
1235 .minimum = 0,
1236 .maximum = 1,
1237 .step = 1,
1238 .default_value = 1,
1239 },
1240};
1241
1242static struct soc_camera_ops rj54n1_ops = {
1243 .set_bus_param = rj54n1_set_bus_param,
1244 .query_bus_param = rj54n1_query_bus_param,
1245 .controls = rj54n1_controls,
1246 .num_controls = ARRAY_SIZE(rj54n1_controls),
1247};
1248
1249static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1250{ 1183{
1184 struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
1185 struct v4l2_subdev *sd = &rj54n1->subdev;
1251 struct i2c_client *client = v4l2_get_subdevdata(sd); 1186 struct i2c_client *client = v4l2_get_subdevdata(sd);
1252 struct rj54n1 *rj54n1 = to_rj54n1(client);
1253 int data; 1187 int data;
1254 1188
1255 switch (ctrl->id) { 1189 switch (ctrl->id) {
1256 case V4L2_CID_VFLIP: 1190 case V4L2_CID_VFLIP:
1257 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); 1191 if (ctrl->val)
1258 if (data < 0)
1259 return -EIO;
1260 ctrl->value = !(data & 1);
1261 break;
1262 case V4L2_CID_HFLIP:
1263 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
1264 if (data < 0)
1265 return -EIO;
1266 ctrl->value = !(data & 2);
1267 break;
1268 case V4L2_CID_GAIN:
1269 data = reg_read(client, RJ54N1_Y_GAIN);
1270 if (data < 0)
1271 return -EIO;
1272
1273 ctrl->value = data / 2;
1274 break;
1275 case V4L2_CID_AUTO_WHITE_BALANCE:
1276 ctrl->value = rj54n1->auto_wb;
1277 break;
1278 }
1279
1280 return 0;
1281}
1282
1283static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1284{
1285 int data;
1286 struct i2c_client *client = v4l2_get_subdevdata(sd);
1287 struct rj54n1 *rj54n1 = to_rj54n1(client);
1288 const struct v4l2_queryctrl *qctrl;
1289
1290 qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
1291 if (!qctrl)
1292 return -EINVAL;
1293
1294 switch (ctrl->id) {
1295 case V4L2_CID_VFLIP:
1296 if (ctrl->value)
1297 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1); 1192 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
1298 else 1193 else
1299 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1); 1194 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
1300 if (data < 0) 1195 if (data < 0)
1301 return -EIO; 1196 return -EIO;
1302 break; 1197 return 0;
1303 case V4L2_CID_HFLIP: 1198 case V4L2_CID_HFLIP:
1304 if (ctrl->value) 1199 if (ctrl->val)
1305 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2); 1200 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
1306 else 1201 else
1307 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2); 1202 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
1308 if (data < 0) 1203 if (data < 0)
1309 return -EIO; 1204 return -EIO;
1310 break; 1205 return 0;
1311 case V4L2_CID_GAIN: 1206 case V4L2_CID_GAIN:
1312 if (ctrl->value > qctrl->maximum || 1207 if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
1313 ctrl->value < qctrl->minimum)
1314 return -EINVAL;
1315 else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
1316 return -EIO; 1208 return -EIO;
1317 break; 1209 return 0;
1318 case V4L2_CID_AUTO_WHITE_BALANCE: 1210 case V4L2_CID_AUTO_WHITE_BALANCE:
1319 /* Auto WB area - whole image */ 1211 /* Auto WB area - whole image */
1320 if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7, 1212 if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
1321 0x80) < 0) 1213 0x80) < 0)
1322 return -EIO; 1214 return -EIO;
1323 rj54n1->auto_wb = ctrl->value; 1215 rj54n1->auto_wb = ctrl->val;
1324 break; 1216 return 0;
1325 } 1217 }
1326 1218
1327 return 0; 1219 return -EINVAL;
1328} 1220}
1329 1221
1222static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
1223 .s_ctrl = rj54n1_s_ctrl,
1224};
1225
1330static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { 1226static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1331 .g_ctrl = rj54n1_g_ctrl,
1332 .s_ctrl = rj54n1_s_ctrl,
1333 .g_chip_ident = rj54n1_g_chip_ident, 1227 .g_chip_ident = rj54n1_g_chip_ident,
1334#ifdef CONFIG_VIDEO_ADV_DEBUG 1228#ifdef CONFIG_VIDEO_ADV_DEBUG
1335 .g_register = rj54n1_g_register, 1229 .g_register = rj54n1_g_register,
@@ -1337,6 +1231,36 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1337#endif 1231#endif
1338}; 1232};
1339 1233
1234static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
1235 struct v4l2_mbus_config *cfg)
1236{
1237 struct i2c_client *client = v4l2_get_subdevdata(sd);
1238 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1239
1240 cfg->flags =
1241 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
1242 V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
1243 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1244 cfg->type = V4L2_MBUS_PARALLEL;
1245 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1246
1247 return 0;
1248}
1249
1250static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
1251 const struct v4l2_mbus_config *cfg)
1252{
1253 struct i2c_client *client = v4l2_get_subdevdata(sd);
1254 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1255
1256 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
1257 if (soc_camera_apply_board_flags(icl, cfg) &
1258 V4L2_MBUS_PCLK_SAMPLE_RISING)
1259 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
1260 else
1261 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
1262}
1263
1340static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { 1264static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1341 .s_stream = rj54n1_s_stream, 1265 .s_stream = rj54n1_s_stream,
1342 .s_mbus_fmt = rj54n1_s_fmt, 1266 .s_mbus_fmt = rj54n1_s_fmt,
@@ -1346,6 +1270,8 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1346 .g_crop = rj54n1_g_crop, 1270 .g_crop = rj54n1_g_crop,
1347 .s_crop = rj54n1_s_crop, 1271 .s_crop = rj54n1_s_crop,
1348 .cropcap = rj54n1_cropcap, 1272 .cropcap = rj54n1_cropcap,
1273 .g_mbus_config = rj54n1_g_mbus_config,
1274 .s_mbus_config = rj54n1_s_mbus_config,
1349}; 1275};
1350 1276
1351static struct v4l2_subdev_ops rj54n1_subdev_ops = { 1277static struct v4l2_subdev_ops rj54n1_subdev_ops = {
@@ -1357,17 +1283,12 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = {
1357 * Interface active, can use i2c. If it fails, it can indeed mean, that 1283 * Interface active, can use i2c. If it fails, it can indeed mean, that
1358 * this wasn't our capture interface, so, we wait for the right one 1284 * this wasn't our capture interface, so, we wait for the right one
1359 */ 1285 */
1360static int rj54n1_video_probe(struct soc_camera_device *icd, 1286static int rj54n1_video_probe(struct i2c_client *client,
1361 struct i2c_client *client,
1362 struct rj54n1_pdata *priv) 1287 struct rj54n1_pdata *priv)
1363{ 1288{
1364 int data1, data2; 1289 int data1, data2;
1365 int ret; 1290 int ret;
1366 1291
1367 /* We must have a parent by now. And it cannot be a wrong one. */
1368 BUG_ON(!icd->parent ||
1369 to_soc_camera_host(icd->parent)->nr != icd->iface);
1370
1371 /* Read out the chip version register */ 1292 /* Read out the chip version register */
1372 data1 = reg_read(client, RJ54N1_DEV_CODE); 1293 data1 = reg_read(client, RJ54N1_DEV_CODE);
1373 data2 = reg_read(client, RJ54N1_DEV_CODE2); 1294 data2 = reg_read(client, RJ54N1_DEV_CODE2);
@@ -1395,18 +1316,11 @@ static int rj54n1_probe(struct i2c_client *client,
1395 const struct i2c_device_id *did) 1316 const struct i2c_device_id *did)
1396{ 1317{
1397 struct rj54n1 *rj54n1; 1318 struct rj54n1 *rj54n1;
1398 struct soc_camera_device *icd = client->dev.platform_data; 1319 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1399 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1320 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1400 struct soc_camera_link *icl;
1401 struct rj54n1_pdata *rj54n1_priv; 1321 struct rj54n1_pdata *rj54n1_priv;
1402 int ret; 1322 int ret;
1403 1323
1404 if (!icd) {
1405 dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
1406 return -EINVAL;
1407 }
1408
1409 icl = to_soc_camera_link(icd);
1410 if (!icl || !icl->priv) { 1324 if (!icl || !icl->priv) {
1411 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); 1325 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
1412 return -EINVAL; 1326 return -EINVAL;
@@ -1425,8 +1339,22 @@ static int rj54n1_probe(struct i2c_client *client,
1425 return -ENOMEM; 1339 return -ENOMEM;
1426 1340
1427 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops); 1341 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
1342 v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
1343 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1344 V4L2_CID_VFLIP, 0, 1, 1, 0);
1345 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1346 V4L2_CID_HFLIP, 0, 1, 1, 0);
1347 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1348 V4L2_CID_GAIN, 0, 127, 1, 66);
1349 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1350 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1351 rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
1352 if (rj54n1->hdl.error) {
1353 int err = rj54n1->hdl.error;
1428 1354
1429 icd->ops = &rj54n1_ops; 1355 kfree(rj54n1);
1356 return err;
1357 }
1430 1358
1431 rj54n1->clk_div = clk_div; 1359 rj54n1->clk_div = clk_div;
1432 rj54n1->rect.left = RJ54N1_COLUMN_SKIP; 1360 rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
@@ -1440,25 +1368,24 @@ static int rj54n1_probe(struct i2c_client *client,
1440 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) / 1368 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
1441 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1); 1369 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
1442 1370
1443 ret = rj54n1_video_probe(icd, client, rj54n1_priv); 1371 ret = rj54n1_video_probe(client, rj54n1_priv);
1444 if (ret < 0) { 1372 if (ret < 0) {
1445 icd->ops = NULL; 1373 v4l2_ctrl_handler_free(&rj54n1->hdl);
1446 kfree(rj54n1); 1374 kfree(rj54n1);
1447 return ret; 1375 return ret;
1448 } 1376 }
1449 1377 return v4l2_ctrl_handler_setup(&rj54n1->hdl);
1450 return ret;
1451} 1378}
1452 1379
1453static int rj54n1_remove(struct i2c_client *client) 1380static int rj54n1_remove(struct i2c_client *client)
1454{ 1381{
1455 struct rj54n1 *rj54n1 = to_rj54n1(client); 1382 struct rj54n1 *rj54n1 = to_rj54n1(client);
1456 struct soc_camera_device *icd = client->dev.platform_data; 1383 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1457 struct soc_camera_link *icl = to_soc_camera_link(icd);
1458 1384
1459 icd->ops = NULL; 1385 v4l2_device_unregister_subdev(&rj54n1->subdev);
1460 if (icl->free_bus) 1386 if (icl->free_bus)
1461 icl->free_bus(icl); 1387 icl->free_bus(icl);
1388 v4l2_ctrl_handler_free(&rj54n1->hdl);
1462 kfree(rj54n1); 1389 kfree(rj54n1);
1463 1390
1464 return 0; 1391 return 0;
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
new file mode 100644
index 000000000000..2446736b7871
--- /dev/null
+++ b/drivers/media/video/s5k6aa.c
@@ -0,0 +1,1680 @@
1/*
2 * Driver for Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor
3 * with embedded SoC ISP.
4 *
5 * Copyright (C) 2011, Samsung Electronics Co., Ltd.
6 * Sylwester Nawrocki <s.nawrocki@samsung.com>
7 *
8 * Based on a driver authored by Dongsoo Nathaniel Kim.
9 * Copyright (C) 2009, Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/clk.h>
18#include <linux/delay.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/media.h>
22#include <linux/regulator/consumer.h>
23#include <linux/slab.h>
24
25#include <media/media-entity.h>
26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-subdev.h>
29#include <media/v4l2-mediabus.h>
30#include <media/s5k6aa.h>
31
32static int debug;
33module_param(debug, int, 0644);
34
35#define DRIVER_NAME "S5K6AA"
36
37/* The token to indicate array termination */
38#define S5K6AA_TERM 0xffff
39#define S5K6AA_OUT_WIDTH_DEF 640
40#define S5K6AA_OUT_HEIGHT_DEF 480
41#define S5K6AA_WIN_WIDTH_MAX 1280
42#define S5K6AA_WIN_HEIGHT_MAX 1024
43#define S5K6AA_WIN_WIDTH_MIN 8
44#define S5K6AA_WIN_HEIGHT_MIN 8
45
46/*
47 * H/W register Interface (0xD0000000 - 0xD0000FFF)
48 */
49#define AHB_MSB_ADDR_PTR 0xfcfc
50#define GEN_REG_OFFSH 0xd000
51#define REG_CMDWR_ADDRH 0x0028
52#define REG_CMDWR_ADDRL 0x002a
53#define REG_CMDRD_ADDRH 0x002c
54#define REG_CMDRD_ADDRL 0x002e
55#define REG_CMDBUF0_ADDR 0x0f12
56#define REG_CMDBUF1_ADDR 0x0f10
57
58/*
59 * Host S/W Register interface (0x70000000 - 0x70002000)
60 * The value of the two most significant address bytes is 0x7000,
61 * (HOST_SWIF_OFFS_H). The register addresses below specify 2 LSBs.
62 */
63#define HOST_SWIF_OFFSH 0x7000
64
65/* Initialization parameters */
66/* Master clock frequency in KHz */
67#define REG_I_INCLK_FREQ_L 0x01b8
68#define REG_I_INCLK_FREQ_H 0x01ba
69#define MIN_MCLK_FREQ_KHZ 6000U
70#define MAX_MCLK_FREQ_KHZ 27000U
71#define REG_I_USE_NPVI_CLOCKS 0x01c6
72#define REG_I_USE_NMIPI_CLOCKS 0x01c8
73
74/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
75#define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
76#define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
77#define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
78#define SYS_PLL_OUT_FREQ (48000000 / 4000)
79#define PCLK_FREQ_MIN (24000000 / 4000)
80#define PCLK_FREQ_MAX (48000000 / 4000)
81#define REG_I_INIT_PARAMS_UPDATED 0x01e0
82#define REG_I_ERROR_INFO 0x01e2
83
84/* General purpose parameters */
85#define REG_USER_BRIGHTNESS 0x01e4
86#define REG_USER_CONTRAST 0x01e6
87#define REG_USER_SATURATION 0x01e8
88#define REG_USER_SHARPBLUR 0x01ea
89
90#define REG_G_SPEC_EFFECTS 0x01ee
91#define REG_G_ENABLE_PREV 0x01f0
92#define REG_G_ENABLE_PREV_CHG 0x01f2
93#define REG_G_NEW_CFG_SYNC 0x01f8
94#define REG_G_PREVZOOM_IN_WIDTH 0x020a
95#define REG_G_PREVZOOM_IN_HEIGHT 0x020c
96#define REG_G_PREVZOOM_IN_XOFFS 0x020e
97#define REG_G_PREVZOOM_IN_YOFFS 0x0210
98#define REG_G_INPUTS_CHANGE_REQ 0x021a
99#define REG_G_ACTIVE_PREV_CFG 0x021c
100#define REG_G_PREV_CFG_CHG 0x021e
101#define REG_G_PREV_OPEN_AFTER_CH 0x0220
102#define REG_G_PREV_CFG_ERROR 0x0222
103
104/* Preview control section. n = 0...4. */
105#define PREG(n, x) ((n) * 0x26 + x)
106#define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
107#define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
108#define REG_P_FMT(n) PREG(n, 0x0246)
109#define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
110#define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
111#define REG_P_PVI_MASK(n) PREG(n, 0x024c)
112#define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
113#define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
114#define FR_RATE_DYNAMIC 0
115#define FR_RATE_FIXED 1
116#define FR_RATE_FIXED_ACCURATE 2
117#define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
118#define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
119#define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
120/* Frame period in 0.1 ms units */
121#define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
122#define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
123/* Conversion to REG_P_[MAX/MIN]_FR_TIME value; __t: time in us */
124#define US_TO_FR_TIME(__t) ((__t) / 100)
125#define S5K6AA_MIN_FR_TIME 33300 /* us */
126#define S5K6AA_MAX_FR_TIME 650000 /* us */
127#define S5K6AA_MAX_HIGHRES_FR_TIME 666 /* x100 us */
128/* The below 5 registers are for "device correction" values */
129#define REG_P_COLORTEMP(n) PREG(n, 0x025e)
130#define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
131
132/* Extended image property controls */
133/* Exposure time in 10 us units */
134#define REG_SF_USR_EXPOSURE_L 0x03c6
135#define REG_SF_USR_EXPOSURE_H 0x03c8
136#define REG_SF_USR_EXPOSURE_CHG 0x03ca
137#define REG_SF_USR_TOT_GAIN 0x03cc
138#define REG_SF_USR_TOT_GAIN_CHG 0x03ce
139#define REG_SF_RGAIN 0x03d0
140#define REG_SF_RGAIN_CHG 0x03d2
141#define REG_SF_GGAIN 0x03d4
142#define REG_SF_GGAIN_CHG 0x03d6
143#define REG_SF_BGAIN 0x03d8
144#define REG_SF_BGAIN_CHG 0x03da
145#define REG_SF_FLICKER_QUANT 0x03dc
146#define REG_SF_FLICKER_QUANT_CHG 0x03de
147
148/* Output interface (parallel/MIPI) setup */
149#define REG_OIF_EN_MIPI_LANES 0x03fa
150#define REG_OIF_EN_PACKETS 0x03fc
151#define REG_OIF_CFG_CHG 0x03fe
152
153/* Auto-algorithms enable mask */
154#define REG_DBG_AUTOALG_EN 0x0400
155#define AALG_ALL_EN_MASK (1 << 0)
156#define AALG_AE_EN_MASK (1 << 1)
157#define AALG_DIVLEI_EN_MASK (1 << 2)
158#define AALG_WB_EN_MASK (1 << 3)
159#define AALG_FLICKER_EN_MASK (1 << 5)
160#define AALG_FIT_EN_MASK (1 << 6)
161#define AALG_WRHW_EN_MASK (1 << 7)
162
163/* Firmware revision information */
164#define REG_FW_APIVER 0x012e
165#define S5K6AAFX_FW_APIVER 0x0001
166#define REG_FW_REVISION 0x0130
167
168/* For now we use only one user configuration register set */
169#define S5K6AA_MAX_PRESETS 1
170
171static const char * const s5k6aa_supply_names[] = {
172 "vdd_core", /* Digital core supply 1.5V (1.4V to 1.6V) */
173 "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
174 "vdd_reg", /* Regulator input power 1.8V (1.7V to 1.9V)
175 or 2.8V (2.6V to 3.0) */
176 "vddio", /* I/O supply 1.8V (1.65V to 1.95V)
177 or 2.8V (2.5V to 3.1V) */
178};
179#define S5K6AA_NUM_SUPPLIES ARRAY_SIZE(s5k6aa_supply_names)
180
181enum s5k6aa_gpio_id {
182 STBY,
183 RST,
184 GPIO_NUM,
185};
186
187struct s5k6aa_regval {
188 u16 addr;
189 u16 val;
190};
191
192struct s5k6aa_pixfmt {
193 enum v4l2_mbus_pixelcode code;
194 u32 colorspace;
195 /* REG_P_FMT(x) register value */
196 u16 reg_p_fmt;
197};
198
199struct s5k6aa_preset {
200 /* output pixel format and resolution */
201 struct v4l2_mbus_framefmt mbus_fmt;
202 u8 clk_id;
203 u8 index;
204};
205
206struct s5k6aa_ctrls {
207 struct v4l2_ctrl_handler handler;
208 /* Auto / manual white balance cluster */
209 struct v4l2_ctrl *awb;
210 struct v4l2_ctrl *gain_red;
211 struct v4l2_ctrl *gain_blue;
212 struct v4l2_ctrl *gain_green;
213 /* Mirror cluster */
214 struct v4l2_ctrl *hflip;
215 struct v4l2_ctrl *vflip;
216 /* Auto exposure / manual exposure and gain cluster */
217 struct v4l2_ctrl *auto_exp;
218 struct v4l2_ctrl *exposure;
219 struct v4l2_ctrl *gain;
220};
221
222struct s5k6aa_interval {
223 u16 reg_fr_time;
224 struct v4l2_fract interval;
225 /* Maximum rectangle for the interval */
226 struct v4l2_frmsize_discrete size;
227};
228
229struct s5k6aa {
230 struct v4l2_subdev sd;
231 struct media_pad pad;
232
233 enum v4l2_mbus_type bus_type;
234 u8 mipi_lanes;
235
236 int (*s_power)(int enable);
237 struct regulator_bulk_data supplies[S5K6AA_NUM_SUPPLIES];
238 struct s5k6aa_gpio gpio[GPIO_NUM];
239
240 /* external master clock frequency */
241 unsigned long mclk_frequency;
242 /* ISP internal master clock frequency */
243 u16 clk_fop;
244 /* output pixel clock frequency range */
245 u16 pclk_fmin;
246 u16 pclk_fmax;
247
248 unsigned int inv_hflip:1;
249 unsigned int inv_vflip:1;
250
251 /* protects the struct members below */
252 struct mutex lock;
253
254 /* sensor matrix scan window */
255 struct v4l2_rect ccd_rect;
256
257 struct s5k6aa_ctrls ctrls;
258 struct s5k6aa_preset presets[S5K6AA_MAX_PRESETS];
259 struct s5k6aa_preset *preset;
260 const struct s5k6aa_interval *fiv;
261
262 unsigned int streaming:1;
263 unsigned int apply_cfg:1;
264 unsigned int apply_crop:1;
265 unsigned int power;
266};
267
268static struct s5k6aa_regval s5k6aa_analog_config[] = {
269 /* Analog settings */
270 { 0x112a, 0x0000 }, { 0x1132, 0x0000 },
271 { 0x113e, 0x0000 }, { 0x115c, 0x0000 },
272 { 0x1164, 0x0000 }, { 0x1174, 0x0000 },
273 { 0x1178, 0x0000 }, { 0x077a, 0x0000 },
274 { 0x077c, 0x0000 }, { 0x077e, 0x0000 },
275 { 0x0780, 0x0000 }, { 0x0782, 0x0000 },
276 { 0x0784, 0x0000 }, { 0x0786, 0x0000 },
277 { 0x0788, 0x0000 }, { 0x07a2, 0x0000 },
278 { 0x07a4, 0x0000 }, { 0x07a6, 0x0000 },
279 { 0x07a8, 0x0000 }, { 0x07b6, 0x0000 },
280 { 0x07b8, 0x0002 }, { 0x07ba, 0x0004 },
281 { 0x07bc, 0x0004 }, { 0x07be, 0x0005 },
282 { 0x07c0, 0x0005 }, { S5K6AA_TERM, 0 },
283};
284
285/* TODO: Add RGB888 and Bayer format */
286static const struct s5k6aa_pixfmt s5k6aa_formats[] = {
287 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 },
288 /* range 16-240 */
289 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 },
290 { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
291};
292
293static const struct s5k6aa_interval s5k6aa_intervals[] = {
294 { 1000, {10000, 1000000}, {1280, 1024} }, /* 10 fps */
295 { 666, {15000, 1000000}, {1280, 1024} }, /* 15 fps */
296 { 500, {20000, 1000000}, {1280, 720} }, /* 20 fps */
297 { 400, {25000, 1000000}, {640, 480} }, /* 25 fps */
298 { 333, {33300, 1000000}, {640, 480} }, /* 30 fps */
299};
300
301#define S5K6AA_INTERVAL_DEF_INDEX 1 /* 15 fps */
302
303static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
304{
305 return &container_of(ctrl->handler, struct s5k6aa, ctrls.handler)->sd;
306}
307
308static inline struct s5k6aa *to_s5k6aa(struct v4l2_subdev *sd)
309{
310 return container_of(sd, struct s5k6aa, sd);
311}
312
313/* Set initial values for all preview presets */
314static void s5k6aa_presets_data_init(struct s5k6aa *s5k6aa)
315{
316 struct s5k6aa_preset *preset = &s5k6aa->presets[0];
317 int i;
318
319 for (i = 0; i < S5K6AA_MAX_PRESETS; i++) {
320 preset->mbus_fmt.width = S5K6AA_OUT_WIDTH_DEF;
321 preset->mbus_fmt.height = S5K6AA_OUT_HEIGHT_DEF;
322 preset->mbus_fmt.code = s5k6aa_formats[0].code;
323 preset->index = i;
324 preset->clk_id = 0;
325 preset++;
326 }
327
328 s5k6aa->fiv = &s5k6aa_intervals[S5K6AA_INTERVAL_DEF_INDEX];
329 s5k6aa->preset = &s5k6aa->presets[0];
330}
331
332static int s5k6aa_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
333{
334 u8 wbuf[2] = {addr >> 8, addr & 0xFF};
335 struct i2c_msg msg[2];
336 u8 rbuf[2];
337 int ret;
338
339 msg[0].addr = client->addr;
340 msg[0].flags = 0;
341 msg[0].len = 2;
342 msg[0].buf = wbuf;
343
344 msg[1].addr = client->addr;
345 msg[1].flags = I2C_M_RD;
346 msg[1].len = 2;
347 msg[1].buf = rbuf;
348
349 ret = i2c_transfer(client->adapter, msg, 2);
350 *val = be16_to_cpu(*((u16 *)rbuf));
351
352 v4l2_dbg(3, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
353
354 return ret == 2 ? 0 : ret;
355}
356
357static int s5k6aa_i2c_write(struct i2c_client *client, u16 addr, u16 val)
358{
359 u8 buf[4] = {addr >> 8, addr & 0xFF, val >> 8, val & 0xFF};
360
361 int ret = i2c_master_send(client, buf, 4);
362 v4l2_dbg(3, debug, client, "i2c_write: 0x%04X : 0x%04x\n", addr, val);
363
364 return ret == 4 ? 0 : ret;
365}
366
367/* The command register write, assumes Command_Wr_addH = 0x7000. */
368static int s5k6aa_write(struct i2c_client *c, u16 addr, u16 val)
369{
370 int ret = s5k6aa_i2c_write(c, REG_CMDWR_ADDRL, addr);
371 if (ret)
372 return ret;
373 return s5k6aa_i2c_write(c, REG_CMDBUF0_ADDR, val);
374}
375
376/* The command register read, assumes Command_Rd_addH = 0x7000. */
377static int s5k6aa_read(struct i2c_client *client, u16 addr, u16 *val)
378{
379 int ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRL, addr);
380 if (ret)
381 return ret;
382 return s5k6aa_i2c_read(client, REG_CMDBUF0_ADDR, val);
383}
384
385static int s5k6aa_write_array(struct v4l2_subdev *sd,
386 const struct s5k6aa_regval *msg)
387{
388 struct i2c_client *client = v4l2_get_subdevdata(sd);
389 u16 addr_incr = 0;
390 int ret = 0;
391
392 while (msg->addr != S5K6AA_TERM) {
393 if (addr_incr != 2)
394 ret = s5k6aa_i2c_write(client, REG_CMDWR_ADDRL,
395 msg->addr);
396 if (ret)
397 break;
398 ret = s5k6aa_i2c_write(client, REG_CMDBUF0_ADDR, msg->val);
399 if (ret)
400 break;
401 /* Assume that msg->addr is always less than 0xfffc */
402 addr_incr = (msg + 1)->addr - msg->addr;
403 msg++;
404 }
405
406 return ret;
407}
408
409/* Configure the AHB high address bytes for GTG registers access */
410static int s5k6aa_set_ahb_address(struct i2c_client *client)
411{
412 int ret = s5k6aa_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
413 if (ret)
414 return ret;
415 ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRH, HOST_SWIF_OFFSH);
416 if (ret)
417 return ret;
418 return s5k6aa_i2c_write(client, REG_CMDWR_ADDRH, HOST_SWIF_OFFSH);
419}
420
421/**
422 * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
423 *
424 * Configure the internal ISP PLL for the required output frequency.
425 * Locking: called with s5k6aa.lock mutex held.
426 */
427static int s5k6aa_configure_pixel_clocks(struct s5k6aa *s5k6aa)
428{
429 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
430 unsigned long fmclk = s5k6aa->mclk_frequency / 1000;
431 u16 status;
432 int ret;
433
434 if (WARN(fmclk < MIN_MCLK_FREQ_KHZ || fmclk > MAX_MCLK_FREQ_KHZ,
435 "Invalid clock frequency: %ld\n", fmclk))
436 return -EINVAL;
437
438 s5k6aa->pclk_fmin = PCLK_FREQ_MIN;
439 s5k6aa->pclk_fmax = PCLK_FREQ_MAX;
440 s5k6aa->clk_fop = SYS_PLL_OUT_FREQ;
441
442 /* External input clock frequency in kHz */
443 ret = s5k6aa_write(c, REG_I_INCLK_FREQ_H, fmclk >> 16);
444 if (!ret)
445 ret = s5k6aa_write(c, REG_I_INCLK_FREQ_L, fmclk & 0xFFFF);
446 if (!ret)
447 ret = s5k6aa_write(c, REG_I_USE_NPVI_CLOCKS, 1);
448 /* Internal PLL frequency */
449 if (!ret)
450 ret = s5k6aa_write(c, REG_I_OPCLK_4KHZ(0), s5k6aa->clk_fop);
451 if (!ret)
452 ret = s5k6aa_write(c, REG_I_MIN_OUTRATE_4KHZ(0),
453 s5k6aa->pclk_fmin);
454 if (!ret)
455 ret = s5k6aa_write(c, REG_I_MAX_OUTRATE_4KHZ(0),
456 s5k6aa->pclk_fmax);
457 if (!ret)
458 ret = s5k6aa_write(c, REG_I_INIT_PARAMS_UPDATED, 1);
459 if (!ret)
460 ret = s5k6aa_read(c, REG_I_ERROR_INFO, &status);
461
462 return ret ? ret : (status ? -EINVAL : 0);
463}
464
465/* Set horizontal and vertical image flipping */
466static int s5k6aa_set_mirror(struct s5k6aa *s5k6aa, int horiz_flip)
467{
468 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
469 int index = s5k6aa->preset->index;
470
471 unsigned int vflip = s5k6aa->ctrls.vflip->val ^ s5k6aa->inv_vflip;
472 unsigned int flip = (horiz_flip ^ s5k6aa->inv_hflip) | (vflip << 1);
473
474 return s5k6aa_write(client, REG_P_PREV_MIRROR(index), flip);
475}
476
477/* Configure auto/manual white balance and R/G/B gains */
478static int s5k6aa_set_awb(struct s5k6aa *s5k6aa, int awb)
479{
480 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
481 struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
482 u16 reg;
483
484 int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &reg);
485
486 if (!ret && !awb) {
487 ret = s5k6aa_write(c, REG_SF_RGAIN, ctrls->gain_red->val);
488 if (!ret)
489 ret = s5k6aa_write(c, REG_SF_RGAIN_CHG, 1);
490 if (ret)
491 return ret;
492
493 ret = s5k6aa_write(c, REG_SF_GGAIN, ctrls->gain_green->val);
494 if (!ret)
495 ret = s5k6aa_write(c, REG_SF_GGAIN_CHG, 1);
496 if (ret)
497 return ret;
498
499 ret = s5k6aa_write(c, REG_SF_BGAIN, ctrls->gain_blue->val);
500 if (!ret)
501 ret = s5k6aa_write(c, REG_SF_BGAIN_CHG, 1);
502 }
503 if (!ret) {
504 reg = awb ? reg | AALG_WB_EN_MASK : reg & ~AALG_WB_EN_MASK;
505 ret = s5k6aa_write(c, REG_DBG_AUTOALG_EN, reg);
506 }
507
508 return ret;
509}
510
511/* Program FW with exposure time, 'exposure' in us units */
512static int s5k6aa_set_user_exposure(struct i2c_client *client, int exposure)
513{
514 unsigned int time = exposure / 10;
515
516 int ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_L, time & 0xffff);
517 if (!ret)
518 ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_H, time >> 16);
519 if (ret)
520 return ret;
521 return s5k6aa_write(client, REG_SF_USR_EXPOSURE_CHG, 1);
522}
523
524static int s5k6aa_set_user_gain(struct i2c_client *client, int gain)
525{
526 int ret = s5k6aa_write(client, REG_SF_USR_TOT_GAIN, gain);
527 if (ret)
528 return ret;
529 return s5k6aa_write(client, REG_SF_USR_TOT_GAIN_CHG, 1);
530}
531
532/* Set auto/manual exposure and total gain */
533static int s5k6aa_set_auto_exposure(struct s5k6aa *s5k6aa, int value)
534{
535 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
536 unsigned int exp_time = s5k6aa->ctrls.exposure->val;
537 u16 auto_alg;
538
539 int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &auto_alg);
540 if (ret)
541 return ret;
542
543 v4l2_dbg(1, debug, c, "man_exp: %d, auto_exp: %d, a_alg: 0x%x\n",
544 exp_time, value, auto_alg);
545
546 if (value == V4L2_EXPOSURE_AUTO) {
547 auto_alg |= AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK;
548 } else {
549 ret = s5k6aa_set_user_exposure(c, exp_time);
550 if (ret)
551 return ret;
552 ret = s5k6aa_set_user_gain(c, s5k6aa->ctrls.gain->val);
553 if (ret)
554 return ret;
555 auto_alg &= ~(AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK);
556 }
557
558 return s5k6aa_write(c, REG_DBG_AUTOALG_EN, auto_alg);
559}
560
561static int s5k6aa_set_anti_flicker(struct s5k6aa *s5k6aa, int value)
562{
563 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
564 u16 auto_alg;
565 int ret;
566
567 ret = s5k6aa_read(client, REG_DBG_AUTOALG_EN, &auto_alg);
568 if (ret)
569 return ret;
570
571 if (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
572 auto_alg |= AALG_FLICKER_EN_MASK;
573 } else {
574 auto_alg &= ~AALG_FLICKER_EN_MASK;
575 /* The V4L2_CID_LINE_FREQUENCY control values match
576 * the register values */
577 ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT, value);
578 if (ret)
579 return ret;
580 ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT_CHG, 1);
581 if (ret)
582 return ret;
583 }
584
585 return s5k6aa_write(client, REG_DBG_AUTOALG_EN, auto_alg);
586}
587
588static int s5k6aa_set_colorfx(struct s5k6aa *s5k6aa, int val)
589{
590 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
591 static const struct v4l2_control colorfx[] = {
592 { V4L2_COLORFX_NONE, 0 },
593 { V4L2_COLORFX_BW, 1 },
594 { V4L2_COLORFX_NEGATIVE, 2 },
595 { V4L2_COLORFX_SEPIA, 3 },
596 { V4L2_COLORFX_SKY_BLUE, 4 },
597 { V4L2_COLORFX_SKETCH, 5 },
598 };
599 int i;
600
601 for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
602 if (colorfx[i].id == val)
603 return s5k6aa_write(client, REG_G_SPEC_EFFECTS,
604 colorfx[i].value);
605 }
606 return -EINVAL;
607}
608
609static int s5k6aa_preview_config_status(struct i2c_client *client)
610{
611 u16 error = 0;
612 int ret = s5k6aa_read(client, REG_G_PREV_CFG_ERROR, &error);
613
614 v4l2_dbg(1, debug, client, "error: 0x%x (%d)\n", error, ret);
615 return ret ? ret : (error ? -EINVAL : 0);
616}
617
618static int s5k6aa_get_pixfmt_index(struct s5k6aa *s5k6aa,
619 struct v4l2_mbus_framefmt *mf)
620{
621 unsigned int i;
622
623 for (i = 0; i < ARRAY_SIZE(s5k6aa_formats); i++)
624 if (mf->colorspace == s5k6aa_formats[i].colorspace &&
625 mf->code == s5k6aa_formats[i].code)
626 return i;
627 return 0;
628}
629
630static int s5k6aa_set_output_framefmt(struct s5k6aa *s5k6aa,
631 struct s5k6aa_preset *preset)
632{
633 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
634 int fmt_index = s5k6aa_get_pixfmt_index(s5k6aa, &preset->mbus_fmt);
635 int ret;
636
637 ret = s5k6aa_write(client, REG_P_OUT_WIDTH(preset->index),
638 preset->mbus_fmt.width);
639 if (!ret)
640 ret = s5k6aa_write(client, REG_P_OUT_HEIGHT(preset->index),
641 preset->mbus_fmt.height);
642 if (!ret)
643 ret = s5k6aa_write(client, REG_P_FMT(preset->index),
644 s5k6aa_formats[fmt_index].reg_p_fmt);
645 return ret;
646}
647
648static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
649{
650 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
651 struct v4l2_rect *r = &s5k6aa->ccd_rect;
652 int ret;
653
654 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
655 if (!ret)
656 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
657 if (!ret)
658 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
659 if (!ret)
660 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
661 if (!ret)
662 ret = s5k6aa_write(c, REG_G_INPUTS_CHANGE_REQ, 1);
663 if (!ret)
664 s5k6aa->apply_crop = 0;
665
666 return ret;
667}
668
669/**
670 * s5k6aa_configure_video_bus - configure the video output interface
671 * @bus_type: video bus type: parallel or MIPI-CSI
672 * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
673 *
674 * Note: Only parallel bus operation has been tested.
675 */
676static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
677 enum v4l2_mbus_type bus_type, int nlanes)
678{
679 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
680 u16 cfg = 0;
681 int ret;
682
683 /*
684 * TODO: The sensor is supposed to support BT.601 and BT.656
685 * but there is nothing indicating how to switch between both
686 * in the datasheet. For now default BT.601 interface is assumed.
687 */
688 if (bus_type == V4L2_MBUS_CSI2)
689 cfg = nlanes;
690 else if (bus_type != V4L2_MBUS_PARALLEL)
691 return -EINVAL;
692
693 ret = s5k6aa_write(client, REG_OIF_EN_MIPI_LANES, cfg);
694 if (ret)
695 return ret;
696 return s5k6aa_write(client, REG_OIF_CFG_CHG, 1);
697}
698
699/* This function should be called when switching to new user configuration set*/
700static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
701 int cid)
702{
703 unsigned long end = jiffies + msecs_to_jiffies(timeout);
704 u16 reg = 1;
705 int ret;
706
707 ret = s5k6aa_write(client, REG_G_ACTIVE_PREV_CFG, cid);
708 if (!ret)
709 ret = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
710 if (!ret)
711 ret = s5k6aa_write(client, REG_G_NEW_CFG_SYNC, 1);
712 if (timeout == 0)
713 return ret;
714
715 while (ret >= 0 && time_is_after_jiffies(end)) {
716 ret = s5k6aa_read(client, REG_G_NEW_CFG_SYNC, &reg);
717 if (!reg)
718 return 0;
719 usleep_range(1000, 5000);
720 }
721 return ret ? ret : -ETIMEDOUT;
722}
723
724/**
725 * s5k6aa_set_prev_config - write user preview register set
726 *
727 * Configure output resolution and color fromat, pixel clock
728 * frequency range, device frame rate type and frame period range.
729 */
730static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
731 struct s5k6aa_preset *preset)
732{
733 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
734 int idx = preset->index;
735 u16 frame_rate_q;
736 int ret;
737
738 if (s5k6aa->fiv->reg_fr_time >= S5K6AA_MAX_HIGHRES_FR_TIME)
739 frame_rate_q = FR_RATE_Q_BEST_FRRATE;
740 else
741 frame_rate_q = FR_RATE_Q_BEST_QUALITY;
742
743 ret = s5k6aa_set_output_framefmt(s5k6aa, preset);
744 if (!ret)
745 ret = s5k6aa_write(client, REG_P_MAX_OUT_RATE(idx),
746 s5k6aa->pclk_fmax);
747 if (!ret)
748 ret = s5k6aa_write(client, REG_P_MIN_OUT_RATE(idx),
749 s5k6aa->pclk_fmin);
750 if (!ret)
751 ret = s5k6aa_write(client, REG_P_CLK_INDEX(idx),
752 preset->clk_id);
753 if (!ret)
754 ret = s5k6aa_write(client, REG_P_FR_RATE_TYPE(idx),
755 FR_RATE_DYNAMIC);
756 if (!ret)
757 ret = s5k6aa_write(client, REG_P_FR_RATE_Q_TYPE(idx),
758 frame_rate_q);
759 if (!ret)
760 ret = s5k6aa_write(client, REG_P_MAX_FR_TIME(idx),
761 s5k6aa->fiv->reg_fr_time + 33);
762 if (!ret)
763 ret = s5k6aa_write(client, REG_P_MIN_FR_TIME(idx),
764 s5k6aa->fiv->reg_fr_time - 33);
765 if (!ret)
766 ret = s5k6aa_new_config_sync(client, 250, idx);
767 if (!ret)
768 ret = s5k6aa_preview_config_status(client);
769 if (!ret)
770 s5k6aa->apply_cfg = 0;
771
772 v4l2_dbg(1, debug, client, "Frame interval: %d +/- 3.3ms. (%d)\n",
773 s5k6aa->fiv->reg_fr_time, ret);
774 return ret;
775}
776
777/**
778 * s5k6aa_initialize_isp - basic ISP MCU initialization
779 *
780 * Configure AHB addresses for registers read/write; configure PLLs for
781 * required output pixel clock. The ISP power supply needs to be already
782 * enabled, with an optional H/W reset.
783 * Locking: called with s5k6aa.lock mutex held.
784 */
785static int s5k6aa_initialize_isp(struct v4l2_subdev *sd)
786{
787 struct i2c_client *client = v4l2_get_subdevdata(sd);
788 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
789 int ret;
790
791 s5k6aa->apply_crop = 1;
792 s5k6aa->apply_cfg = 1;
793 msleep(100);
794
795 ret = s5k6aa_set_ahb_address(client);
796 if (ret)
797 return ret;
798 ret = s5k6aa_configure_video_bus(s5k6aa, s5k6aa->bus_type,
799 s5k6aa->mipi_lanes);
800 if (ret)
801 return ret;
802 ret = s5k6aa_write_array(sd, s5k6aa_analog_config);
803 if (ret)
804 return ret;
805 msleep(20);
806
807 return s5k6aa_configure_pixel_clocks(s5k6aa);
808}
809
810static int s5k6aa_gpio_set_value(struct s5k6aa *priv, int id, u32 val)
811{
812 if (!gpio_is_valid(priv->gpio[id].gpio))
813 return 0;
814 gpio_set_value(priv->gpio[id].gpio, !!val);
815 return 1;
816}
817
818static int s5k6aa_gpio_assert(struct s5k6aa *priv, int id)
819{
820 return s5k6aa_gpio_set_value(priv, id, priv->gpio[id].level);
821}
822
823static int s5k6aa_gpio_deassert(struct s5k6aa *priv, int id)
824{
825 return s5k6aa_gpio_set_value(priv, id, !priv->gpio[id].level);
826}
827
828static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
829{
830 int ret;
831
832 ret = regulator_bulk_enable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
833 if (ret)
834 return ret;
835 if (s5k6aa_gpio_deassert(s5k6aa, STBY))
836 usleep_range(150, 200);
837
838 if (s5k6aa->s_power)
839 ret = s5k6aa->s_power(1);
840 usleep_range(4000, 4000);
841
842 if (s5k6aa_gpio_deassert(s5k6aa, RST))
843 msleep(20);
844
845 return ret;
846}
847
848static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
849{
850 int ret;
851
852 if (s5k6aa_gpio_assert(s5k6aa, RST))
853 usleep_range(100, 150);
854
855 if (s5k6aa->s_power) {
856 ret = s5k6aa->s_power(0);
857 if (ret)
858 return ret;
859 }
860 if (s5k6aa_gpio_assert(s5k6aa, STBY))
861 usleep_range(50, 100);
862 s5k6aa->streaming = 0;
863
864 return regulator_bulk_disable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
865}
866
867/*
868 * V4L2 subdev core and video operations
869 */
870static int s5k6aa_set_power(struct v4l2_subdev *sd, int on)
871{
872 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
873 int ret = 0;
874
875 mutex_lock(&s5k6aa->lock);
876
877 if (!on == s5k6aa->power) {
878 if (on) {
879 ret = __s5k6aa_power_on(s5k6aa);
880 if (!ret)
881 ret = s5k6aa_initialize_isp(sd);
882 } else {
883 ret = __s5k6aa_power_off(s5k6aa);
884 }
885
886 if (!ret)
887 s5k6aa->power += on ? 1 : -1;
888 }
889
890 mutex_unlock(&s5k6aa->lock);
891
892 if (!on || ret || s5k6aa->power != 1)
893 return ret;
894
895 return v4l2_ctrl_handler_setup(sd->ctrl_handler);
896}
897
898static int __s5k6aa_stream(struct s5k6aa *s5k6aa, int enable)
899{
900 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
901 int ret = 0;
902
903 ret = s5k6aa_write(client, REG_G_ENABLE_PREV, enable);
904 if (!ret)
905 ret = s5k6aa_write(client, REG_G_ENABLE_PREV_CHG, 1);
906 if (!ret)
907 s5k6aa->streaming = enable;
908
909 return ret;
910}
911
912static int s5k6aa_s_stream(struct v4l2_subdev *sd, int on)
913{
914 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
915 int ret = 0;
916
917 mutex_lock(&s5k6aa->lock);
918
919 if (s5k6aa->streaming == !on) {
920 if (!ret && s5k6aa->apply_cfg)
921 ret = s5k6aa_set_prev_config(s5k6aa, s5k6aa->preset);
922 if (s5k6aa->apply_crop)
923 ret = s5k6aa_set_input_params(s5k6aa);
924 if (!ret)
925 ret = __s5k6aa_stream(s5k6aa, !!on);
926 }
927 mutex_unlock(&s5k6aa->lock);
928
929 return ret;
930}
931
932static int s5k6aa_g_frame_interval(struct v4l2_subdev *sd,
933 struct v4l2_subdev_frame_interval *fi)
934{
935 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
936
937 mutex_lock(&s5k6aa->lock);
938 fi->interval = s5k6aa->fiv->interval;
939 mutex_unlock(&s5k6aa->lock);
940
941 return 0;
942}
943
944static int __s5k6aa_set_frame_interval(struct s5k6aa *s5k6aa,
945 struct v4l2_subdev_frame_interval *fi)
946{
947 struct v4l2_mbus_framefmt *mbus_fmt = &s5k6aa->preset->mbus_fmt;
948 const struct s5k6aa_interval *fiv = &s5k6aa_intervals[0];
949 unsigned int err, min_err = UINT_MAX;
950 unsigned int i, fr_time;
951
952 if (fi->interval.denominator == 0)
953 return -EINVAL;
954
955 fr_time = fi->interval.numerator * 10000 / fi->interval.denominator;
956
957 for (i = 0; i < ARRAY_SIZE(s5k6aa_intervals); i++) {
958 const struct s5k6aa_interval *iv = &s5k6aa_intervals[i];
959
960 if (mbus_fmt->width > iv->size.width ||
961 mbus_fmt->height > iv->size.height)
962 continue;
963
964 err = abs(iv->reg_fr_time - fr_time);
965 if (err < min_err) {
966 fiv = iv;
967 min_err = err;
968 }
969 }
970 s5k6aa->fiv = fiv;
971
972 v4l2_dbg(1, debug, &s5k6aa->sd, "Changed frame interval to %d us\n",
973 fiv->reg_fr_time * 100);
974 return 0;
975}
976
977static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd,
978 struct v4l2_subdev_frame_interval *fi)
979{
980 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
981 int ret;
982
983 v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
984 fi->interval.numerator, fi->interval.denominator);
985
986 mutex_lock(&s5k6aa->lock);
987 ret = __s5k6aa_set_frame_interval(s5k6aa, fi);
988 s5k6aa->apply_cfg = 1;
989
990 mutex_unlock(&s5k6aa->lock);
991 return ret;
992}
993
994/*
995 * V4L2 subdev pad level and video operations
996 */
997static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
998 struct v4l2_subdev_fh *fh,
999 struct v4l2_subdev_frame_interval_enum *fie)
1000{
1001 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1002 const struct s5k6aa_interval *fi;
1003 int ret = 0;
1004
1005 if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
1006 return -EINVAL;
1007
1008 v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
1009 S5K6AA_WIN_WIDTH_MAX, 1,
1010 &fie->height, S5K6AA_WIN_HEIGHT_MIN,
1011 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1012
1013 mutex_lock(&s5k6aa->lock);
1014 fi = &s5k6aa_intervals[fie->index];
1015 if (fie->width > fi->size.width || fie->height > fi->size.height)
1016 ret = -EINVAL;
1017 else
1018 fie->interval = fi->interval;
1019 mutex_unlock(&s5k6aa->lock);
1020
1021 return ret;
1022}
1023
1024static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd,
1025 struct v4l2_subdev_fh *fh,
1026 struct v4l2_subdev_mbus_code_enum *code)
1027{
1028 if (code->index >= ARRAY_SIZE(s5k6aa_formats))
1029 return -EINVAL;
1030
1031 code->code = s5k6aa_formats[code->index].code;
1032 return 0;
1033}
1034
1035static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd,
1036 struct v4l2_subdev_fh *fh,
1037 struct v4l2_subdev_frame_size_enum *fse)
1038{
1039 int i = ARRAY_SIZE(s5k6aa_formats);
1040
1041 if (fse->index > 0)
1042 return -EINVAL;
1043
1044 while (--i)
1045 if (fse->code == s5k6aa_formats[i].code)
1046 break;
1047
1048 fse->code = s5k6aa_formats[i].code;
1049 fse->min_width = S5K6AA_WIN_WIDTH_MIN;
1050 fse->max_width = S5K6AA_WIN_WIDTH_MAX;
1051 fse->max_height = S5K6AA_WIN_HEIGHT_MIN;
1052 fse->min_height = S5K6AA_WIN_HEIGHT_MAX;
1053
1054 return 0;
1055}
1056
1057static struct v4l2_rect *
1058__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh,
1059 enum v4l2_subdev_format_whence which)
1060{
1061 if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
1062 return &s5k6aa->ccd_rect;
1063 if (which == V4L2_SUBDEV_FORMAT_TRY)
1064 return v4l2_subdev_get_try_crop(fh, 0);
1065
1066 return NULL;
1067}
1068
1069static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
1070 struct v4l2_mbus_framefmt *mf)
1071{
1072 unsigned int index;
1073
1074 v4l_bound_align_image(&mf->width, S5K6AA_WIN_WIDTH_MIN,
1075 S5K6AA_WIN_WIDTH_MAX, 1,
1076 &mf->height, S5K6AA_WIN_HEIGHT_MIN,
1077 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1078
1079 if (mf->colorspace != V4L2_COLORSPACE_JPEG &&
1080 mf->colorspace != V4L2_COLORSPACE_REC709)
1081 mf->colorspace = V4L2_COLORSPACE_JPEG;
1082
1083 index = s5k6aa_get_pixfmt_index(s5k6aa, mf);
1084
1085 mf->colorspace = s5k6aa_formats[index].colorspace;
1086 mf->code = s5k6aa_formats[index].code;
1087 mf->field = V4L2_FIELD_NONE;
1088}
1089
1090static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1091 struct v4l2_subdev_format *fmt)
1092{
1093 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1094 struct v4l2_mbus_framefmt *mf;
1095
1096 memset(fmt->reserved, 0, sizeof(fmt->reserved));
1097
1098 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1099 mf = v4l2_subdev_get_try_format(fh, 0);
1100 fmt->format = *mf;
1101 return 0;
1102 }
1103
1104 mutex_lock(&s5k6aa->lock);
1105 fmt->format = s5k6aa->preset->mbus_fmt;
1106 mutex_unlock(&s5k6aa->lock);
1107
1108 return 0;
1109}
1110
1111static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1112 struct v4l2_subdev_format *fmt)
1113{
1114 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1115 struct s5k6aa_preset *preset = s5k6aa->preset;
1116 struct v4l2_mbus_framefmt *mf;
1117 struct v4l2_rect *crop;
1118 int ret = 0;
1119
1120 mutex_lock(&s5k6aa->lock);
1121 s5k6aa_try_format(s5k6aa, &fmt->format);
1122
1123 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1124 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1125 crop = v4l2_subdev_get_try_crop(fh, 0);
1126 } else {
1127 if (s5k6aa->streaming) {
1128 ret = -EBUSY;
1129 } else {
1130 mf = &preset->mbus_fmt;
1131 crop = &s5k6aa->ccd_rect;
1132 s5k6aa->apply_cfg = 1;
1133 }
1134 }
1135
1136 if (ret == 0) {
1137 struct v4l2_subdev_frame_interval fiv = {
1138 .interval = {0, 1}
1139 };
1140
1141 *mf = fmt->format;
1142 /*
1143 * Make sure the crop window is valid, i.e. its size is
1144 * greater than the output window, as the ISP supports
1145 * only down-scaling.
1146 */
1147 crop->width = clamp_t(unsigned int, crop->width, mf->width,
1148 S5K6AA_WIN_WIDTH_MAX);
1149 crop->height = clamp_t(unsigned int, crop->height, mf->height,
1150 S5K6AA_WIN_HEIGHT_MAX);
1151 crop->left = clamp_t(unsigned int, crop->left, 0,
1152 S5K6AA_WIN_WIDTH_MAX - crop->width);
1153 crop->top = clamp_t(unsigned int, crop->top, 0,
1154 S5K6AA_WIN_HEIGHT_MAX - crop->height);
1155
1156 /* Reset to minimum possible frame interval */
1157 ret = __s5k6aa_set_frame_interval(s5k6aa, &fiv);
1158 }
1159 mutex_unlock(&s5k6aa->lock);
1160
1161 return ret;
1162}
1163
1164static int s5k6aa_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1165 struct v4l2_subdev_crop *crop)
1166{
1167 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1168 struct v4l2_rect *rect;
1169
1170 memset(crop->reserved, 0, sizeof(crop->reserved));
1171 mutex_lock(&s5k6aa->lock);
1172
1173 rect = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
1174 if (rect)
1175 crop->rect = *rect;
1176
1177 mutex_unlock(&s5k6aa->lock);
1178
1179 v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
1180 rect->left, rect->top, rect->width, rect->height);
1181
1182 return 0;
1183}
1184
1185static int s5k6aa_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1186 struct v4l2_subdev_crop *crop)
1187{
1188 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1189 struct v4l2_mbus_framefmt *mf;
1190 unsigned int max_x, max_y;
1191 struct v4l2_rect *crop_r;
1192
1193 mutex_lock(&s5k6aa->lock);
1194 crop_r = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
1195
1196 if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1197 mf = &s5k6aa->preset->mbus_fmt;
1198 s5k6aa->apply_crop = 1;
1199 } else {
1200 mf = v4l2_subdev_get_try_format(fh, 0);
1201 }
1202 v4l_bound_align_image(&crop->rect.width, mf->width,
1203 S5K6AA_WIN_WIDTH_MAX, 1,
1204 &crop->rect.height, mf->height,
1205 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1206
1207 max_x = (S5K6AA_WIN_WIDTH_MAX - crop->rect.width) & ~1;
1208 max_y = (S5K6AA_WIN_HEIGHT_MAX - crop->rect.height) & ~1;
1209
1210 crop->rect.left = clamp_t(unsigned int, crop->rect.left, 0, max_x);
1211 crop->rect.top = clamp_t(unsigned int, crop->rect.top, 0, max_y);
1212
1213 *crop_r = crop->rect;
1214
1215 mutex_unlock(&s5k6aa->lock);
1216
1217 v4l2_dbg(1, debug, sd, "Set crop rectangle: (%d,%d)/%dx%d\n",
1218 crop_r->left, crop_r->top, crop_r->width, crop_r->height);
1219
1220 return 0;
1221}
1222
1223static const struct v4l2_subdev_pad_ops s5k6aa_pad_ops = {
1224 .enum_mbus_code = s5k6aa_enum_mbus_code,
1225 .enum_frame_size = s5k6aa_enum_frame_size,
1226 .enum_frame_interval = s5k6aa_enum_frame_interval,
1227 .get_fmt = s5k6aa_get_fmt,
1228 .set_fmt = s5k6aa_set_fmt,
1229 .get_crop = s5k6aa_get_crop,
1230 .set_crop = s5k6aa_set_crop,
1231};
1232
1233static const struct v4l2_subdev_video_ops s5k6aa_video_ops = {
1234 .g_frame_interval = s5k6aa_g_frame_interval,
1235 .s_frame_interval = s5k6aa_s_frame_interval,
1236 .s_stream = s5k6aa_s_stream,
1237};
1238
1239/*
1240 * V4L2 subdev controls
1241 */
1242
1243static int s5k6aa_s_ctrl(struct v4l2_ctrl *ctrl)
1244{
1245 struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1246 struct i2c_client *client = v4l2_get_subdevdata(sd);
1247 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1248 int idx, err = 0;
1249
1250 v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
1251
1252 mutex_lock(&s5k6aa->lock);
1253 /*
1254 * If the device is not powered up by the host driver do
1255 * not apply any controls to H/W at this time. Instead
1256 * the controls will be restored right after power-up.
1257 */
1258 if (s5k6aa->power == 0)
1259 goto unlock;
1260 idx = s5k6aa->preset->index;
1261
1262 switch (ctrl->id) {
1263 case V4L2_CID_AUTO_WHITE_BALANCE:
1264 err = s5k6aa_set_awb(s5k6aa, ctrl->val);
1265 break;
1266
1267 case V4L2_CID_BRIGHTNESS:
1268 err = s5k6aa_write(client, REG_USER_BRIGHTNESS, ctrl->val);
1269 break;
1270
1271 case V4L2_CID_COLORFX:
1272 err = s5k6aa_set_colorfx(s5k6aa, ctrl->val);
1273 break;
1274
1275 case V4L2_CID_CONTRAST:
1276 err = s5k6aa_write(client, REG_USER_CONTRAST, ctrl->val);
1277 break;
1278
1279 case V4L2_CID_EXPOSURE_AUTO:
1280 err = s5k6aa_set_auto_exposure(s5k6aa, ctrl->val);
1281 break;
1282
1283 case V4L2_CID_HFLIP:
1284 err = s5k6aa_set_mirror(s5k6aa, ctrl->val);
1285 if (err)
1286 break;
1287 err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1288 break;
1289
1290 case V4L2_CID_POWER_LINE_FREQUENCY:
1291 err = s5k6aa_set_anti_flicker(s5k6aa, ctrl->val);
1292 break;
1293
1294 case V4L2_CID_SATURATION:
1295 err = s5k6aa_write(client, REG_USER_SATURATION, ctrl->val);
1296 break;
1297
1298 case V4L2_CID_SHARPNESS:
1299 err = s5k6aa_write(client, REG_USER_SHARPBLUR, ctrl->val);
1300 break;
1301
1302 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
1303 err = s5k6aa_write(client, REG_P_COLORTEMP(idx), ctrl->val);
1304 if (err)
1305 break;
1306 err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1307 break;
1308 }
1309unlock:
1310 mutex_unlock(&s5k6aa->lock);
1311 return err;
1312}
1313
1314static const struct v4l2_ctrl_ops s5k6aa_ctrl_ops = {
1315 .s_ctrl = s5k6aa_s_ctrl,
1316};
1317
1318static int s5k6aa_log_status(struct v4l2_subdev *sd)
1319{
1320 v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
1321 return 0;
1322}
1323
1324#define V4L2_CID_RED_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1001)
1325#define V4L2_CID_GREEN_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1002)
1326#define V4L2_CID_BLUE_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1003)
1327
1328static const struct v4l2_ctrl_config s5k6aa_ctrls[] = {
1329 {
1330 .ops = &s5k6aa_ctrl_ops,
1331 .id = V4L2_CID_RED_GAIN,
1332 .type = V4L2_CTRL_TYPE_INTEGER,
1333 .name = "Gain, Red",
1334 .min = 0,
1335 .max = 256,
1336 .def = 127,
1337 .step = 1,
1338 }, {
1339 .ops = &s5k6aa_ctrl_ops,
1340 .id = V4L2_CID_GREEN_GAIN,
1341 .type = V4L2_CTRL_TYPE_INTEGER,
1342 .name = "Gain, Green",
1343 .min = 0,
1344 .max = 256,
1345 .def = 127,
1346 .step = 1,
1347 }, {
1348 .ops = &s5k6aa_ctrl_ops,
1349 .id = V4L2_CID_BLUE_GAIN,
1350 .type = V4L2_CTRL_TYPE_INTEGER,
1351 .name = "Gain, Blue",
1352 .min = 0,
1353 .max = 256,
1354 .def = 127,
1355 .step = 1,
1356 },
1357};
1358
1359static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa)
1360{
1361 const struct v4l2_ctrl_ops *ops = &s5k6aa_ctrl_ops;
1362 struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
1363 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1364
1365 int ret = v4l2_ctrl_handler_init(hdl, 16);
1366 if (ret)
1367 return ret;
1368 /* Auto white balance cluster */
1369 ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
1370 0, 1, 1, 1);
1371 ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[0], NULL);
1372 ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[1], NULL);
1373 ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[2], NULL);
1374 v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
1375
1376 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1377 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1378 v4l2_ctrl_cluster(2, &ctrls->hflip);
1379
1380 ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
1381 V4L2_CID_EXPOSURE_AUTO,
1382 V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
1383 /* Exposure time: x 1 us */
1384 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
1385 0, 6000000U, 1, 100000U);
1386 /* Total gain: 256 <=> 1x */
1387 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
1388 0, 256, 1, 256);
1389 v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
1390
1391 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
1392 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
1393 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
1394
1395 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
1396 V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
1397
1398 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
1399 0, 256, 1, 0);
1400
1401 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
1402 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
1403 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
1404 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
1405
1406 if (hdl->error) {
1407 ret = hdl->error;
1408 v4l2_ctrl_handler_free(hdl);
1409 return ret;
1410 }
1411
1412 s5k6aa->sd.ctrl_handler = hdl;
1413 return 0;
1414}
1415
1416/*
1417 * V4L2 subdev internal operations
1418 */
1419static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1420{
1421 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
1422 struct v4l2_rect *crop = v4l2_subdev_get_try_crop(fh, 0);
1423
1424 format->colorspace = s5k6aa_formats[0].colorspace;
1425 format->code = s5k6aa_formats[0].code;
1426 format->width = S5K6AA_OUT_WIDTH_DEF;
1427 format->height = S5K6AA_OUT_HEIGHT_DEF;
1428 format->field = V4L2_FIELD_NONE;
1429
1430 crop->width = S5K6AA_WIN_WIDTH_MAX;
1431 crop->height = S5K6AA_WIN_HEIGHT_MAX;
1432 crop->left = 0;
1433 crop->top = 0;
1434
1435 return 0;
1436}
1437
1438int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
1439{
1440 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
1441 u16 api_ver = 0, fw_rev = 0;
1442
1443 int ret = s5k6aa_set_ahb_address(client);
1444
1445 if (!ret)
1446 ret = s5k6aa_read(client, REG_FW_APIVER, &api_ver);
1447 if (!ret)
1448 ret = s5k6aa_read(client, REG_FW_REVISION, &fw_rev);
1449 if (ret) {
1450 v4l2_err(&s5k6aa->sd, "FW revision check failed!\n");
1451 return ret;
1452 }
1453
1454 v4l2_info(&s5k6aa->sd, "FW API ver.: 0x%X, FW rev.: 0x%X\n",
1455 api_ver, fw_rev);
1456
1457 return api_ver == S5K6AAFX_FW_APIVER ? 0 : -ENODEV;
1458}
1459
1460static int s5k6aa_registered(struct v4l2_subdev *sd)
1461{
1462 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1463 int ret;
1464
1465 mutex_lock(&s5k6aa->lock);
1466 ret = __s5k6aa_power_on(s5k6aa);
1467 if (!ret) {
1468 msleep(100);
1469 ret = s5k6aa_check_fw_revision(s5k6aa);
1470 __s5k6aa_power_off(s5k6aa);
1471 }
1472 mutex_unlock(&s5k6aa->lock);
1473
1474 return ret;
1475}
1476
1477static const struct v4l2_subdev_internal_ops s5k6aa_subdev_internal_ops = {
1478 .registered = s5k6aa_registered,
1479 .open = s5k6aa_open,
1480};
1481
1482static const struct v4l2_subdev_core_ops s5k6aa_core_ops = {
1483 .s_power = s5k6aa_set_power,
1484 .log_status = s5k6aa_log_status,
1485};
1486
1487static const struct v4l2_subdev_ops s5k6aa_subdev_ops = {
1488 .core = &s5k6aa_core_ops,
1489 .pad = &s5k6aa_pad_ops,
1490 .video = &s5k6aa_video_ops,
1491};
1492
1493/*
1494 * GPIO setup
1495 */
1496static int s5k6aa_configure_gpio(int nr, int val, const char *name)
1497{
1498 unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
1499 int ret;
1500
1501 if (!gpio_is_valid(nr))
1502 return 0;
1503 ret = gpio_request_one(nr, flags, name);
1504 if (!ret)
1505 gpio_export(nr, 0);
1506 return ret;
1507}
1508
1509static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
1510{
1511 int i;
1512
1513 for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
1514 if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
1515 continue;
1516 gpio_free(s5k6aa->gpio[i].gpio);
1517 s5k6aa->gpio[i].gpio = -EINVAL;
1518 }
1519}
1520
1521static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
1522 const struct s5k6aa_platform_data *pdata)
1523{
1524 const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
1525 int ret;
1526
1527 s5k6aa->gpio[STBY].gpio = -EINVAL;
1528 s5k6aa->gpio[RST].gpio = -EINVAL;
1529
1530 ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
1531 if (ret) {
1532 s5k6aa_free_gpios(s5k6aa);
1533 return ret;
1534 }
1535 s5k6aa->gpio[STBY] = *gpio;
1536 if (gpio_is_valid(gpio->gpio))
1537 gpio_set_value(gpio->gpio, 0);
1538
1539 gpio = &pdata->gpio_reset;
1540 ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
1541 if (ret) {
1542 s5k6aa_free_gpios(s5k6aa);
1543 return ret;
1544 }
1545 s5k6aa->gpio[RST] = *gpio;
1546 if (gpio_is_valid(gpio->gpio))
1547 gpio_set_value(gpio->gpio, 0);
1548
1549 return 0;
1550}
1551
1552static int s5k6aa_probe(struct i2c_client *client,
1553 const struct i2c_device_id *id)
1554{
1555 const struct s5k6aa_platform_data *pdata = client->dev.platform_data;
1556 struct v4l2_subdev *sd;
1557 struct s5k6aa *s5k6aa;
1558 int i, ret;
1559
1560 if (pdata == NULL) {
1561 dev_err(&client->dev, "Platform data not specified\n");
1562 return -EINVAL;
1563 }
1564
1565 if (pdata->mclk_frequency == 0) {
1566 dev_err(&client->dev, "MCLK frequency not specified\n");
1567 return -EINVAL;
1568 }
1569
1570 s5k6aa = kzalloc(sizeof(*s5k6aa), GFP_KERNEL);
1571 if (!s5k6aa)
1572 return -ENOMEM;
1573
1574 mutex_init(&s5k6aa->lock);
1575
1576 s5k6aa->mclk_frequency = pdata->mclk_frequency;
1577 s5k6aa->bus_type = pdata->bus_type;
1578 s5k6aa->mipi_lanes = pdata->nlanes;
1579 s5k6aa->s_power = pdata->set_power;
1580 s5k6aa->inv_hflip = pdata->horiz_flip;
1581 s5k6aa->inv_vflip = pdata->vert_flip;
1582
1583 sd = &s5k6aa->sd;
1584 strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
1585 v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
1586
1587 sd->internal_ops = &s5k6aa_subdev_internal_ops;
1588 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1589
1590 s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
1591 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
1592 ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
1593 if (ret)
1594 goto out_err1;
1595
1596 ret = s5k6aa_configure_gpios(s5k6aa, pdata);
1597 if (ret)
1598 goto out_err2;
1599
1600 for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
1601 s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
1602
1603 ret = regulator_bulk_get(&client->dev, S5K6AA_NUM_SUPPLIES,
1604 s5k6aa->supplies);
1605 if (ret) {
1606 dev_err(&client->dev, "Failed to get regulators\n");
1607 goto out_err3;
1608 }
1609
1610 ret = s5k6aa_initialize_ctrls(s5k6aa);
1611 if (ret)
1612 goto out_err4;
1613
1614 s5k6aa_presets_data_init(s5k6aa);
1615
1616 s5k6aa->ccd_rect.width = S5K6AA_WIN_WIDTH_MAX;
1617 s5k6aa->ccd_rect.height = S5K6AA_WIN_HEIGHT_MAX;
1618 s5k6aa->ccd_rect.left = 0;
1619 s5k6aa->ccd_rect.top = 0;
1620
1621 return 0;
1622
1623out_err4:
1624 regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
1625out_err3:
1626 s5k6aa_free_gpios(s5k6aa);
1627out_err2:
1628 media_entity_cleanup(&s5k6aa->sd.entity);
1629out_err1:
1630 kfree(s5k6aa);
1631 return ret;
1632}
1633
1634static int s5k6aa_remove(struct i2c_client *client)
1635{
1636 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1637 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1638
1639 v4l2_device_unregister_subdev(sd);
1640 v4l2_ctrl_handler_free(sd->ctrl_handler);
1641 media_entity_cleanup(&sd->entity);
1642 regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
1643 s5k6aa_free_gpios(s5k6aa);
1644 kfree(s5k6aa);
1645
1646 return 0;
1647}
1648
1649static const struct i2c_device_id s5k6aa_id[] = {
1650 { DRIVER_NAME, 0 },
1651 { },
1652};
1653MODULE_DEVICE_TABLE(i2c, s5k6aa_id);
1654
1655
1656static struct i2c_driver s5k6aa_i2c_driver = {
1657 .driver = {
1658 .name = DRIVER_NAME
1659 },
1660 .probe = s5k6aa_probe,
1661 .remove = s5k6aa_remove,
1662 .id_table = s5k6aa_id,
1663};
1664
1665static int __init s5k6aa_init(void)
1666{
1667 return i2c_add_driver(&s5k6aa_i2c_driver);
1668}
1669
1670static void __exit s5k6aa_exit(void)
1671{
1672 i2c_del_driver(&s5k6aa_i2c_driver);
1673}
1674
1675module_init(s5k6aa_init);
1676module_exit(s5k6aa_exit);
1677
1678MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
1679MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1680MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 931f469604b0..c8d91b0cd9bd 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -246,9 +246,9 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
246 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; 246 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
247} 247}
248 248
249static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, 249static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
250 unsigned int *num_planes, unsigned int sizes[], 250 unsigned int *num_buffers, unsigned int *num_planes,
251 void *allocators[]) 251 unsigned int sizes[], void *allocators[])
252{ 252{
253 struct fimc_ctx *ctx = vq->drv_priv; 253 struct fimc_ctx *ctx = vq->drv_priv;
254 struct fimc_fmt *fmt = ctx->d_frame.fmt; 254 struct fimc_fmt *fmt = ctx->d_frame.fmt;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 6c1c9cb55378..19ca6db38b2f 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -670,9 +670,9 @@ static void fimc_job_abort(void *priv)
670 fimc_m2m_shutdown(priv); 670 fimc_m2m_shutdown(priv);
671} 671}
672 672
673static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, 673static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
674 unsigned int *num_planes, unsigned int sizes[], 674 unsigned int *num_buffers, unsigned int *num_planes,
675 void *allocators[]) 675 unsigned int sizes[], void *allocators[])
676{ 676{
677 struct fimc_ctx *ctx = vb2_get_drv_priv(vq); 677 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
678 struct fimc_frame *f; 678 struct fimc_frame *f;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
index 5f4da80051bb..f2481a85e0a2 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
@@ -38,7 +38,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
38 * into kernel. */ 38 * into kernel. */
39 mfc_debug_enter(); 39 mfc_debug_enter();
40 err = request_firmware((const struct firmware **)&fw_blob, 40 err = request_firmware((const struct firmware **)&fw_blob,
41 "s5pc110-mfc.fw", dev->v4l2_dev.dev); 41 "s5p-mfc.fw", dev->v4l2_dev.dev);
42 if (err != 0) { 42 if (err != 0) {
43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
44 return -EINVAL; 44 return -EINVAL;
@@ -116,7 +116,7 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
116 * into kernel. */ 116 * into kernel. */
117 mfc_debug_enter(); 117 mfc_debug_enter();
118 err = request_firmware((const struct firmware **)&fw_blob, 118 err = request_firmware((const struct firmware **)&fw_blob,
119 "s5pc110-mfc.fw", dev->v4l2_dev.dev); 119 "s5p-mfc.fw", dev->v4l2_dev.dev);
120 if (err != 0) { 120 if (err != 0) {
121 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 121 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
122 return -EINVAL; 122 return -EINVAL;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index bfbe08432050..725634d9736d 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -744,9 +744,10 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
744 .vidioc_g_crop = vidioc_g_crop, 744 .vidioc_g_crop = vidioc_g_crop,
745}; 745};
746 746
747static int s5p_mfc_queue_setup(struct vb2_queue *vq, unsigned int *buf_count, 747static int s5p_mfc_queue_setup(struct vb2_queue *vq,
748 unsigned int *plane_count, unsigned int psize[], 748 const struct v4l2_format *fmt, unsigned int *buf_count,
749 void *allocators[]) 749 unsigned int *plane_count, unsigned int psize[],
750 void *allocators[])
750{ 751{
751 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 752 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
752 753
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index 4c90e53bd964..ecef127dbc66 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1513,8 +1513,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
1513} 1513}
1514 1514
1515static int s5p_mfc_queue_setup(struct vb2_queue *vq, 1515static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1516 unsigned int *buf_count, unsigned int *plane_count, 1516 const struct v4l2_format *fmt,
1517 unsigned int psize[], void *allocators[]) 1517 unsigned int *buf_count, unsigned int *plane_count,
1518 unsigned int psize[], void *allocators[])
1518{ 1519{
1519 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 1520 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1520 1521
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
index 4917e2c2b321..e16d3a4bc1dc 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -727,8 +727,8 @@ static const struct v4l2_file_operations mxr_fops = {
727 .unlocked_ioctl = video_ioctl2, 727 .unlocked_ioctl = video_ioctl2,
728}; 728};
729 729
730static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 730static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
731 unsigned int *nplanes, unsigned int sizes[], 731 unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
732 void *alloc_ctxs[]) 732 void *alloc_ctxs[])
733{ 733{
734 struct mxr_layer *layer = vb2_get_drv_priv(vq); 734 struct mxr_layer *layer = vb2_get_drv_priv(vq);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index bc8d6bba8ee5..9b550687213a 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -843,10 +843,10 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
843int saa7134_ir_start(struct saa7134_dev *dev); 843int saa7134_ir_start(struct saa7134_dev *dev);
844void saa7134_ir_stop(struct saa7134_dev *dev); 844void saa7134_ir_stop(struct saa7134_dev *dev);
845#else 845#else
846#define saa7134_input_init1(dev) (0) 846#define saa7134_input_init1(dev) ((void)0)
847#define saa7134_input_fini(dev) (0) 847#define saa7134_input_fini(dev) ((void)0)
848#define saa7134_input_irq(dev) (0) 848#define saa7134_input_irq(dev) ((void)0)
849#define saa7134_probe_i2c_ir(dev) (0) 849#define saa7134_probe_i2c_ir(dev) ((void)0)
850#define saa7134_ir_start(dev) (0) 850#define saa7134_ir_start(dev) ((void)0)
851#define saa7134_ir_stop(dev) (0) 851#define saa7134_ir_stop(dev) ((void)0)
852#endif 852#endif
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 8615fb81775f..f390682629cf 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -90,7 +90,6 @@
90struct sh_mobile_ceu_buffer { 90struct sh_mobile_ceu_buffer {
91 struct vb2_buffer vb; /* v4l buffer must be first */ 91 struct vb2_buffer vb; /* v4l buffer must be first */
92 struct list_head queue; 92 struct list_head queue;
93 enum v4l2_mbus_pixelcode code;
94}; 93};
95 94
96struct sh_mobile_ceu_dev { 95struct sh_mobile_ceu_dev {
@@ -100,7 +99,8 @@ struct sh_mobile_ceu_dev {
100 99
101 unsigned int irq; 100 unsigned int irq;
102 void __iomem *base; 101 void __iomem *base;
103 unsigned long video_limit; 102 size_t video_limit;
103 size_t buf_total;
104 104
105 spinlock_t lock; /* Protects video buffer lists */ 105 spinlock_t lock; /* Protects video buffer lists */
106 struct list_head capture; 106 struct list_head capture;
@@ -121,7 +121,7 @@ struct sh_mobile_ceu_dev {
121}; 121};
122 122
123struct sh_mobile_ceu_cam { 123struct sh_mobile_ceu_cam {
124 /* CEU offsets within scaled by the CEU camera output */ 124 /* CEU offsets within the camera output, before the CEU scaler */
125 unsigned int ceu_left; 125 unsigned int ceu_left;
126 unsigned int ceu_top; 126 unsigned int ceu_top;
127 /* Client output, as seen by the CEU */ 127 /* Client output, as seen by the CEU */
@@ -144,30 +144,6 @@ static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
144 return container_of(vb, struct sh_mobile_ceu_buffer, vb); 144 return container_of(vb, struct sh_mobile_ceu_buffer, vb);
145} 145}
146 146
147static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
148{
149 unsigned long flags;
150
151 flags = SOCAM_MASTER |
152 SOCAM_PCLK_SAMPLE_RISING |
153 SOCAM_HSYNC_ACTIVE_HIGH |
154 SOCAM_HSYNC_ACTIVE_LOW |
155 SOCAM_VSYNC_ACTIVE_HIGH |
156 SOCAM_VSYNC_ACTIVE_LOW |
157 SOCAM_DATA_ACTIVE_HIGH;
158
159 if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
160 flags |= SOCAM_DATAWIDTH_8;
161
162 if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
163 flags |= SOCAM_DATAWIDTH_16;
164
165 if (flags & SOCAM_DATAWIDTH_MASK)
166 return flags;
167
168 return 0;
169}
170
171static void ceu_write(struct sh_mobile_ceu_dev *priv, 147static void ceu_write(struct sh_mobile_ceu_dev *priv,
172 unsigned long reg_offs, u32 data) 148 unsigned long reg_offs, u32 data)
173{ 149{
@@ -216,33 +192,61 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
216/* 192/*
217 * Videobuf operations 193 * Videobuf operations
218 */ 194 */
195
196/*
197 * .queue_setup() is called to check, whether the driver can accept the
198 * requested number of buffers and to fill in plane sizes
199 * for the current frame format if required
200 */
219static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq, 201static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
202 const struct v4l2_format *fmt,
220 unsigned int *count, unsigned int *num_planes, 203 unsigned int *count, unsigned int *num_planes,
221 unsigned int sizes[], void *alloc_ctxs[]) 204 unsigned int sizes[], void *alloc_ctxs[])
222{ 205{
223 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq); 206 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
224 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 207 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
225 struct sh_mobile_ceu_dev *pcdev = ici->priv; 208 struct sh_mobile_ceu_dev *pcdev = ici->priv;
226 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 209 int bytes_per_line;
227 icd->current_fmt->host_fmt); 210 unsigned int height;
228 211
212 if (fmt) {
213 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
214 fmt->fmt.pix.pixelformat);
215 if (!xlate)
216 return -EINVAL;
217 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
218 xlate->host_fmt);
219 height = fmt->fmt.pix.height;
220 } else {
221 /* Called from VIDIOC_REQBUFS or in compatibility mode */
222 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
223 icd->current_fmt->host_fmt);
224 height = icd->user_height;
225 }
229 if (bytes_per_line < 0) 226 if (bytes_per_line < 0)
230 return bytes_per_line; 227 return bytes_per_line;
231 228
232 *num_planes = 1; 229 sizes[0] = bytes_per_line * height;
233 230
234 pcdev->sequence = 0;
235 sizes[0] = bytes_per_line * icd->user_height;
236 alloc_ctxs[0] = pcdev->alloc_ctx; 231 alloc_ctxs[0] = pcdev->alloc_ctx;
237 232
233 if (!vq->num_buffers)
234 pcdev->sequence = 0;
235
238 if (!*count) 236 if (!*count)
239 *count = 2; 237 *count = 2;
240 238
241 if (pcdev->video_limit) { 239 /* If *num_planes != 0, we have already verified *count. */
242 if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit) 240 if (pcdev->video_limit && !*num_planes) {
243 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]); 241 size_t size = PAGE_ALIGN(sizes[0]) * *count;
242
243 if (size + pcdev->buf_total > pcdev->video_limit)
244 *count = (pcdev->video_limit - pcdev->buf_total) /
245 PAGE_ALIGN(sizes[0]);
244 } 246 }
245 247
248 *num_planes = 1;
249
246 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]); 250 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
247 251
248 return 0; 252 return 0;
@@ -267,6 +271,7 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
267 unsigned long top1, top2; 271 unsigned long top1, top2;
268 unsigned long bottom1, bottom2; 272 unsigned long bottom1, bottom2;
269 u32 status; 273 u32 status;
274 bool planar;
270 int ret = 0; 275 int ret = 0;
271 276
272 /* 277 /*
@@ -314,17 +319,29 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
314 319
315 phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0); 320 phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
316 321
317 ceu_write(pcdev, top1, phys_addr_top);
318 if (V4L2_FIELD_NONE != pcdev->field) {
319 phys_addr_bottom = phys_addr_top + icd->user_width;
320 ceu_write(pcdev, bottom1, phys_addr_bottom);
321 }
322
323 switch (icd->current_fmt->host_fmt->fourcc) { 322 switch (icd->current_fmt->host_fmt->fourcc) {
324 case V4L2_PIX_FMT_NV12: 323 case V4L2_PIX_FMT_NV12:
325 case V4L2_PIX_FMT_NV21: 324 case V4L2_PIX_FMT_NV21:
326 case V4L2_PIX_FMT_NV16: 325 case V4L2_PIX_FMT_NV16:
327 case V4L2_PIX_FMT_NV61: 326 case V4L2_PIX_FMT_NV61:
327 planar = true;
328 break;
329 default:
330 planar = false;
331 }
332
333 ceu_write(pcdev, top1, phys_addr_top);
334 if (V4L2_FIELD_NONE != pcdev->field) {
335 if (planar)
336 phys_addr_bottom = phys_addr_top + icd->user_width;
337 else
338 phys_addr_bottom = phys_addr_top +
339 soc_mbus_bytes_per_line(icd->user_width,
340 icd->current_fmt->host_fmt);
341 ceu_write(pcdev, bottom1, phys_addr_bottom);
342 }
343
344 if (planar) {
328 phys_addr_top += icd->user_width * 345 phys_addr_top += icd->user_width *
329 icd->user_height; 346 icd->user_height;
330 ceu_write(pcdev, top2, phys_addr_top); 347 ceu_write(pcdev, top2, phys_addr_top);
@@ -341,23 +358,40 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
341 358
342static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb) 359static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
343{ 360{
361 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
362
363 /* Added list head initialization on alloc */
364 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
365
366 return 0;
367}
368
369static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
370{
344 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq); 371 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
345 struct sh_mobile_ceu_buffer *buf; 372 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
373 struct sh_mobile_ceu_dev *pcdev = ici->priv;
374 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
375 unsigned long size;
346 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 376 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
347 icd->current_fmt->host_fmt); 377 icd->current_fmt->host_fmt);
348 unsigned long size;
349 378
350 if (bytes_per_line < 0) 379 if (bytes_per_line < 0)
351 return bytes_per_line; 380 goto error;
352 381
353 buf = to_ceu_vb(vb); 382 size = icd->user_height * bytes_per_line;
383
384 if (vb2_plane_size(vb, 0) < size) {
385 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
386 vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
387 goto error;
388 }
389
390 vb2_set_plane_payload(vb, 0, size);
354 391
355 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 392 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
356 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 393 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
357 394
358 /* Added list head initialization on alloc */
359 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
360
361#ifdef DEBUG 395#ifdef DEBUG
362 /* 396 /*
363 * This can be useful if you want to see if we actually fill 397 * This can be useful if you want to see if we actually fill
@@ -367,31 +401,6 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
367 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0)); 401 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
368#endif 402#endif
369 403
370 BUG_ON(NULL == icd->current_fmt);
371
372 size = icd->user_height * bytes_per_line;
373
374 if (vb2_plane_size(vb, 0) < size) {
375 dev_err(icd->parent, "Buffer too small (%lu < %lu)\n",
376 vb2_plane_size(vb, 0), size);
377 return -ENOBUFS;
378 }
379
380 vb2_set_plane_payload(vb, 0, size);
381
382 return 0;
383}
384
385static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
386{
387 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
388 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
389 struct sh_mobile_ceu_dev *pcdev = ici->priv;
390 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
391
392 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
393 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
394
395 spin_lock_irq(&pcdev->lock); 404 spin_lock_irq(&pcdev->lock);
396 list_add_tail(&buf->queue, &pcdev->capture); 405 list_add_tail(&buf->queue, &pcdev->capture);
397 406
@@ -405,6 +414,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
405 sh_mobile_ceu_capture(pcdev); 414 sh_mobile_ceu_capture(pcdev);
406 } 415 }
407 spin_unlock_irq(&pcdev->lock); 416 spin_unlock_irq(&pcdev->lock);
417
418 return;
419
420error:
421 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
408} 422}
409 423
410static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) 424static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -429,11 +443,23 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
429 if (buf->queue.next) 443 if (buf->queue.next)
430 list_del_init(&buf->queue); 444 list_del_init(&buf->queue);
431 445
446 pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
447 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
448 pcdev->buf_total);
449
432 spin_unlock_irq(&pcdev->lock); 450 spin_unlock_irq(&pcdev->lock);
433} 451}
434 452
435static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) 453static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
436{ 454{
455 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
456 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
457 struct sh_mobile_ceu_dev *pcdev = ici->priv;
458
459 pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
460 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
461 pcdev->buf_total);
462
437 /* This is for locking debugging only */ 463 /* This is for locking debugging only */
438 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue); 464 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
439 return 0; 465 return 0;
@@ -535,19 +561,29 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
535 561
536 pm_runtime_get_sync(ici->v4l2_dev.dev); 562 pm_runtime_get_sync(ici->v4l2_dev.dev);
537 563
564 pcdev->buf_total = 0;
565
538 ret = sh_mobile_ceu_soft_reset(pcdev); 566 ret = sh_mobile_ceu_soft_reset(pcdev);
539 567
540 csi2_sd = find_csi2(pcdev); 568 csi2_sd = find_csi2(pcdev);
569 if (csi2_sd)
570 csi2_sd->grp_id = (long)icd;
541 571
542 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); 572 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
543 if (ret != -ENODEV && ret != -ENOIOCTLCMD && ret < 0) { 573 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
544 pm_runtime_put_sync(ici->v4l2_dev.dev); 574 pm_runtime_put_sync(ici->v4l2_dev.dev);
545 } else { 575 return ret;
546 pcdev->icd = icd;
547 ret = 0;
548 } 576 }
549 577
550 return ret; 578 /*
579 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
580 * has not found this soc-camera device among its clients
581 */
582 if (ret == -ENODEV && csi2_sd)
583 csi2_sd->grp_id = 0;
584 pcdev->icd = icd;
585
586 return 0;
551} 587}
552 588
553/* Called with .video_lock held */ 589/* Called with .video_lock held */
@@ -560,6 +596,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
560 BUG_ON(icd != pcdev->icd); 596 BUG_ON(icd != pcdev->icd);
561 597
562 v4l2_subdev_call(csi2_sd, core, s_power, 0); 598 v4l2_subdev_call(csi2_sd, core, s_power, 0);
599 if (csi2_sd)
600 csi2_sd->grp_id = 0;
563 /* disable capture, disable interrupts */ 601 /* disable capture, disable interrupts */
564 ceu_write(pcdev, CEIER, 0); 602 ceu_write(pcdev, CEIER, 0);
565 sh_mobile_ceu_soft_reset(pcdev); 603 sh_mobile_ceu_soft_reset(pcdev);
@@ -628,22 +666,22 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
628 left_offset = cam->ceu_left; 666 left_offset = cam->ceu_left;
629 top_offset = cam->ceu_top; 667 top_offset = cam->ceu_top;
630 668
631 /* CEU cropping (CFSZR) is applied _after_ the scaling filter (CFLCR) */ 669 WARN_ON(icd->user_width & 3 || icd->user_height & 3);
670
671 width = icd->user_width;
672
632 if (pcdev->image_mode) { 673 if (pcdev->image_mode) {
633 in_width = cam->width; 674 in_width = cam->width;
634 if (!pcdev->is_16bit) { 675 if (!pcdev->is_16bit) {
635 in_width *= 2; 676 in_width *= 2;
636 left_offset *= 2; 677 left_offset *= 2;
637 } 678 }
638 width = icd->user_width; 679 cdwdr_width = width;
639 cdwdr_width = icd->user_width;
640 } else { 680 } else {
641 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 681 int bytes_per_line = soc_mbus_bytes_per_line(width,
642 icd->current_fmt->host_fmt); 682 icd->current_fmt->host_fmt);
643 unsigned int w_factor; 683 unsigned int w_factor;
644 684
645 width = icd->user_width;
646
647 switch (icd->current_fmt->host_fmt->packing) { 685 switch (icd->current_fmt->host_fmt->packing) {
648 case SOC_MBUS_PACKING_2X8_PADHI: 686 case SOC_MBUS_PACKING_2X8_PADHI:
649 w_factor = 2; 687 w_factor = 2;
@@ -653,10 +691,10 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
653 } 691 }
654 692
655 in_width = cam->width * w_factor; 693 in_width = cam->width * w_factor;
656 left_offset = left_offset * w_factor; 694 left_offset *= w_factor;
657 695
658 if (bytes_per_line < 0) 696 if (bytes_per_line < 0)
659 cdwdr_width = icd->user_width; 697 cdwdr_width = width;
660 else 698 else
661 cdwdr_width = bytes_per_line; 699 cdwdr_width = bytes_per_line;
662 } 700 }
@@ -664,7 +702,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
664 height = icd->user_height; 702 height = icd->user_height;
665 in_height = cam->height; 703 in_height = cam->height;
666 if (V4L2_FIELD_NONE != pcdev->field) { 704 if (V4L2_FIELD_NONE != pcdev->field) {
667 height /= 2; 705 height = (height / 2) & ~3;
668 in_height /= 2; 706 in_height /= 2;
669 top_offset /= 2; 707 top_offset /= 2;
670 cdwdr_width *= 2; 708 cdwdr_width *= 2;
@@ -686,6 +724,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
686 724
687 ceu_write(pcdev, CAMOR, camor); 725 ceu_write(pcdev, CAMOR, camor);
688 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width); 726 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
727 /* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
689 ceu_write(pcdev, CFSZR, (height << 16) | width); 728 ceu_write(pcdev, CFSZR, (height << 16) | width);
690 ceu_write(pcdev, CDWDR, cdwdr_width); 729 ceu_write(pcdev, CDWDR, cdwdr_width);
691} 730}
@@ -723,66 +762,93 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
723 ceu_write(pcdev, CAPSR, capsr); 762 ceu_write(pcdev, CAPSR, capsr);
724} 763}
725 764
765/* Find the bus subdevice driver, e.g., CSI2 */
766static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
767 struct soc_camera_device *icd)
768{
769 if (pcdev->csi2_pdev) {
770 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
771 if (csi2_sd && csi2_sd->grp_id == (u32)icd)
772 return csi2_sd;
773 }
774
775 return soc_camera_to_subdev(icd);
776}
777
778#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \
779 V4L2_MBUS_PCLK_SAMPLE_RISING | \
780 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
781 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
782 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
783 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
784 V4L2_MBUS_DATA_ACTIVE_HIGH)
785
726/* Capture is not running, no interrupts, no locking needed */ 786/* Capture is not running, no interrupts, no locking needed */
727static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 787static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
728 __u32 pixfmt) 788 __u32 pixfmt)
729{ 789{
730 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 790 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
731 struct sh_mobile_ceu_dev *pcdev = ici->priv; 791 struct sh_mobile_ceu_dev *pcdev = ici->priv;
732 int ret; 792 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
733 unsigned long camera_flags, common_flags, value;
734 int yuv_lineskip;
735 struct sh_mobile_ceu_cam *cam = icd->host_priv; 793 struct sh_mobile_ceu_cam *cam = icd->host_priv;
794 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
795 unsigned long value, common_flags = CEU_BUS_FLAGS;
736 u32 capsr = capture_save_reset(pcdev); 796 u32 capsr = capture_save_reset(pcdev);
797 unsigned int yuv_lineskip;
798 int ret;
737 799
738 camera_flags = icd->ops->query_bus_param(icd); 800 /*
739 common_flags = soc_camera_bus_param_compatible(camera_flags, 801 * If the client doesn't implement g_mbus_config, we just use our
740 make_bus_param(pcdev)); 802 * platform data
741 if (!common_flags) 803 */
742 return -EINVAL; 804 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
805 if (!ret) {
806 common_flags = soc_mbus_config_compatible(&cfg,
807 common_flags);
808 if (!common_flags)
809 return -EINVAL;
810 } else if (ret != -ENOIOCTLCMD) {
811 return ret;
812 }
743 813
744 /* Make choises, based on platform preferences */ 814 /* Make choises, based on platform preferences */
745 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 815 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
746 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 816 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
747 if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) 817 if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
748 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 818 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
749 else 819 else
750 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 820 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
751 } 821 }
752 822
753 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 823 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
754 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 824 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
755 if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) 825 if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
756 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 826 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
757 else 827 else
758 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 828 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
759 } 829 }
760 830
761 ret = icd->ops->set_bus_param(icd, common_flags); 831 cfg.flags = common_flags;
762 if (ret < 0) 832 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
833 if (ret < 0 && ret != -ENOIOCTLCMD)
763 return ret; 834 return ret;
764 835
765 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 836 if (icd->current_fmt->host_fmt->bits_per_sample > 8)
766 case SOCAM_DATAWIDTH_8:
767 pcdev->is_16bit = 0;
768 break;
769 case SOCAM_DATAWIDTH_16:
770 pcdev->is_16bit = 1; 837 pcdev->is_16bit = 1;
771 break; 838 else
772 default: 839 pcdev->is_16bit = 0;
773 return -EINVAL;
774 }
775 840
776 ceu_write(pcdev, CRCNTR, 0); 841 ceu_write(pcdev, CRCNTR, 0);
777 ceu_write(pcdev, CRCMPR, 0); 842 ceu_write(pcdev, CRCMPR, 0);
778 843
779 value = 0x00000010; /* data fetch by default */ 844 value = 0x00000010; /* data fetch by default */
780 yuv_lineskip = 0; 845 yuv_lineskip = 0x10;
781 846
782 switch (icd->current_fmt->host_fmt->fourcc) { 847 switch (icd->current_fmt->host_fmt->fourcc) {
783 case V4L2_PIX_FMT_NV12: 848 case V4L2_PIX_FMT_NV12:
784 case V4L2_PIX_FMT_NV21: 849 case V4L2_PIX_FMT_NV21:
785 yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ 850 /* convert 4:2:2 -> 4:2:0 */
851 yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
786 /* fall-through */ 852 /* fall-through */
787 case V4L2_PIX_FMT_NV16: 853 case V4L2_PIX_FMT_NV16:
788 case V4L2_PIX_FMT_NV61: 854 case V4L2_PIX_FMT_NV61:
@@ -808,8 +874,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
808 icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61) 874 icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
809 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ 875 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
810 876
811 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; 877 value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
812 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; 878 value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
813 value |= pcdev->is_16bit ? 1 << 12 : 0; 879 value |= pcdev->is_16bit ? 1 << 12 : 0;
814 880
815 /* CSI2 mode */ 881 /* CSI2 mode */
@@ -852,9 +918,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
852 * using 7 we swap the data bytes to match the incoming order: 918 * using 7 we swap the data bytes to match the incoming order:
853 * D0, D1, D2, D3, D4, D5, D6, D7 919 * D0, D1, D2, D3, D4, D5, D6, D7
854 */ 920 */
855 value = 0x00000017; 921 value = 0x00000007 | yuv_lineskip;
856 if (yuv_lineskip)
857 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
858 922
859 ceu_write(pcdev, CDOCR, value); 923 ceu_write(pcdev, CDOCR, value);
860 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 924 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
@@ -875,13 +939,19 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
875{ 939{
876 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 940 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
877 struct sh_mobile_ceu_dev *pcdev = ici->priv; 941 struct sh_mobile_ceu_dev *pcdev = ici->priv;
878 unsigned long camera_flags, common_flags; 942 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
943 unsigned long common_flags = CEU_BUS_FLAGS;
944 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
945 int ret;
879 946
880 camera_flags = icd->ops->query_bus_param(icd); 947 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
881 common_flags = soc_camera_bus_param_compatible(camera_flags, 948 if (!ret)
882 make_bus_param(pcdev)); 949 common_flags = soc_mbus_config_compatible(&cfg,
883 if (!common_flags || buswidth > 16 || 950 common_flags);
884 (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16))) 951 else if (ret != -ENOIOCTLCMD)
952 return ret;
953
954 if (!common_flags || buswidth > 16)
885 return -EINVAL; 955 return -EINVAL;
886 956
887 return 0; 957 return 0;
@@ -891,26 +961,26 @@ static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
891 { 961 {
892 .fourcc = V4L2_PIX_FMT_NV12, 962 .fourcc = V4L2_PIX_FMT_NV12,
893 .name = "NV12", 963 .name = "NV12",
894 .bits_per_sample = 12, 964 .bits_per_sample = 8,
895 .packing = SOC_MBUS_PACKING_NONE, 965 .packing = SOC_MBUS_PACKING_1_5X8,
896 .order = SOC_MBUS_ORDER_LE, 966 .order = SOC_MBUS_ORDER_LE,
897 }, { 967 }, {
898 .fourcc = V4L2_PIX_FMT_NV21, 968 .fourcc = V4L2_PIX_FMT_NV21,
899 .name = "NV21", 969 .name = "NV21",
900 .bits_per_sample = 12, 970 .bits_per_sample = 8,
901 .packing = SOC_MBUS_PACKING_NONE, 971 .packing = SOC_MBUS_PACKING_1_5X8,
902 .order = SOC_MBUS_ORDER_LE, 972 .order = SOC_MBUS_ORDER_LE,
903 }, { 973 }, {
904 .fourcc = V4L2_PIX_FMT_NV16, 974 .fourcc = V4L2_PIX_FMT_NV16,
905 .name = "NV16", 975 .name = "NV16",
906 .bits_per_sample = 16, 976 .bits_per_sample = 8,
907 .packing = SOC_MBUS_PACKING_NONE, 977 .packing = SOC_MBUS_PACKING_2X8_PADHI,
908 .order = SOC_MBUS_ORDER_LE, 978 .order = SOC_MBUS_ORDER_LE,
909 }, { 979 }, {
910 .fourcc = V4L2_PIX_FMT_NV61, 980 .fourcc = V4L2_PIX_FMT_NV61,
911 .name = "NV61", 981 .name = "NV61",
912 .bits_per_sample = 16, 982 .bits_per_sample = 8,
913 .packing = SOC_MBUS_PACKING_NONE, 983 .packing = SOC_MBUS_PACKING_2X8_PADHI,
914 .order = SOC_MBUS_ORDER_LE, 984 .order = SOC_MBUS_ORDER_LE,
915 }, 985 },
916}; 986};
@@ -920,6 +990,8 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
920{ 990{
921 return fmt->packing == SOC_MBUS_PACKING_NONE || 991 return fmt->packing == SOC_MBUS_PACKING_NONE ||
922 (fmt->bits_per_sample == 8 && 992 (fmt->bits_per_sample == 8 &&
993 fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
994 (fmt->bits_per_sample == 8 &&
923 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 995 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
924 (fmt->bits_per_sample > 8 && 996 (fmt->bits_per_sample > 8 &&
925 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 997 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
@@ -927,6 +999,38 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
927 999
928static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); 1000static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
929 1001
1002static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
1003{
1004 return container_of(ctrl->handler, struct soc_camera_device,
1005 ctrl_handler);
1006}
1007
1008static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
1009{
1010 struct soc_camera_device *icd = ctrl_to_icd(ctrl);
1011 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1012 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1013
1014 switch (ctrl->id) {
1015 case V4L2_CID_SHARPNESS:
1016 switch (icd->current_fmt->host_fmt->fourcc) {
1017 case V4L2_PIX_FMT_NV12:
1018 case V4L2_PIX_FMT_NV21:
1019 case V4L2_PIX_FMT_NV16:
1020 case V4L2_PIX_FMT_NV61:
1021 ceu_write(pcdev, CLFCR, !ctrl->val);
1022 return 0;
1023 }
1024 break;
1025 }
1026
1027 return -EINVAL;
1028}
1029
1030static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
1031 .s_ctrl = sh_mobile_ceu_s_ctrl,
1032};
1033
930static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx, 1034static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
931 struct soc_camera_format_xlate *xlate) 1035 struct soc_camera_format_xlate *xlate)
932{ 1036{
@@ -952,6 +1056,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
952 } 1056 }
953 1057
954 if (!pcdev->pdata->csi2) { 1058 if (!pcdev->pdata->csi2) {
1059 /* Are there any restrictions in the CSI-2 case? */
955 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); 1060 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
956 if (ret < 0) 1061 if (ret < 0)
957 return 0; 1062 return 0;
@@ -962,6 +1067,12 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
962 struct v4l2_rect rect; 1067 struct v4l2_rect rect;
963 int shift = 0; 1068 int shift = 0;
964 1069
1070 /* Add our control */
1071 v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
1072 V4L2_CID_SHARPNESS, 0, 1, 1, 0);
1073 if (icd->ctrl_handler.error)
1074 return icd->ctrl_handler.error;
1075
965 /* FIXME: subwindow is lost between close / open */ 1076 /* FIXME: subwindow is lost between close / open */
966 1077
967 /* Cache current client geometry */ 1078 /* Cache current client geometry */
@@ -1004,9 +1115,6 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
1004 cam->width = mf.width; 1115 cam->width = mf.width;
1005 cam->height = mf.height; 1116 cam->height = mf.height;
1006 1117
1007 cam->width = mf.width;
1008 cam->height = mf.height;
1009
1010 icd->host_priv = cam; 1118 icd->host_priv = cam;
1011 } else { 1119 } else {
1012 cam = icd->host_priv; 1120 cam = icd->host_priv;
@@ -1278,6 +1386,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
1278 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 1386 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
1279 unsigned int max_width, max_height; 1387 unsigned int max_width, max_height;
1280 struct v4l2_cropcap cap; 1388 struct v4l2_cropcap cap;
1389 bool ceu_1to1;
1281 int ret; 1390 int ret;
1282 1391
1283 ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, 1392 ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
@@ -1287,7 +1396,14 @@ static int client_s_fmt(struct soc_camera_device *icd,
1287 1396
1288 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height); 1397 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
1289 1398
1290 if ((width == mf->width && height == mf->height) || !ceu_can_scale) 1399 if (width == mf->width && height == mf->height) {
1400 /* Perfect! The client has done it all. */
1401 ceu_1to1 = true;
1402 goto update_cache;
1403 }
1404
1405 ceu_1to1 = false;
1406 if (!ceu_can_scale)
1291 goto update_cache; 1407 goto update_cache;
1292 1408
1293 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1409 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1327,7 +1443,10 @@ update_cache:
1327 if (ret < 0) 1443 if (ret < 0)
1328 return ret; 1444 return ret;
1329 1445
1330 update_subrect(cam); 1446 if (ceu_1to1)
1447 cam->subrect = cam->rect;
1448 else
1449 update_subrect(cam);
1331 1450
1332 return 0; 1451 return 0;
1333} 1452}
@@ -1414,7 +1533,10 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1414 capsr = capture_save_reset(pcdev); 1533 capsr = capture_save_reset(pcdev);
1415 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); 1534 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1416 1535
1417 /* 1. - 2. Apply iterative camera S_CROP for new input window. */ 1536 /*
1537 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
1538 * actual camera rectangle.
1539 */
1418 ret = client_s_crop(icd, a, &cam_crop); 1540 ret = client_s_crop(icd, a, &cam_crop);
1419 if (ret < 0) 1541 if (ret < 0)
1420 return ret; 1542 return ret;
@@ -1498,8 +1620,9 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1498 ceu_write(pcdev, CFLCR, cflcr); 1620 ceu_write(pcdev, CFLCR, cflcr);
1499 } 1621 }
1500 1622
1501 icd->user_width = out_width; 1623 icd->user_width = out_width & ~3;
1502 icd->user_height = out_height; 1624 icd->user_height = out_height & ~3;
1625 /* Offsets are applied at the CEU scaling filter input */
1503 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1; 1626 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
1504 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1; 1627 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1505 1628
@@ -1538,7 +1661,7 @@ static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
1538 * CEU crop, mapped backed onto the client input (subrect). 1661 * CEU crop, mapped backed onto the client input (subrect).
1539 */ 1662 */
1540static void calculate_client_output(struct soc_camera_device *icd, 1663static void calculate_client_output(struct soc_camera_device *icd,
1541 struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf) 1664 const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1542{ 1665{
1543 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1666 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1544 struct device *dev = icd->parent; 1667 struct device *dev = icd->parent;
@@ -1574,8 +1697,8 @@ static void calculate_client_output(struct soc_camera_device *icd,
1574 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v); 1697 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1575 1698
1576 /* 1699 /*
1577 * 4. Calculate client output window by applying combined scales to real 1700 * 4. Calculate desired client output window by applying combined scales
1578 * input window. 1701 * to client (real) input window.
1579 */ 1702 */
1580 mf->width = scale_down(cam->rect.width, scale_h); 1703 mf->width = scale_down(cam->rect.width, scale_h);
1581 mf->height = scale_down(cam->rect.height, scale_v); 1704 mf->height = scale_down(cam->rect.height, scale_v);
@@ -1600,8 +1723,6 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1600 bool image_mode; 1723 bool image_mode;
1601 enum v4l2_field field; 1724 enum v4l2_field field;
1602 1725
1603 dev_geo(dev, "S_FMT(pix=0x%x, %ux%u)\n", pixfmt, pix->width, pix->height);
1604
1605 switch (pix->field) { 1726 switch (pix->field) {
1606 default: 1727 default:
1607 pix->field = V4L2_FIELD_NONE; 1728 pix->field = V4L2_FIELD_NONE;
@@ -1622,8 +1743,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1622 return -EINVAL; 1743 return -EINVAL;
1623 } 1744 }
1624 1745
1625 /* 1.-4. Calculate client output geometry */ 1746 /* 1.-4. Calculate desired client output geometry */
1626 calculate_client_output(icd, &f->fmt.pix, &mf); 1747 calculate_client_output(icd, pix, &mf);
1627 mf.field = pix->field; 1748 mf.field = pix->field;
1628 mf.colorspace = pix->colorspace; 1749 mf.colorspace = pix->colorspace;
1629 mf.code = xlate->code; 1750 mf.code = xlate->code;
@@ -1639,6 +1760,9 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1639 image_mode = false; 1760 image_mode = false;
1640 } 1761 }
1641 1762
1763 dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
1764 pix->width, pix->height);
1765
1642 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height); 1766 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
1643 1767
1644 /* 5. - 9. */ 1768 /* 5. - 9. */
@@ -1700,6 +1824,10 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1700 pcdev->field = field; 1824 pcdev->field = field;
1701 pcdev->image_mode = image_mode; 1825 pcdev->image_mode = image_mode;
1702 1826
1827 /* CFSZR requirement */
1828 pix->width &= ~3;
1829 pix->height &= ~3;
1830
1703 return 0; 1831 return 0;
1704} 1832}
1705 1833
@@ -1725,7 +1853,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1725 1853
1726 /* FIXME: calculate using depth and bus width */ 1854 /* FIXME: calculate using depth and bus width */
1727 1855
1728 v4l_bound_align_image(&pix->width, 2, 2560, 1, 1856 /* CFSZR requires height and width to be 4-pixel aligned */
1857 v4l_bound_align_image(&pix->width, 2, 2560, 2,
1729 &pix->height, 4, 1920, 2, 0); 1858 &pix->height, 4, 1920, 2, 0);
1730 1859
1731 width = pix->width; 1860 width = pix->width;
@@ -1778,6 +1907,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1778 pix->height = height; 1907 pix->height = height;
1779 } 1908 }
1780 1909
1910 pix->width &= ~3;
1911 pix->height &= ~3;
1912
1781 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n", 1913 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1782 __func__, ret, pix->pixelformat, pix->width, pix->height); 1914 __func__, ret, pix->pixelformat, pix->width, pix->height);
1783 1915
@@ -1824,8 +1956,8 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1824 out_height != f.fmt.pix.height)) 1956 out_height != f.fmt.pix.height))
1825 ret = -EINVAL; 1957 ret = -EINVAL;
1826 if (!ret) { 1958 if (!ret) {
1827 icd->user_width = out_width; 1959 icd->user_width = out_width & ~3;
1828 icd->user_height = out_height; 1960 icd->user_height = out_height & ~3;
1829 ret = sh_mobile_ceu_set_bus_param(icd, 1961 ret = sh_mobile_ceu_set_bus_param(icd,
1830 icd->current_fmt->host_fmt->fourcc); 1962 icd->current_fmt->host_fmt->fourcc);
1831 } 1963 }
@@ -1869,55 +2001,6 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
1869 return vb2_queue_init(q); 2001 return vb2_queue_init(q);
1870} 2002}
1871 2003
1872static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1873 struct v4l2_control *ctrl)
1874{
1875 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1876 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1877 u32 val;
1878
1879 switch (ctrl->id) {
1880 case V4L2_CID_SHARPNESS:
1881 val = ceu_read(pcdev, CLFCR);
1882 ctrl->value = val ^ 1;
1883 return 0;
1884 }
1885 return -ENOIOCTLCMD;
1886}
1887
1888static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1889 struct v4l2_control *ctrl)
1890{
1891 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1892 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1893
1894 switch (ctrl->id) {
1895 case V4L2_CID_SHARPNESS:
1896 switch (icd->current_fmt->host_fmt->fourcc) {
1897 case V4L2_PIX_FMT_NV12:
1898 case V4L2_PIX_FMT_NV21:
1899 case V4L2_PIX_FMT_NV16:
1900 case V4L2_PIX_FMT_NV61:
1901 ceu_write(pcdev, CLFCR, !ctrl->value);
1902 return 0;
1903 }
1904 return -EINVAL;
1905 }
1906 return -ENOIOCTLCMD;
1907}
1908
1909static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
1910 {
1911 .id = V4L2_CID_SHARPNESS,
1912 .type = V4L2_CTRL_TYPE_BOOLEAN,
1913 .name = "Low-pass filter",
1914 .minimum = 0,
1915 .maximum = 1,
1916 .step = 1,
1917 .default_value = 0,
1918 },
1919};
1920
1921static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { 2004static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1922 .owner = THIS_MODULE, 2005 .owner = THIS_MODULE,
1923 .add = sh_mobile_ceu_add_device, 2006 .add = sh_mobile_ceu_add_device,
@@ -1929,14 +2012,10 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1929 .set_livecrop = sh_mobile_ceu_set_livecrop, 2012 .set_livecrop = sh_mobile_ceu_set_livecrop,
1930 .set_fmt = sh_mobile_ceu_set_fmt, 2013 .set_fmt = sh_mobile_ceu_set_fmt,
1931 .try_fmt = sh_mobile_ceu_try_fmt, 2014 .try_fmt = sh_mobile_ceu_try_fmt,
1932 .set_ctrl = sh_mobile_ceu_set_ctrl,
1933 .get_ctrl = sh_mobile_ceu_get_ctrl,
1934 .poll = sh_mobile_ceu_poll, 2015 .poll = sh_mobile_ceu_poll,
1935 .querycap = sh_mobile_ceu_querycap, 2016 .querycap = sh_mobile_ceu_querycap,
1936 .set_bus_param = sh_mobile_ceu_set_bus_param, 2017 .set_bus_param = sh_mobile_ceu_set_bus_param,
1937 .init_videobuf2 = sh_mobile_ceu_init_videobuf, 2018 .init_videobuf2 = sh_mobile_ceu_init_videobuf,
1938 .controls = sh_mobile_ceu_controls,
1939 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
1940}; 2019};
1941 2020
1942struct bus_wait { 2021struct bus_wait {
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 2893a0134c7e..37706eb81f25 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -19,6 +19,7 @@
19#include <media/sh_mobile_ceu.h> 19#include <media/sh_mobile_ceu.h>
20#include <media/sh_mobile_csi2.h> 20#include <media/sh_mobile_csi2.h>
21#include <media/soc_camera.h> 21#include <media/soc_camera.h>
22#include <media/soc_mediabus.h>
22#include <media/v4l2-common.h> 23#include <media/v4l2-common.h>
23#include <media/v4l2-dev.h> 24#include <media/v4l2-dev.h>
24#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
@@ -35,11 +36,10 @@ struct sh_csi2 {
35 struct v4l2_subdev subdev; 36 struct v4l2_subdev subdev;
36 struct list_head list; 37 struct list_head list;
37 unsigned int irq; 38 unsigned int irq;
39 unsigned long mipi_flags;
38 void __iomem *base; 40 void __iomem *base;
39 struct platform_device *pdev; 41 struct platform_device *pdev;
40 struct sh_csi2_client_config *client; 42 struct sh_csi2_client_config *client;
41 unsigned long (*query_bus_param)(struct soc_camera_device *);
42 int (*set_bus_param)(struct soc_camera_device *, unsigned long);
43}; 43};
44 44
45static int sh_csi2_try_fmt(struct v4l2_subdev *sd, 45static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
@@ -127,9 +127,34 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
127 return 0; 127 return 0;
128} 128}
129 129
130static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
131 struct v4l2_mbus_config *cfg)
132{
133 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
134 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
135 V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
136 cfg->type = V4L2_MBUS_PARALLEL;
137
138 return 0;
139}
140
141static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd,
142 const struct v4l2_mbus_config *cfg)
143{
144 struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
145 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
146 struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
147 struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
148 .flags = priv->mipi_flags};
149
150 return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
151}
152
130static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { 153static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = {
131 .s_mbus_fmt = sh_csi2_s_fmt, 154 .s_mbus_fmt = sh_csi2_s_fmt,
132 .try_mbus_fmt = sh_csi2_try_fmt, 155 .try_mbus_fmt = sh_csi2_try_fmt,
156 .g_mbus_config = sh_csi2_g_mbus_config,
157 .s_mbus_config = sh_csi2_s_mbus_config,
133}; 158};
134 159
135static void sh_csi2_hwinit(struct sh_csi2 *priv) 160static void sh_csi2_hwinit(struct sh_csi2 *priv)
@@ -144,11 +169,21 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
144 udelay(5); 169 udelay(5);
145 iowrite32(0x00000000, priv->base + SH_CSI2_SRST); 170 iowrite32(0x00000000, priv->base + SH_CSI2_SRST);
146 171
147 if (priv->client->lanes & 3) 172 switch (pdata->type) {
148 tmp |= priv->client->lanes & 3; 173 case SH_CSI2C:
149 else 174 if (priv->client->lanes == 1)
150 /* Default - both lanes */ 175 tmp |= 1;
151 tmp |= 3; 176 else
177 /* Default - both lanes */
178 tmp |= 3;
179 break;
180 case SH_CSI2I:
181 if (!priv->client->lanes || priv->client->lanes > 4)
182 /* Default - all 4 lanes */
183 tmp |= 0xf;
184 else
185 tmp |= (1 << priv->client->lanes) - 1;
186 }
152 187
153 if (priv->client->phy == SH_CSI2_PHY_MAIN) 188 if (priv->client->phy == SH_CSI2_PHY_MAIN)
154 tmp |= 0x8000; 189 tmp |= 0x8000;
@@ -163,38 +198,18 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
163 iowrite32(tmp, priv->base + SH_CSI2_CHKSUM); 198 iowrite32(tmp, priv->base + SH_CSI2_CHKSUM);
164} 199}
165 200
166static int sh_csi2_set_bus_param(struct soc_camera_device *icd,
167 unsigned long flags)
168{
169 return 0;
170}
171
172static unsigned long sh_csi2_query_bus_param(struct soc_camera_device *icd)
173{
174 struct soc_camera_link *icl = to_soc_camera_link(icd);
175 const unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
176 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
177 SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_DATA_ACTIVE_HIGH;
178
179 return soc_camera_apply_sensor_flags(icl, flags);
180}
181
182static int sh_csi2_client_connect(struct sh_csi2 *priv) 201static int sh_csi2_client_connect(struct sh_csi2 *priv)
183{ 202{
184 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; 203 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
185 struct v4l2_subdev *sd, *csi2_sd = &priv->subdev; 204 struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id;
186 struct soc_camera_device *icd = NULL; 205 struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
187 struct device *dev = v4l2_get_subdevdata(&priv->subdev); 206 struct device *dev = v4l2_get_subdevdata(&priv->subdev);
188 int i; 207 struct v4l2_mbus_config cfg;
208 unsigned long common_flags, csi2_flags;
209 int i, ret;
189 210
190 v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev) 211 if (priv->client)
191 if (sd->grp_id) { 212 return -EBUSY;
192 icd = (struct soc_camera_device *)sd->grp_id;
193 break;
194 }
195
196 if (!icd)
197 return -EINVAL;
198 213
199 for (i = 0; i < pdata->num_clients; i++) 214 for (i = 0; i < pdata->num_clients; i++)
200 if (&pdata->clients[i].pdev->dev == icd->pdev) 215 if (&pdata->clients[i].pdev->dev == icd->pdev)
@@ -205,14 +220,41 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
205 if (i == pdata->num_clients) 220 if (i == pdata->num_clients)
206 return -ENODEV; 221 return -ENODEV;
207 222
208 priv->client = pdata->clients + i; 223 /* Check if we can support this camera */
224 csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
225
226 switch (pdata->type) {
227 case SH_CSI2C:
228 if (pdata->clients[i].lanes != 1)
229 csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
230 break;
231 case SH_CSI2I:
232 switch (pdata->clients[i].lanes) {
233 default:
234 csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
235 case 3:
236 csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
237 case 2:
238 csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
239 }
240 }
209 241
210 priv->set_bus_param = icd->ops->set_bus_param; 242 cfg.type = V4L2_MBUS_CSI2;
211 priv->query_bus_param = icd->ops->query_bus_param; 243 ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
212 icd->ops->set_bus_param = sh_csi2_set_bus_param; 244 if (ret == -ENOIOCTLCMD)
213 icd->ops->query_bus_param = sh_csi2_query_bus_param; 245 common_flags = csi2_flags;
246 else if (!ret)
247 common_flags = soc_mbus_config_compatible(&cfg,
248 csi2_flags);
249 else
250 common_flags = 0;
214 251
215 csi2_sd->grp_id = (long)icd; 252 if (!common_flags)
253 return -EINVAL;
254
255 /* All good: camera MIPI configuration supported */
256 priv->mipi_flags = common_flags;
257 priv->client = pdata->clients + i;
216 258
217 pm_runtime_get_sync(dev); 259 pm_runtime_get_sync(dev);
218 260
@@ -223,16 +265,10 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
223 265
224static void sh_csi2_client_disconnect(struct sh_csi2 *priv) 266static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
225{ 267{
226 struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id; 268 if (!priv->client)
269 return;
227 270
228 priv->client = NULL; 271 priv->client = NULL;
229 priv->subdev.grp_id = 0;
230
231 /* Driver is about to be unbound */
232 icd->ops->set_bus_param = priv->set_bus_param;
233 icd->ops->query_bus_param = priv->query_bus_param;
234 priv->set_bus_param = NULL;
235 priv->query_bus_param = NULL;
236 272
237 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); 273 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
238} 274}
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 5bdfe7e16bc1..b72580c38957 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -50,49 +50,65 @@ static LIST_HEAD(hosts);
50static LIST_HEAD(devices); 50static LIST_HEAD(devices);
51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
52 52
53static int soc_camera_power_set(struct soc_camera_device *icd, 53static int soc_camera_power_on(struct soc_camera_device *icd,
54 struct soc_camera_link *icl, 54 struct soc_camera_link *icl)
55 int power_on)
56{ 55{
57 int ret; 56 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
58 57 int ret = regulator_bulk_enable(icl->num_regulators,
59 if (power_on) { 58 icl->regulators);
60 ret = regulator_bulk_enable(icl->num_regulators, 59 if (ret < 0) {
61 icl->regulators); 60 dev_err(icd->pdev, "Cannot enable regulators\n");
62 if (ret < 0) { 61 return ret;
63 dev_err(icd->pdev, "Cannot enable regulators\n"); 62 }
64 return ret;
65 }
66 63
67 if (icl->power) 64 if (icl->power) {
68 ret = icl->power(icd->pdev, power_on); 65 ret = icl->power(icd->pdev, 1);
69 if (ret < 0) { 66 if (ret < 0) {
70 dev_err(icd->pdev, 67 dev_err(icd->pdev,
71 "Platform failed to power-on the camera.\n"); 68 "Platform failed to power-on the camera.\n");
72 69 goto elinkpwr;
73 regulator_bulk_disable(icl->num_regulators,
74 icl->regulators);
75 return ret;
76 } 70 }
77 } else { 71 }
78 ret = 0; 72
79 if (icl->power) 73 ret = v4l2_subdev_call(sd, core, s_power, 1);
80 ret = icl->power(icd->pdev, 0); 74 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
75 goto esdpwr;
76
77 return 0;
78
79esdpwr:
80 if (icl->power)
81 icl->power(icd->pdev, 0);
82elinkpwr:
83 regulator_bulk_disable(icl->num_regulators,
84 icl->regulators);
85 return ret;
86}
87
88static int soc_camera_power_off(struct soc_camera_device *icd,
89 struct soc_camera_link *icl)
90{
91 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
92 int ret = v4l2_subdev_call(sd, core, s_power, 0);
93
94 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
95 return ret;
96
97 if (icl->power) {
98 ret = icl->power(icd->pdev, 0);
81 if (ret < 0) { 99 if (ret < 0) {
82 dev_err(icd->pdev, 100 dev_err(icd->pdev,
83 "Platform failed to power-off the camera.\n"); 101 "Platform failed to power-off the camera.\n");
84 return ret; 102 return ret;
85 } 103 }
86
87 ret = regulator_bulk_disable(icl->num_regulators,
88 icl->regulators);
89 if (ret < 0) {
90 dev_err(icd->pdev, "Cannot disable regulators\n");
91 return ret;
92 }
93 } 104 }
94 105
95 return 0; 106 ret = regulator_bulk_disable(icl->num_regulators,
107 icl->regulators);
108 if (ret < 0)
109 dev_err(icd->pdev, "Cannot disable regulators\n");
110
111 return ret;
96} 112}
97 113
98const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 114const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
@@ -108,38 +124,38 @@ const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
108EXPORT_SYMBOL(soc_camera_xlate_by_fourcc); 124EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
109 125
110/** 126/**
111 * soc_camera_apply_sensor_flags() - apply platform SOCAM_SENSOR_INVERT_* flags 127 * soc_camera_apply_board_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
112 * @icl: camera platform parameters 128 * @icl: camera platform parameters
113 * @flags: flags to be inverted according to platform configuration 129 * @cfg: media bus configuration
114 * @return: resulting flags 130 * @return: resulting flags
115 */ 131 */
116unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 132unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
117 unsigned long flags) 133 const struct v4l2_mbus_config *cfg)
118{ 134{
119 unsigned long f; 135 unsigned long f, flags = cfg->flags;
120 136
121 /* If only one of the two polarities is supported, switch to the opposite */ 137 /* If only one of the two polarities is supported, switch to the opposite */
122 if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) { 138 if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
123 f = flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW); 139 f = flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW);
124 if (f == SOCAM_HSYNC_ACTIVE_HIGH || f == SOCAM_HSYNC_ACTIVE_LOW) 140 if (f == V4L2_MBUS_HSYNC_ACTIVE_HIGH || f == V4L2_MBUS_HSYNC_ACTIVE_LOW)
125 flags ^= SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW; 141 flags ^= V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW;
126 } 142 }
127 143
128 if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) { 144 if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
129 f = flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW); 145 f = flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW);
130 if (f == SOCAM_VSYNC_ACTIVE_HIGH || f == SOCAM_VSYNC_ACTIVE_LOW) 146 if (f == V4L2_MBUS_VSYNC_ACTIVE_HIGH || f == V4L2_MBUS_VSYNC_ACTIVE_LOW)
131 flags ^= SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW; 147 flags ^= V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW;
132 } 148 }
133 149
134 if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) { 150 if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
135 f = flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING); 151 f = flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING);
136 if (f == SOCAM_PCLK_SAMPLE_RISING || f == SOCAM_PCLK_SAMPLE_FALLING) 152 if (f == V4L2_MBUS_PCLK_SAMPLE_RISING || f == V4L2_MBUS_PCLK_SAMPLE_FALLING)
137 flags ^= SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING; 153 flags ^= V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
138 } 154 }
139 155
140 return flags; 156 return flags;
141} 157}
142EXPORT_SYMBOL(soc_camera_apply_sensor_flags); 158EXPORT_SYMBOL(soc_camera_apply_board_flags);
143 159
144#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ 160#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
145 ((x) >> 24) & 0xff 161 ((x) >> 24) & 0xff
@@ -233,6 +249,14 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
233 return v4l2_subdev_call(sd, core, s_std, *a); 249 return v4l2_subdev_call(sd, core, s_std, *a);
234} 250}
235 251
252static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
253{
254 struct soc_camera_device *icd = file->private_data;
255 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
256
257 return v4l2_subdev_call(sd, core, g_std, a);
258}
259
236static int soc_camera_enum_fsizes(struct file *file, void *fh, 260static int soc_camera_enum_fsizes(struct file *file, void *fh,
237 struct v4l2_frmsizeenum *fsize) 261 struct v4l2_frmsizeenum *fsize)
238{ 262{
@@ -318,6 +342,32 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
318 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK); 342 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
319} 343}
320 344
345static int soc_camera_create_bufs(struct file *file, void *priv,
346 struct v4l2_create_buffers *create)
347{
348 struct soc_camera_device *icd = file->private_data;
349 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
350
351 /* videobuf2 only */
352 if (ici->ops->init_videobuf)
353 return -EINVAL;
354 else
355 return vb2_create_bufs(&icd->vb2_vidq, create);
356}
357
358static int soc_camera_prepare_buf(struct file *file, void *priv,
359 struct v4l2_buffer *b)
360{
361 struct soc_camera_device *icd = file->private_data;
362 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
363
364 /* videobuf2 only */
365 if (ici->ops->init_videobuf)
366 return -EINVAL;
367 else
368 return vb2_prepare_buf(&icd->vb2_vidq, b);
369}
370
321/* Always entered with .video_lock held */ 371/* Always entered with .video_lock held */
322static int soc_camera_init_user_formats(struct soc_camera_device *icd) 372static int soc_camera_init_user_formats(struct soc_camera_device *icd)
323{ 373{
@@ -448,7 +498,7 @@ static int soc_camera_open(struct file *file)
448 struct soc_camera_host *ici; 498 struct soc_camera_host *ici;
449 int ret; 499 int ret;
450 500
451 if (!icd->ops) 501 if (!to_soc_camera_control(icd))
452 /* No device driver attached */ 502 /* No device driver attached */
453 return -ENODEV; 503 return -ENODEV;
454 504
@@ -476,7 +526,7 @@ static int soc_camera_open(struct file *file)
476 }, 526 },
477 }; 527 };
478 528
479 ret = soc_camera_power_set(icd, icl, 1); 529 ret = soc_camera_power_on(icd, icl);
480 if (ret < 0) 530 if (ret < 0)
481 goto epower; 531 goto epower;
482 532
@@ -512,6 +562,7 @@ static int soc_camera_open(struct file *file)
512 if (ret < 0) 562 if (ret < 0)
513 goto einitvb; 563 goto einitvb;
514 } 564 }
565 v4l2_ctrl_handler_setup(&icd->ctrl_handler);
515 } 566 }
516 567
517 file->private_data = icd; 568 file->private_data = icd;
@@ -529,7 +580,7 @@ esfmt:
529eresume: 580eresume:
530 ici->ops->remove(icd); 581 ici->ops->remove(icd);
531eiciadd: 582eiciadd:
532 soc_camera_power_set(icd, icl, 0); 583 soc_camera_power_off(icd, icl);
533epower: 584epower:
534 icd->use_count--; 585 icd->use_count--;
535 module_put(ici->ops->owner); 586 module_put(ici->ops->owner);
@@ -553,7 +604,7 @@ static int soc_camera_close(struct file *file)
553 if (ici->ops->init_videobuf2) 604 if (ici->ops->init_videobuf2)
554 vb2_queue_release(&icd->vb2_vidq); 605 vb2_queue_release(&icd->vb2_vidq);
555 606
556 soc_camera_power_set(icd, icl, 0); 607 soc_camera_power_off(icd, icl);
557 } 608 }
558 609
559 if (icd->streamer == file) 610 if (icd->streamer == file)
@@ -781,75 +832,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
781 return 0; 832 return 0;
782} 833}
783 834
784static int soc_camera_queryctrl(struct file *file, void *priv,
785 struct v4l2_queryctrl *qc)
786{
787 struct soc_camera_device *icd = file->private_data;
788 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
789 int i;
790
791 WARN_ON(priv != file->private_data);
792
793 if (!qc->id)
794 return -EINVAL;
795
796 /* First check host controls */
797 for (i = 0; i < ici->ops->num_controls; i++)
798 if (qc->id == ici->ops->controls[i].id) {
799 memcpy(qc, &(ici->ops->controls[i]),
800 sizeof(*qc));
801 return 0;
802 }
803
804 /* Then device controls */
805 for (i = 0; i < icd->ops->num_controls; i++)
806 if (qc->id == icd->ops->controls[i].id) {
807 memcpy(qc, &(icd->ops->controls[i]),
808 sizeof(*qc));
809 return 0;
810 }
811
812 return -EINVAL;
813}
814
815static int soc_camera_g_ctrl(struct file *file, void *priv,
816 struct v4l2_control *ctrl)
817{
818 struct soc_camera_device *icd = file->private_data;
819 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
820 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
821 int ret;
822
823 WARN_ON(priv != file->private_data);
824
825 if (ici->ops->get_ctrl) {
826 ret = ici->ops->get_ctrl(icd, ctrl);
827 if (ret != -ENOIOCTLCMD)
828 return ret;
829 }
830
831 return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
832}
833
834static int soc_camera_s_ctrl(struct file *file, void *priv,
835 struct v4l2_control *ctrl)
836{
837 struct soc_camera_device *icd = file->private_data;
838 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
839 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
840 int ret;
841
842 WARN_ON(priv != file->private_data);
843
844 if (ici->ops->set_ctrl) {
845 ret = ici->ops->set_ctrl(icd, ctrl);
846 if (ret != -ENOIOCTLCMD)
847 return ret;
848 }
849
850 return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
851}
852
853static int soc_camera_cropcap(struct file *file, void *fh, 835static int soc_camera_cropcap(struct file *file, void *fh,
854 struct v4l2_cropcap *a) 836 struct v4l2_cropcap *a)
855{ 837{
@@ -1003,7 +985,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
1003 goto ei2cga; 985 goto ei2cga;
1004 } 986 }
1005 987
1006 icl->board_info->platform_data = icd; 988 icl->board_info->platform_data = icl;
1007 989
1008 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, 990 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
1009 icl->board_info, NULL); 991 icl->board_info, NULL);
@@ -1052,12 +1034,29 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1052 1034
1053 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev)); 1035 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
1054 1036
1037 /*
1038 * Currently the subdev with the largest number of controls (13) is
1039 * ov6550. So let's pick 16 as a hint for the control handler. Note
1040 * that this is a hint only: too large and you waste some memory, too
1041 * small and there is a (very) small performance hit when looking up
1042 * controls in the internal hash.
1043 */
1044 ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
1045 if (ret < 0)
1046 return ret;
1047
1055 ret = regulator_bulk_get(icd->pdev, icl->num_regulators, 1048 ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
1056 icl->regulators); 1049 icl->regulators);
1057 if (ret < 0) 1050 if (ret < 0)
1058 goto ereg; 1051 goto ereg;
1059 1052
1060 ret = soc_camera_power_set(icd, icl, 1); 1053 /*
1054 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
1055 * subdevice has not been initialised yet. We'll have to call it once
1056 * again after initialisation, even though it shouldn't be needed, we
1057 * don't do any IO here.
1058 */
1059 ret = soc_camera_power_on(icd, icl);
1061 if (ret < 0) 1060 if (ret < 0)
1062 goto epower; 1061 goto epower;
1063 1062
@@ -1098,6 +1097,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1098 if (!control || !control->driver || !dev_get_drvdata(control) || 1097 if (!control || !control->driver || !dev_get_drvdata(control) ||
1099 !try_module_get(control->driver->owner)) { 1098 !try_module_get(control->driver->owner)) {
1100 icl->del_device(icd); 1099 icl->del_device(icd);
1100 ret = -ENODEV;
1101 goto enodrv; 1101 goto enodrv;
1102 } 1102 }
1103 } 1103 }
@@ -1105,6 +1105,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1105 sd = soc_camera_to_subdev(icd); 1105 sd = soc_camera_to_subdev(icd);
1106 sd->grp_id = (long)icd; 1106 sd->grp_id = (long)icd;
1107 1107
1108 if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
1109 goto ectrl;
1110
1108 /* At this point client .probe() should have run already */ 1111 /* At this point client .probe() should have run already */
1109 ret = soc_camera_init_user_formats(icd); 1112 ret = soc_camera_init_user_formats(icd);
1110 if (ret < 0) 1113 if (ret < 0)
@@ -1123,6 +1126,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1123 if (ret < 0) 1126 if (ret < 0)
1124 goto evidstart; 1127 goto evidstart;
1125 1128
1129 ret = v4l2_subdev_call(sd, core, s_power, 1);
1130 if (ret < 0 && ret != -ENOIOCTLCMD)
1131 goto esdpwr;
1132
1126 /* Try to improve our guess of a reasonable window format */ 1133 /* Try to improve our guess of a reasonable window format */
1127 if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { 1134 if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
1128 icd->user_width = mf.width; 1135 icd->user_width = mf.width;
@@ -1133,16 +1140,19 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1133 1140
1134 ici->ops->remove(icd); 1141 ici->ops->remove(icd);
1135 1142
1136 soc_camera_power_set(icd, icl, 0); 1143 soc_camera_power_off(icd, icl);
1137 1144
1138 mutex_unlock(&icd->video_lock); 1145 mutex_unlock(&icd->video_lock);
1139 1146
1140 return 0; 1147 return 0;
1141 1148
1149esdpwr:
1150 video_unregister_device(icd->vdev);
1142evidstart: 1151evidstart:
1143 mutex_unlock(&icd->video_lock); 1152 mutex_unlock(&icd->video_lock);
1144 soc_camera_free_user_formats(icd); 1153 soc_camera_free_user_formats(icd);
1145eiufmt: 1154eiufmt:
1155ectrl:
1146 if (icl->board_info) { 1156 if (icl->board_info) {
1147 soc_camera_free_i2c(icd); 1157 soc_camera_free_i2c(icd);
1148 } else { 1158 } else {
@@ -1152,13 +1162,15 @@ eiufmt:
1152enodrv: 1162enodrv:
1153eadddev: 1163eadddev:
1154 video_device_release(icd->vdev); 1164 video_device_release(icd->vdev);
1165 icd->vdev = NULL;
1155evdc: 1166evdc:
1156 ici->ops->remove(icd); 1167 ici->ops->remove(icd);
1157eadd: 1168eadd:
1158 soc_camera_power_set(icd, icl, 0); 1169 soc_camera_power_off(icd, icl);
1159epower: 1170epower:
1160 regulator_bulk_free(icl->num_regulators, icl->regulators); 1171 regulator_bulk_free(icl->num_regulators, icl->regulators);
1161ereg: 1172ereg:
1173 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1162 return ret; 1174 return ret;
1163} 1175}
1164 1176
@@ -1173,6 +1185,7 @@ static int soc_camera_remove(struct soc_camera_device *icd)
1173 1185
1174 BUG_ON(!icd->parent); 1186 BUG_ON(!icd->parent);
1175 1187
1188 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1176 if (vdev) { 1189 if (vdev) {
1177 video_unregister_device(vdev); 1190 video_unregister_device(vdev);
1178 icd->vdev = NULL; 1191 icd->vdev = NULL;
@@ -1363,24 +1376,24 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
1363 1376
1364static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1377static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1365 .vidioc_querycap = soc_camera_querycap, 1378 .vidioc_querycap = soc_camera_querycap,
1379 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1366 .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, 1380 .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap,
1367 .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
1368 .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, 1381 .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap,
1382 .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
1369 .vidioc_enum_input = soc_camera_enum_input, 1383 .vidioc_enum_input = soc_camera_enum_input,
1370 .vidioc_g_input = soc_camera_g_input, 1384 .vidioc_g_input = soc_camera_g_input,
1371 .vidioc_s_input = soc_camera_s_input, 1385 .vidioc_s_input = soc_camera_s_input,
1372 .vidioc_s_std = soc_camera_s_std, 1386 .vidioc_s_std = soc_camera_s_std,
1387 .vidioc_g_std = soc_camera_g_std,
1373 .vidioc_enum_framesizes = soc_camera_enum_fsizes, 1388 .vidioc_enum_framesizes = soc_camera_enum_fsizes,
1374 .vidioc_reqbufs = soc_camera_reqbufs, 1389 .vidioc_reqbufs = soc_camera_reqbufs,
1375 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1376 .vidioc_querybuf = soc_camera_querybuf, 1390 .vidioc_querybuf = soc_camera_querybuf,
1377 .vidioc_qbuf = soc_camera_qbuf, 1391 .vidioc_qbuf = soc_camera_qbuf,
1378 .vidioc_dqbuf = soc_camera_dqbuf, 1392 .vidioc_dqbuf = soc_camera_dqbuf,
1393 .vidioc_create_bufs = soc_camera_create_bufs,
1394 .vidioc_prepare_buf = soc_camera_prepare_buf,
1379 .vidioc_streamon = soc_camera_streamon, 1395 .vidioc_streamon = soc_camera_streamon,
1380 .vidioc_streamoff = soc_camera_streamoff, 1396 .vidioc_streamoff = soc_camera_streamoff,
1381 .vidioc_queryctrl = soc_camera_queryctrl,
1382 .vidioc_g_ctrl = soc_camera_g_ctrl,
1383 .vidioc_s_ctrl = soc_camera_s_ctrl,
1384 .vidioc_cropcap = soc_camera_cropcap, 1397 .vidioc_cropcap = soc_camera_cropcap,
1385 .vidioc_g_crop = soc_camera_g_crop, 1398 .vidioc_g_crop = soc_camera_g_crop,
1386 .vidioc_s_crop = soc_camera_s_crop, 1399 .vidioc_s_crop = soc_camera_s_crop,
@@ -1409,6 +1422,7 @@ static int video_dev_create(struct soc_camera_device *icd)
1409 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1422 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1410 vdev->release = video_device_release; 1423 vdev->release = video_device_release;
1411 vdev->tvnorms = V4L2_STD_UNKNOWN; 1424 vdev->tvnorms = V4L2_STD_UNKNOWN;
1425 vdev->ctrl_handler = &icd->ctrl_handler;
1412 vdev->lock = &icd->video_lock; 1426 vdev->lock = &icd->video_lock;
1413 1427
1414 icd->vdev = vdev; 1428 icd->vdev = vdev;
@@ -1427,11 +1441,6 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
1427 if (!icd->parent) 1441 if (!icd->parent)
1428 return -ENODEV; 1442 return -ENODEV;
1429 1443
1430 if (!icd->ops ||
1431 !icd->ops->query_bus_param ||
1432 !icd->ops->set_bus_param)
1433 return -EINVAL;
1434
1435 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); 1444 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
1436 if (ret < 0) { 1445 if (ret < 0) {
1437 dev_err(icd->pdev, "video_register_device failed: %d\n", ret); 1446 dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 8069cd6bc5e8..4402a8a74f7a 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -30,32 +30,12 @@ static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
30 return container_of(subdev, struct soc_camera_platform_priv, subdev); 30 return container_of(subdev, struct soc_camera_platform_priv, subdev);
31} 31}
32 32
33static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
34{
35 struct platform_device *pdev =
36 to_platform_device(to_soc_camera_control(icd));
37 return pdev->dev.platform_data;
38}
39
40static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable) 33static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
41{ 34{
42 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 35 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
43 return p->set_capture(p, enable); 36 return p->set_capture(p, enable);
44} 37}
45 38
46static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
47 unsigned long flags)
48{
49 return 0;
50}
51
52static unsigned long
53soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
54{
55 struct soc_camera_platform_info *p = get_info(icd);
56 return p->bus_param;
57}
58
59static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd, 39static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
60 struct v4l2_mbus_framefmt *mf) 40 struct v4l2_mbus_framefmt *mf)
61{ 41{
@@ -115,6 +95,17 @@ static int soc_camera_platform_cropcap(struct v4l2_subdev *sd,
115 return 0; 95 return 0;
116} 96}
117 97
98static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
99 struct v4l2_mbus_config *cfg)
100{
101 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
102
103 cfg->flags = p->mbus_param;
104 cfg->type = p->mbus_type;
105
106 return 0;
107}
108
118static struct v4l2_subdev_video_ops platform_subdev_video_ops = { 109static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
119 .s_stream = soc_camera_platform_s_stream, 110 .s_stream = soc_camera_platform_s_stream,
120 .enum_mbus_fmt = soc_camera_platform_enum_fmt, 111 .enum_mbus_fmt = soc_camera_platform_enum_fmt,
@@ -123,6 +114,7 @@ static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
123 .try_mbus_fmt = soc_camera_platform_fill_fmt, 114 .try_mbus_fmt = soc_camera_platform_fill_fmt,
124 .g_mbus_fmt = soc_camera_platform_fill_fmt, 115 .g_mbus_fmt = soc_camera_platform_fill_fmt,
125 .s_mbus_fmt = soc_camera_platform_fill_fmt, 116 .s_mbus_fmt = soc_camera_platform_fill_fmt,
117 .g_mbus_config = soc_camera_platform_g_mbus_config,
126}; 118};
127 119
128static struct v4l2_subdev_ops platform_subdev_ops = { 120static struct v4l2_subdev_ops platform_subdev_ops = {
@@ -130,11 +122,6 @@ static struct v4l2_subdev_ops platform_subdev_ops = {
130 .video = &platform_subdev_video_ops, 122 .video = &platform_subdev_video_ops,
131}; 123};
132 124
133static struct soc_camera_ops soc_camera_platform_ops = {
134 .set_bus_param = soc_camera_platform_set_bus_param,
135 .query_bus_param = soc_camera_platform_query_bus_param,
136};
137
138static int soc_camera_platform_probe(struct platform_device *pdev) 125static int soc_camera_platform_probe(struct platform_device *pdev)
139{ 126{
140 struct soc_camera_host *ici; 127 struct soc_camera_host *ici;
@@ -163,8 +150,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
163 /* Set the control device reference */ 150 /* Set the control device reference */
164 icd->control = &pdev->dev; 151 icd->control = &pdev->dev;
165 152
166 icd->ops = &soc_camera_platform_ops;
167
168 ici = to_soc_camera_host(icd->parent); 153 ici = to_soc_camera_host(icd->parent);
169 154
170 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); 155 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
@@ -178,7 +163,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
178 return ret; 163 return ret;
179 164
180evdrs: 165evdrs:
181 icd->ops = NULL;
182 platform_set_drvdata(pdev, NULL); 166 platform_set_drvdata(pdev, NULL);
183 kfree(priv); 167 kfree(priv);
184 return ret; 168 return ret;
@@ -187,11 +171,10 @@ evdrs:
187static int soc_camera_platform_remove(struct platform_device *pdev) 171static int soc_camera_platform_remove(struct platform_device *pdev)
188{ 172{
189 struct soc_camera_platform_priv *priv = get_priv(pdev); 173 struct soc_camera_platform_priv *priv = get_priv(pdev);
190 struct soc_camera_platform_info *p = pdev->dev.platform_data; 174 struct soc_camera_platform_info *p = v4l2_get_subdevdata(&priv->subdev);
191 struct soc_camera_device *icd = p->icd;
192 175
176 p->icd->control = NULL;
193 v4l2_device_unregister_subdev(&priv->subdev); 177 v4l2_device_unregister_subdev(&priv->subdev);
194 icd->ops = NULL;
195 platform_set_drvdata(pdev, NULL); 178 platform_set_drvdata(pdev, NULL);
196 kfree(priv); 179 kfree(priv);
197 return 0; 180 return 0;
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index bea7c9cf4f88..cf7f2194ded4 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -383,6 +383,39 @@ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
383} 383}
384EXPORT_SYMBOL(soc_mbus_get_fmtdesc); 384EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
385 385
386unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
387 unsigned int flags)
388{
389 unsigned long common_flags;
390 bool hsync = true, vsync = true, pclk, data, mode;
391 bool mipi_lanes, mipi_clock;
392
393 common_flags = cfg->flags & flags;
394
395 switch (cfg->type) {
396 case V4L2_MBUS_PARALLEL:
397 hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
398 V4L2_MBUS_HSYNC_ACTIVE_LOW);
399 vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
400 V4L2_MBUS_VSYNC_ACTIVE_LOW);
401 case V4L2_MBUS_BT656:
402 pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
403 V4L2_MBUS_PCLK_SAMPLE_FALLING);
404 data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
405 V4L2_MBUS_DATA_ACTIVE_LOW);
406 mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
407 return (!hsync || !vsync || !pclk || !data || !mode) ?
408 0 : common_flags;
409 case V4L2_MBUS_CSI2:
410 mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
411 mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
412 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
413 return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
414 }
415 return 0;
416}
417EXPORT_SYMBOL(soc_mbus_config_compatible);
418
386static int __init soc_mbus_init(void) 419static int __init soc_mbus_init(void)
387{ 420{
388 return 0; 421 return 0;
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 742482e30011..a514fa61116c 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -22,11 +22,13 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/v4l2-mediabus.h>
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h> 27
27#include <media/v4l2-subdev.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-subdev.h>
30 32
31#define GET_ID(val) ((val & 0xF8) >> 3) 33#define GET_ID(val) ((val & 0xF8) >> 3)
32#define GET_REV(val) (val & 0x07) 34#define GET_REV(val) (val & 0x07)
@@ -203,6 +205,10 @@
203#define RTSEL_FIELD 0x06 /* 0110 = FIELD */ 205#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
204#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */ 206#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */
205 207
208/* HSYNC start and end are constant for now */
209#define HSYNC_START 0x0260
210#define HSYNC_END 0x0300
211
206/* 212/*
207 * structure 213 * structure
208 */ 214 */
@@ -220,22 +226,11 @@ struct tw9910_scale_ctrl {
220 u16 vscale; 226 u16 vscale;
221}; 227};
222 228
223struct tw9910_cropping_ctrl {
224 u16 vdelay;
225 u16 vactive;
226 u16 hdelay;
227 u16 hactive;
228};
229
230struct tw9910_hsync_ctrl {
231 u16 start;
232 u16 end;
233};
234
235struct tw9910_priv { 229struct tw9910_priv {
236 struct v4l2_subdev subdev; 230 struct v4l2_subdev subdev;
237 struct tw9910_video_info *info; 231 struct tw9910_video_info *info;
238 const struct tw9910_scale_ctrl *scale; 232 const struct tw9910_scale_ctrl *scale;
233 v4l2_std_id norm;
239 u32 revision; 234 u32 revision;
240}; 235};
241 236
@@ -329,11 +324,6 @@ static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
329 }, 324 },
330}; 325};
331 326
332static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
333 .start = 0x0260,
334 .end = 0x0300,
335};
336
337/* 327/*
338 * general function 328 * general function
339 */ 329 */
@@ -378,21 +368,20 @@ static int tw9910_set_scale(struct i2c_client *client,
378 return ret; 368 return ret;
379} 369}
380 370
381static int tw9910_set_hsync(struct i2c_client *client, 371static int tw9910_set_hsync(struct i2c_client *client)
382 const struct tw9910_hsync_ctrl *hsync)
383{ 372{
384 struct tw9910_priv *priv = to_tw9910(client); 373 struct tw9910_priv *priv = to_tw9910(client);
385 int ret; 374 int ret;
386 375
387 /* bit 10 - 3 */ 376 /* bit 10 - 3 */
388 ret = i2c_smbus_write_byte_data(client, HSBEGIN, 377 ret = i2c_smbus_write_byte_data(client, HSBEGIN,
389 (hsync->start & 0x07F8) >> 3); 378 (HSYNC_START & 0x07F8) >> 3);
390 if (ret < 0) 379 if (ret < 0)
391 return ret; 380 return ret;
392 381
393 /* bit 10 - 3 */ 382 /* bit 10 - 3 */
394 ret = i2c_smbus_write_byte_data(client, HSEND, 383 ret = i2c_smbus_write_byte_data(client, HSEND,
395 (hsync->end & 0x07F8) >> 3); 384 (HSYNC_END & 0x07F8) >> 3);
396 if (ret < 0) 385 if (ret < 0)
397 return ret; 386 return ret;
398 387
@@ -400,8 +389,8 @@ static int tw9910_set_hsync(struct i2c_client *client,
400 /* bit 2 - 0 */ 389 /* bit 2 - 0 */
401 if (1 == priv->revision) 390 if (1 == priv->revision)
402 ret = tw9910_mask_set(client, HSLOWCTL, 0x77, 391 ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
403 (hsync->start & 0x0007) << 4 | 392 (HSYNC_START & 0x0007) << 4 |
404 (hsync->end & 0x0007)); 393 (HSYNC_END & 0x0007));
405 394
406 return ret; 395 return ret;
407} 396}
@@ -433,12 +422,11 @@ static int tw9910_power(struct i2c_client *client, int enable)
433 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); 422 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
434} 423}
435 424
436static const struct tw9910_scale_ctrl* 425static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
437tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) 426 u32 width, u32 height)
438{ 427{
439 const struct tw9910_scale_ctrl *scale; 428 const struct tw9910_scale_ctrl *scale;
440 const struct tw9910_scale_ctrl *ret = NULL; 429 const struct tw9910_scale_ctrl *ret = NULL;
441 v4l2_std_id norm = icd->vdev->current_norm;
442 __u32 diff = 0xffffffff, tmp; 430 __u32 diff = 0xffffffff, tmp;
443 int size, i; 431 int size, i;
444 432
@@ -465,7 +453,7 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
465} 453}
466 454
467/* 455/*
468 * soc_camera_ops function 456 * subdevice operations
469 */ 457 */
470static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) 458static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
471{ 459{
@@ -507,49 +495,27 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
507 return tw9910_power(client, enable); 495 return tw9910_power(client, enable);
508} 496}
509 497
510static int tw9910_set_bus_param(struct soc_camera_device *icd, 498static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
511 unsigned long flags)
512{ 499{
513 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
514 struct i2c_client *client = v4l2_get_subdevdata(sd); 500 struct i2c_client *client = v4l2_get_subdevdata(sd);
515 u8 val = VSSL_VVALID | HSSL_DVALID; 501 struct tw9910_priv *priv = to_tw9910(client);
516 502
517 /* 503 *norm = priv->norm;
518 * set OUTCTR1
519 *
520 * We use VVALID and DVALID signals to control VSYNC and HSYNC
521 * outputs, in this mode their polarity is inverted.
522 */
523 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
524 val |= HSP_HI;
525 504
526 if (flags & SOCAM_VSYNC_ACTIVE_LOW) 505 return 0;
527 val |= VSP_HI;
528
529 return i2c_smbus_write_byte_data(client, OUTCTR1, val);
530} 506}
531 507
532static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) 508static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
533{ 509{
534 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 510 struct i2c_client *client = v4l2_get_subdevdata(sd);
535 struct tw9910_priv *priv = to_tw9910(client); 511 struct tw9910_priv *priv = to_tw9910(client);
536 struct soc_camera_link *icl = to_soc_camera_link(icd);
537 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
538 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
539 SOCAM_VSYNC_ACTIVE_LOW | SOCAM_HSYNC_ACTIVE_LOW |
540 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
541 512
542 return soc_camera_apply_sensor_flags(icl, flags); 513 if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
543} 514 return -EINVAL;
544
545static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
546{
547 int ret = -EINVAL;
548 515
549 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL)) 516 priv->norm = norm;
550 ret = 0;
551 517
552 return ret; 518 return 0;
553} 519}
554 520
555static int tw9910_g_chip_ident(struct v4l2_subdev *sd, 521static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
@@ -600,19 +566,17 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
600} 566}
601#endif 567#endif
602 568
603static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 569static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
604{ 570{
605 struct v4l2_rect *rect = &a->c;
606 struct i2c_client *client = v4l2_get_subdevdata(sd); 571 struct i2c_client *client = v4l2_get_subdevdata(sd);
607 struct tw9910_priv *priv = to_tw9910(client); 572 struct tw9910_priv *priv = to_tw9910(client);
608 struct soc_camera_device *icd = client->dev.platform_data; 573 int ret = -EINVAL;
609 int ret = -EINVAL; 574 u8 val;
610 u8 val;
611 575
612 /* 576 /*
613 * select suitable norm 577 * select suitable norm
614 */ 578 */
615 priv->scale = tw9910_select_norm(icd, rect->width, rect->height); 579 priv->scale = tw9910_select_norm(priv->norm, *width, *height);
616 if (!priv->scale) 580 if (!priv->scale)
617 goto tw9910_set_fmt_error; 581 goto tw9910_set_fmt_error;
618 582
@@ -670,14 +634,12 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
670 /* 634 /*
671 * set hsync 635 * set hsync
672 */ 636 */
673 ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl); 637 ret = tw9910_set_hsync(client);
674 if (ret < 0) 638 if (ret < 0)
675 goto tw9910_set_fmt_error; 639 goto tw9910_set_fmt_error;
676 640
677 rect->width = priv->scale->width; 641 *width = priv->scale->width;
678 rect->height = priv->scale->height; 642 *height = priv->scale->height;
679 rect->left = 0;
680 rect->top = 0;
681 643
682 return ret; 644 return ret;
683 645
@@ -694,25 +656,15 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
694 struct i2c_client *client = v4l2_get_subdevdata(sd); 656 struct i2c_client *client = v4l2_get_subdevdata(sd);
695 struct tw9910_priv *priv = to_tw9910(client); 657 struct tw9910_priv *priv = to_tw9910(client);
696 658
697 if (!priv->scale) {
698 int ret;
699 struct v4l2_crop crop = {
700 .c = {
701 .left = 0,
702 .top = 0,
703 .width = 640,
704 .height = 480,
705 },
706 };
707 ret = tw9910_s_crop(sd, &crop);
708 if (ret < 0)
709 return ret;
710 }
711
712 a->c.left = 0; 659 a->c.left = 0;
713 a->c.top = 0; 660 a->c.top = 0;
714 a->c.width = priv->scale->width; 661 if (priv->norm & V4L2_STD_NTSC) {
715 a->c.height = priv->scale->height; 662 a->c.width = 640;
663 a->c.height = 480;
664 } else {
665 a->c.width = 768;
666 a->c.height = 576;
667 }
716 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 668 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
717 669
718 return 0; 670 return 0;
@@ -720,14 +672,19 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
720 672
721static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 673static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
722{ 674{
675 struct i2c_client *client = v4l2_get_subdevdata(sd);
676 struct tw9910_priv *priv = to_tw9910(client);
677
723 a->bounds.left = 0; 678 a->bounds.left = 0;
724 a->bounds.top = 0; 679 a->bounds.top = 0;
725 a->bounds.width = 768; 680 if (priv->norm & V4L2_STD_NTSC) {
726 a->bounds.height = 576; 681 a->bounds.width = 640;
727 a->defrect.left = 0; 682 a->bounds.height = 480;
728 a->defrect.top = 0; 683 } else {
729 a->defrect.width = 640; 684 a->bounds.width = 768;
730 a->defrect.height = 480; 685 a->bounds.height = 576;
686 }
687 a->defrect = a->bounds;
731 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 688 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
732 a->pixelaspect.numerator = 1; 689 a->pixelaspect.numerator = 1;
733 a->pixelaspect.denominator = 1; 690 a->pixelaspect.denominator = 1;
@@ -743,15 +700,8 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
743 700
744 if (!priv->scale) { 701 if (!priv->scale) {
745 int ret; 702 int ret;
746 struct v4l2_crop crop = { 703 u32 width = 640, height = 480;
747 .c = { 704 ret = tw9910_set_frame(sd, &width, &height);
748 .left = 0,
749 .top = 0,
750 .width = 640,
751 .height = 480,
752 },
753 };
754 ret = tw9910_s_crop(sd, &crop);
755 if (ret < 0) 705 if (ret < 0)
756 return ret; 706 return ret;
757 } 707 }
@@ -768,17 +718,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
768static int tw9910_s_fmt(struct v4l2_subdev *sd, 718static int tw9910_s_fmt(struct v4l2_subdev *sd,
769 struct v4l2_mbus_framefmt *mf) 719 struct v4l2_mbus_framefmt *mf)
770{ 720{
771 struct i2c_client *client = v4l2_get_subdevdata(sd); 721 u32 width = mf->width, height = mf->height;
772 struct tw9910_priv *priv = to_tw9910(client);
773 /* See tw9910_s_crop() - no proper cropping support */
774 struct v4l2_crop a = {
775 .c = {
776 .left = 0,
777 .top = 0,
778 .width = mf->width,
779 .height = mf->height,
780 },
781 };
782 int ret; 722 int ret;
783 723
784 WARN_ON(mf->field != V4L2_FIELD_ANY && 724 WARN_ON(mf->field != V4L2_FIELD_ANY &&
@@ -792,10 +732,10 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
792 732
793 mf->colorspace = V4L2_COLORSPACE_JPEG; 733 mf->colorspace = V4L2_COLORSPACE_JPEG;
794 734
795 ret = tw9910_s_crop(sd, &a); 735 ret = tw9910_set_frame(sd, &width, &height);
796 if (!ret) { 736 if (!ret) {
797 mf->width = priv->scale->width; 737 mf->width = width;
798 mf->height = priv->scale->height; 738 mf->height = height;
799 } 739 }
800 return ret; 740 return ret;
801} 741}
@@ -804,7 +744,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
804 struct v4l2_mbus_framefmt *mf) 744 struct v4l2_mbus_framefmt *mf)
805{ 745{
806 struct i2c_client *client = v4l2_get_subdevdata(sd); 746 struct i2c_client *client = v4l2_get_subdevdata(sd);
807 struct soc_camera_device *icd = client->dev.platform_data; 747 struct tw9910_priv *priv = to_tw9910(client);
808 const struct tw9910_scale_ctrl *scale; 748 const struct tw9910_scale_ctrl *scale;
809 749
810 if (V4L2_FIELD_ANY == mf->field) { 750 if (V4L2_FIELD_ANY == mf->field) {
@@ -820,7 +760,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
820 /* 760 /*
821 * select suitable norm 761 * select suitable norm
822 */ 762 */
823 scale = tw9910_select_norm(icd, mf->width, mf->height); 763 scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
824 if (!scale) 764 if (!scale)
825 return -EINVAL; 765 return -EINVAL;
826 766
@@ -830,16 +770,11 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
830 return 0; 770 return 0;
831} 771}
832 772
833static int tw9910_video_probe(struct soc_camera_device *icd, 773static int tw9910_video_probe(struct i2c_client *client)
834 struct i2c_client *client)
835{ 774{
836 struct tw9910_priv *priv = to_tw9910(client); 775 struct tw9910_priv *priv = to_tw9910(client);
837 s32 id; 776 s32 id;
838 777
839 /* We must have a parent by now. And it cannot be a wrong one. */
840 BUG_ON(!icd->parent ||
841 to_soc_camera_host(icd->parent)->nr != icd->iface);
842
843 /* 778 /*
844 * tw9910 only use 8 or 16 bit bus width 779 * tw9910 only use 8 or 16 bit bus width
845 */ 780 */
@@ -868,20 +803,15 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
868 dev_info(&client->dev, 803 dev_info(&client->dev,
869 "tw9910 Product ID %0x:%0x\n", id, priv->revision); 804 "tw9910 Product ID %0x:%0x\n", id, priv->revision);
870 805
871 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 806 priv->norm = V4L2_STD_NTSC;
872 icd->vdev->current_norm = V4L2_STD_NTSC;
873 807
874 return 0; 808 return 0;
875} 809}
876 810
877static struct soc_camera_ops tw9910_ops = {
878 .set_bus_param = tw9910_set_bus_param,
879 .query_bus_param = tw9910_query_bus_param,
880};
881
882static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { 811static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
883 .g_chip_ident = tw9910_g_chip_ident, 812 .g_chip_ident = tw9910_g_chip_ident,
884 .s_std = tw9910_s_std, 813 .s_std = tw9910_s_std,
814 .g_std = tw9910_g_std,
885#ifdef CONFIG_VIDEO_ADV_DEBUG 815#ifdef CONFIG_VIDEO_ADV_DEBUG
886 .g_register = tw9910_g_register, 816 .g_register = tw9910_g_register,
887 .s_register = tw9910_s_register, 817 .s_register = tw9910_s_register,
@@ -898,6 +828,45 @@ static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
898 return 0; 828 return 0;
899} 829}
900 830
831static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
832 struct v4l2_mbus_config *cfg)
833{
834 struct i2c_client *client = v4l2_get_subdevdata(sd);
835 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
836
837 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
838 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
839 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
840 V4L2_MBUS_DATA_ACTIVE_HIGH;
841 cfg->type = V4L2_MBUS_PARALLEL;
842 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
843
844 return 0;
845}
846
847static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
848 const struct v4l2_mbus_config *cfg)
849{
850 struct i2c_client *client = v4l2_get_subdevdata(sd);
851 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
852 u8 val = VSSL_VVALID | HSSL_DVALID;
853 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
854
855 /*
856 * set OUTCTR1
857 *
858 * We use VVALID and DVALID signals to control VSYNC and HSYNC
859 * outputs, in this mode their polarity is inverted.
860 */
861 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
862 val |= HSP_HI;
863
864 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
865 val |= VSP_HI;
866
867 return i2c_smbus_write_byte_data(client, OUTCTR1, val);
868}
869
901static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { 870static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
902 .s_stream = tw9910_s_stream, 871 .s_stream = tw9910_s_stream,
903 .g_mbus_fmt = tw9910_g_fmt, 872 .g_mbus_fmt = tw9910_g_fmt,
@@ -905,8 +874,9 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
905 .try_mbus_fmt = tw9910_try_fmt, 874 .try_mbus_fmt = tw9910_try_fmt,
906 .cropcap = tw9910_cropcap, 875 .cropcap = tw9910_cropcap,
907 .g_crop = tw9910_g_crop, 876 .g_crop = tw9910_g_crop,
908 .s_crop = tw9910_s_crop,
909 .enum_mbus_fmt = tw9910_enum_fmt, 877 .enum_mbus_fmt = tw9910_enum_fmt,
878 .g_mbus_config = tw9910_g_mbus_config,
879 .s_mbus_config = tw9910_s_mbus_config,
910}; 880};
911 881
912static struct v4l2_subdev_ops tw9910_subdev_ops = { 882static struct v4l2_subdev_ops tw9910_subdev_ops = {
@@ -922,23 +892,18 @@ static int tw9910_probe(struct i2c_client *client,
922 const struct i2c_device_id *did) 892 const struct i2c_device_id *did)
923 893
924{ 894{
925 struct tw9910_priv *priv; 895 struct tw9910_priv *priv;
926 struct tw9910_video_info *info; 896 struct tw9910_video_info *info;
927 struct soc_camera_device *icd = client->dev.platform_data; 897 struct i2c_adapter *adapter =
928 struct i2c_adapter *adapter =
929 to_i2c_adapter(client->dev.parent); 898 to_i2c_adapter(client->dev.parent);
930 struct soc_camera_link *icl; 899 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
931 int ret; 900 int ret;
932 901
933 if (!icd) { 902 if (!icl || !icl->priv) {
934 dev_err(&client->dev, "TW9910: missing soc-camera data!\n"); 903 dev_err(&client->dev, "TW9910: missing platform data!\n");
935 return -EINVAL; 904 return -EINVAL;
936 } 905 }
937 906
938 icl = to_soc_camera_link(icd);
939 if (!icl || !icl->priv)
940 return -EINVAL;
941
942 info = icl->priv; 907 info = icl->priv;
943 908
944 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 909 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -956,14 +921,9 @@ static int tw9910_probe(struct i2c_client *client,
956 921
957 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); 922 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
958 923
959 icd->ops = &tw9910_ops; 924 ret = tw9910_video_probe(client);
960 icd->iface = icl->bus_id; 925 if (ret)
961
962 ret = tw9910_video_probe(icd, client);
963 if (ret) {
964 icd->ops = NULL;
965 kfree(priv); 926 kfree(priv);
966 }
967 927
968 return ret; 928 return ret;
969} 929}
@@ -971,9 +931,7 @@ static int tw9910_probe(struct i2c_client *client,
971static int tw9910_remove(struct i2c_client *client) 931static int tw9910_remove(struct i2c_client *client)
972{ 932{
973 struct tw9910_priv *priv = to_tw9910(client); 933 struct tw9910_priv *priv = to_tw9910(client);
974 struct soc_camera_device *icd = client->dev.platform_data;
975 934
976 icd->ops = NULL;
977 kfree(priv); 935 kfree(priv);
978 return 0; 936 return 0;
979} 937}
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b70f388..c68531b88279 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,25 @@ struct v4l2_format32 {
159 } fmt; 159 } fmt;
160}; 160};
161 161
162static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) 162/**
163 * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
164 * @index: on return, index of the first created buffer
165 * @count: entry: number of requested buffers,
166 * return: number of created buffers
167 * @memory: buffer memory type
168 * @format: frame format, for which buffers are requested
169 * @reserved: future extensions
170 */
171struct v4l2_create_buffers32 {
172 __u32 index;
173 __u32 count;
174 enum v4l2_memory memory;
175 struct v4l2_format32 format;
176 __u32 reserved[8];
177};
178
179static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
163{ 180{
164 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
165 get_user(kp->type, &up->type))
166 return -EFAULT;
167 switch (kp->type) { 181 switch (kp->type) {
168 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 182 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
169 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 183 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +206,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
192 } 206 }
193} 207}
194 208
195static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) 209static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
210{
211 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
212 get_user(kp->type, &up->type))
213 return -EFAULT;
214 return __get_v4l2_format32(kp, up);
215}
216
217static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
218{
219 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
220 copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
221 return -EFAULT;
222 return __get_v4l2_format32(&kp->format, &up->format);
223}
224
225static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
196{ 226{
197 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
198 put_user(kp->type, &up->type))
199 return -EFAULT;
200 switch (kp->type) { 227 switch (kp->type) {
201 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 228 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
202 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 229 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +252,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
225 } 252 }
226} 253}
227 254
255static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
256{
257 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
258 put_user(kp->type, &up->type))
259 return -EFAULT;
260 return __put_v4l2_format32(kp, up);
261}
262
263static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
264{
265 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
266 copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
267 return -EFAULT;
268 return __put_v4l2_format32(&kp->format, &up->format);
269}
270
228struct v4l2_standard32 { 271struct v4l2_standard32 {
229 __u32 index; 272 __u32 index;
230 __u32 id[2]; /* __u64 would get the alignment wrong */ 273 __u32 id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +745,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
702#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) 745#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
703#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 746#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
704#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32) 747#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32)
748#define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
749#define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
705 750
706#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32) 751#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
707#define VIDIOC_STREAMON32 _IOW ('V', 18, s32) 752#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
@@ -721,6 +766,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
721 struct v4l2_standard v2s; 766 struct v4l2_standard v2s;
722 struct v4l2_ext_controls v2ecs; 767 struct v4l2_ext_controls v2ecs;
723 struct v4l2_event v2ev; 768 struct v4l2_event v2ev;
769 struct v4l2_create_buffers v2crt;
724 unsigned long vx; 770 unsigned long vx;
725 int vi; 771 int vi;
726 } karg; 772 } karg;
@@ -751,6 +797,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
751 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; 797 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
752 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; 798 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
753 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; 799 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
800 case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
801 case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
754 } 802 }
755 803
756 switch (cmd) { 804 switch (cmd) {
@@ -775,6 +823,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
775 compatible_arg = 0; 823 compatible_arg = 0;
776 break; 824 break;
777 825
826 case VIDIOC_CREATE_BUFS:
827 err = get_v4l2_create32(&karg.v2crt, up);
828 compatible_arg = 0;
829 break;
830
831 case VIDIOC_PREPARE_BUF:
778 case VIDIOC_QUERYBUF: 832 case VIDIOC_QUERYBUF:
779 case VIDIOC_QBUF: 833 case VIDIOC_QBUF:
780 case VIDIOC_DQBUF: 834 case VIDIOC_DQBUF:
@@ -860,6 +914,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
860 err = put_v4l2_format32(&karg.v2f, up); 914 err = put_v4l2_format32(&karg.v2f, up);
861 break; 915 break;
862 916
917 case VIDIOC_CREATE_BUFS:
918 err = put_v4l2_create32(&karg.v2crt, up);
919 break;
920
863 case VIDIOC_QUERYBUF: 921 case VIDIOC_QUERYBUF:
864 case VIDIOC_QBUF: 922 case VIDIOC_QBUF:
865 case VIDIOC_DQBUF: 923 case VIDIOC_DQBUF:
@@ -959,6 +1017,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
959 case VIDIOC_DQEVENT32: 1017 case VIDIOC_DQEVENT32:
960 case VIDIOC_SUBSCRIBE_EVENT: 1018 case VIDIOC_SUBSCRIBE_EVENT:
961 case VIDIOC_UNSUBSCRIBE_EVENT: 1019 case VIDIOC_UNSUBSCRIBE_EVENT:
1020 case VIDIOC_CREATE_BUFS32:
1021 case VIDIOC_PREPARE_BUF32:
962 ret = do_video_ioctl(file, cmd, arg); 1022 ret = do_video_ioctl(file, cmd, arg);
963 break; 1023 break;
964 1024
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index fc8666ae408f..5552f8137571 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -210,6 +210,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
210 "Disabled", 210 "Disabled",
211 "50 Hz", 211 "50 Hz",
212 "60 Hz", 212 "60 Hz",
213 "Auto",
213 NULL 214 NULL
214 }; 215 };
215 static const char * const camera_exposure_auto[] = { 216 static const char * const camera_exposure_auto[] = {
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index e6a2c3b302d4..9fc0ae8a526a 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -21,6 +21,7 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/ioctl.h> 22#include <linux/ioctl.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/slab.h>
24#if defined(CONFIG_SPI) 25#if defined(CONFIG_SPI)
25#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
26#endif 27#endif
@@ -193,6 +194,13 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
193} 194}
194EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); 195EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
195 196
197static void v4l2_device_release_subdev_node(struct video_device *vdev)
198{
199 struct v4l2_subdev *sd = video_get_drvdata(vdev);
200 sd->devnode = NULL;
201 kfree(vdev);
202}
203
196int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) 204int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
197{ 205{
198 struct video_device *vdev; 206 struct video_device *vdev;
@@ -206,22 +214,40 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
206 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) 214 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
207 continue; 215 continue;
208 216
209 vdev = &sd->devnode; 217 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
218 if (!vdev) {
219 err = -ENOMEM;
220 goto clean_up;
221 }
222
223 video_set_drvdata(vdev, sd);
210 strlcpy(vdev->name, sd->name, sizeof(vdev->name)); 224 strlcpy(vdev->name, sd->name, sizeof(vdev->name));
211 vdev->v4l2_dev = v4l2_dev; 225 vdev->v4l2_dev = v4l2_dev;
212 vdev->fops = &v4l2_subdev_fops; 226 vdev->fops = &v4l2_subdev_fops;
213 vdev->release = video_device_release_empty; 227 vdev->release = v4l2_device_release_subdev_node;
214 vdev->ctrl_handler = sd->ctrl_handler; 228 vdev->ctrl_handler = sd->ctrl_handler;
215 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1, 229 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
216 sd->owner); 230 sd->owner);
217 if (err < 0) 231 if (err < 0) {
218 return err; 232 kfree(vdev);
233 goto clean_up;
234 }
219#if defined(CONFIG_MEDIA_CONTROLLER) 235#if defined(CONFIG_MEDIA_CONTROLLER)
220 sd->entity.v4l.major = VIDEO_MAJOR; 236 sd->entity.v4l.major = VIDEO_MAJOR;
221 sd->entity.v4l.minor = vdev->minor; 237 sd->entity.v4l.minor = vdev->minor;
222#endif 238#endif
239 sd->devnode = vdev;
223 } 240 }
224 return 0; 241 return 0;
242
243clean_up:
244 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
245 if (!sd->devnode)
246 break;
247 video_unregister_device(sd->devnode);
248 }
249
250 return err;
225} 251}
226EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes); 252EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
227 253
@@ -247,7 +273,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
247 if (v4l2_dev->mdev) 273 if (v4l2_dev->mdev)
248 media_device_unregister_entity(&sd->entity); 274 media_device_unregister_entity(&sd->entity);
249#endif 275#endif
250 video_unregister_device(&sd->devnode); 276 video_unregister_device(sd->devnode);
251 module_put(sd->owner); 277 module_put(sd->owner);
252} 278}
253EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); 279EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 24fd43322150..e1da8fc9dd2f 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
273 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", 273 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
274 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", 274 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
275 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", 275 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
276 [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS",
277 [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF",
276}; 278};
277#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 279#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
278 280
@@ -2104,6 +2106,40 @@ static long __video_do_ioctl(struct file *file,
2104 dbgarg(cmd, "type=0x%8.8x", sub->type); 2106 dbgarg(cmd, "type=0x%8.8x", sub->type);
2105 break; 2107 break;
2106 } 2108 }
2109 case VIDIOC_CREATE_BUFS:
2110 {
2111 struct v4l2_create_buffers *create = arg;
2112
2113 if (!ops->vidioc_create_bufs)
2114 break;
2115 if (ret_prio) {
2116 ret = ret_prio;
2117 break;
2118 }
2119 ret = check_fmt(ops, create->format.type);
2120 if (ret)
2121 break;
2122
2123 ret = ops->vidioc_create_bufs(file, fh, create);
2124
2125 dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
2126 break;
2127 }
2128 case VIDIOC_PREPARE_BUF:
2129 {
2130 struct v4l2_buffer *b = arg;
2131
2132 if (!ops->vidioc_prepare_buf)
2133 break;
2134 ret = check_fmt(ops, b->type);
2135 if (ret)
2136 break;
2137
2138 ret = ops->vidioc_prepare_buf(file, fh, b);
2139
2140 dbgarg(cmd, "index=%d", b->index);
2141 break;
2142 }
2107 default: 2143 default:
2108 if (!ops->vidioc_default) 2144 if (!ops->vidioc_default)
2109 break; 2145 break;
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 3f5c7a38e6e8..979e544388cb 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -38,7 +38,8 @@ module_param(debug, int, 0644);
38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0) 38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
39 39
40#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ 40#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
41 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) 41 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
42 V4L2_BUF_FLAG_PREPARED)
42 43
43/** 44/**
44 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer 45 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -109,13 +110,22 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
109 * __setup_offsets() - setup unique offsets ("cookies") for every plane in 110 * __setup_offsets() - setup unique offsets ("cookies") for every plane in
110 * every buffer on the queue 111 * every buffer on the queue
111 */ 112 */
112static void __setup_offsets(struct vb2_queue *q) 113static void __setup_offsets(struct vb2_queue *q, unsigned int n)
113{ 114{
114 unsigned int buffer, plane; 115 unsigned int buffer, plane;
115 struct vb2_buffer *vb; 116 struct vb2_buffer *vb;
116 unsigned long off = 0; 117 unsigned long off;
117 118
118 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 119 if (q->num_buffers) {
120 struct v4l2_plane *p;
121 vb = q->bufs[q->num_buffers - 1];
122 p = &vb->v4l2_planes[vb->num_planes - 1];
123 off = PAGE_ALIGN(p->m.mem_offset + p->length);
124 } else {
125 off = 0;
126 }
127
128 for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
119 vb = q->bufs[buffer]; 129 vb = q->bufs[buffer];
120 if (!vb) 130 if (!vb)
121 continue; 131 continue;
@@ -161,7 +171,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
161 vb->state = VB2_BUF_STATE_DEQUEUED; 171 vb->state = VB2_BUF_STATE_DEQUEUED;
162 vb->vb2_queue = q; 172 vb->vb2_queue = q;
163 vb->num_planes = num_planes; 173 vb->num_planes = num_planes;
164 vb->v4l2_buf.index = buffer; 174 vb->v4l2_buf.index = q->num_buffers + buffer;
165 vb->v4l2_buf.type = q->type; 175 vb->v4l2_buf.type = q->type;
166 vb->v4l2_buf.memory = memory; 176 vb->v4l2_buf.memory = memory;
167 177
@@ -189,15 +199,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
189 } 199 }
190 } 200 }
191 201
192 q->bufs[buffer] = vb; 202 q->bufs[q->num_buffers + buffer] = vb;
193 } 203 }
194 204
195 q->num_buffers = buffer; 205 __setup_offsets(q, buffer);
196
197 __setup_offsets(q);
198 206
199 dprintk(1, "Allocated %d buffers, %d plane(s) each\n", 207 dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
200 q->num_buffers, num_planes); 208 buffer, num_planes);
201 209
202 return buffer; 210 return buffer;
203} 211}
@@ -205,12 +213,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
205/** 213/**
206 * __vb2_free_mem() - release all video buffer memory for a given queue 214 * __vb2_free_mem() - release all video buffer memory for a given queue
207 */ 215 */
208static void __vb2_free_mem(struct vb2_queue *q) 216static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
209{ 217{
210 unsigned int buffer; 218 unsigned int buffer;
211 struct vb2_buffer *vb; 219 struct vb2_buffer *vb;
212 220
213 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 221 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
222 ++buffer) {
214 vb = q->bufs[buffer]; 223 vb = q->bufs[buffer];
215 if (!vb) 224 if (!vb)
216 continue; 225 continue;
@@ -224,17 +233,18 @@ static void __vb2_free_mem(struct vb2_queue *q)
224} 233}
225 234
226/** 235/**
227 * __vb2_queue_free() - free the queue - video memory and related information 236 * __vb2_queue_free() - free buffers at the end of the queue - video memory and
228 * and return the queue to an uninitialized state. Might be called even if the 237 * related information, if no buffers are left return the queue to an
229 * queue has already been freed. 238 * uninitialized state. Might be called even if the queue has already been freed.
230 */ 239 */
231static void __vb2_queue_free(struct vb2_queue *q) 240static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
232{ 241{
233 unsigned int buffer; 242 unsigned int buffer;
234 243
235 /* Call driver-provided cleanup function for each buffer, if provided */ 244 /* Call driver-provided cleanup function for each buffer, if provided */
236 if (q->ops->buf_cleanup) { 245 if (q->ops->buf_cleanup) {
237 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 246 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
247 ++buffer) {
238 if (NULL == q->bufs[buffer]) 248 if (NULL == q->bufs[buffer])
239 continue; 249 continue;
240 q->ops->buf_cleanup(q->bufs[buffer]); 250 q->ops->buf_cleanup(q->bufs[buffer]);
@@ -242,23 +252,25 @@ static void __vb2_queue_free(struct vb2_queue *q)
242 } 252 }
243 253
244 /* Release video buffer memory */ 254 /* Release video buffer memory */
245 __vb2_free_mem(q); 255 __vb2_free_mem(q, buffers);
246 256
247 /* Free videobuf buffers */ 257 /* Free videobuf buffers */
248 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 258 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
259 ++buffer) {
249 kfree(q->bufs[buffer]); 260 kfree(q->bufs[buffer]);
250 q->bufs[buffer] = NULL; 261 q->bufs[buffer] = NULL;
251 } 262 }
252 263
253 q->num_buffers = 0; 264 q->num_buffers -= buffers;
254 q->memory = 0; 265 if (!q->num_buffers)
266 q->memory = 0;
255} 267}
256 268
257/** 269/**
258 * __verify_planes_array() - verify that the planes array passed in struct 270 * __verify_planes_array() - verify that the planes array passed in struct
259 * v4l2_buffer from userspace can be safely used 271 * v4l2_buffer from userspace can be safely used
260 */ 272 */
261static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b) 273static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
262{ 274{
263 /* Is memory for copying plane information present? */ 275 /* Is memory for copying plane information present? */
264 if (NULL == b->m.planes) { 276 if (NULL == b->m.planes) {
@@ -318,7 +330,7 @@ static bool __buffers_in_use(struct vb2_queue *q)
318static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) 330static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
319{ 331{
320 struct vb2_queue *q = vb->vb2_queue; 332 struct vb2_queue *q = vb->vb2_queue;
321 int ret = 0; 333 int ret;
322 334
323 /* Copy back data such as timestamp, flags, input, etc. */ 335 /* Copy back data such as timestamp, flags, input, etc. */
324 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); 336 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
@@ -365,6 +377,9 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
365 case VB2_BUF_STATE_DONE: 377 case VB2_BUF_STATE_DONE:
366 b->flags |= V4L2_BUF_FLAG_DONE; 378 b->flags |= V4L2_BUF_FLAG_DONE;
367 break; 379 break;
380 case VB2_BUF_STATE_PREPARED:
381 b->flags |= V4L2_BUF_FLAG_PREPARED;
382 break;
368 case VB2_BUF_STATE_DEQUEUED: 383 case VB2_BUF_STATE_DEQUEUED:
369 /* nothing */ 384 /* nothing */
370 break; 385 break;
@@ -373,7 +388,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
373 if (__buffer_in_use(q, vb)) 388 if (__buffer_in_use(q, vb))
374 b->flags |= V4L2_BUF_FLAG_MAPPED; 389 b->flags |= V4L2_BUF_FLAG_MAPPED;
375 390
376 return ret; 391 return 0;
377} 392}
378 393
379/** 394/**
@@ -459,7 +474,7 @@ static int __verify_mmap_ops(struct vb2_queue *q)
459 */ 474 */
460int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) 475int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
461{ 476{
462 unsigned int num_buffers, num_planes; 477 unsigned int num_buffers, allocated_buffers, num_planes = 0;
463 int ret = 0; 478 int ret = 0;
464 479
465 if (q->fileio) { 480 if (q->fileio) {
@@ -507,7 +522,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
507 return -EBUSY; 522 return -EBUSY;
508 } 523 }
509 524
510 __vb2_queue_free(q); 525 __vb2_queue_free(q, q->num_buffers);
511 526
512 /* 527 /*
513 * In case of REQBUFS(0) return immediately without calling 528 * In case of REQBUFS(0) return immediately without calling
@@ -529,7 +544,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
529 * Ask the driver how many buffers and planes per buffer it requires. 544 * Ask the driver how many buffers and planes per buffer it requires.
530 * Driver also sets the size and allocator context for each plane. 545 * Driver also sets the size and allocator context for each plane.
531 */ 546 */
532 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 547 ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
533 q->plane_sizes, q->alloc_ctx); 548 q->plane_sizes, q->alloc_ctx);
534 if (ret) 549 if (ret)
535 return ret; 550 return ret;
@@ -541,44 +556,168 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
541 return -ENOMEM; 556 return -ENOMEM;
542 } 557 }
543 558
559 allocated_buffers = ret;
560
544 /* 561 /*
545 * Check if driver can handle the allocated number of buffers. 562 * Check if driver can handle the allocated number of buffers.
546 */ 563 */
547 if (ret < num_buffers) { 564 if (allocated_buffers < num_buffers) {
548 unsigned int orig_num_buffers; 565 num_buffers = allocated_buffers;
549 566
550 orig_num_buffers = num_buffers = ret; 567 ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
551 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 568 &num_planes, q->plane_sizes, q->alloc_ctx);
552 q->plane_sizes, q->alloc_ctx);
553 if (ret)
554 goto free_mem;
555 569
556 if (orig_num_buffers < num_buffers) { 570 if (!ret && allocated_buffers < num_buffers)
557 ret = -ENOMEM; 571 ret = -ENOMEM;
558 goto free_mem;
559 }
560 572
561 /* 573 /*
562 * Ok, driver accepted smaller number of buffers. 574 * Either the driver has accepted a smaller number of buffers,
575 * or .queue_setup() returned an error
563 */ 576 */
564 ret = num_buffers; 577 }
578
579 q->num_buffers = allocated_buffers;
580
581 if (ret < 0) {
582 __vb2_queue_free(q, allocated_buffers);
583 return ret;
565 } 584 }
566 585
567 /* 586 /*
568 * Return the number of successfully allocated buffers 587 * Return the number of successfully allocated buffers
569 * to the userspace. 588 * to the userspace.
570 */ 589 */
571 req->count = ret; 590 req->count = allocated_buffers;
572 591
573 return 0; 592 return 0;
574
575free_mem:
576 __vb2_queue_free(q);
577 return ret;
578} 593}
579EXPORT_SYMBOL_GPL(vb2_reqbufs); 594EXPORT_SYMBOL_GPL(vb2_reqbufs);
580 595
581/** 596/**
597 * vb2_create_bufs() - Allocate buffers and any required auxiliary structs
598 * @q: videobuf2 queue
599 * @create: creation parameters, passed from userspace to vidioc_create_bufs
600 * handler in driver
601 *
602 * Should be called from vidioc_create_bufs ioctl handler of a driver.
603 * This function:
604 * 1) verifies parameter sanity
605 * 2) calls the .queue_setup() queue operation
606 * 3) performs any necessary memory allocations
607 *
608 * The return values from this function are intended to be directly returned
609 * from vidioc_create_bufs handler in driver.
610 */
611int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
612{
613 unsigned int num_planes = 0, num_buffers, allocated_buffers;
614 int ret = 0;
615
616 if (q->fileio) {
617 dprintk(1, "%s(): file io in progress\n", __func__);
618 return -EBUSY;
619 }
620
621 if (create->memory != V4L2_MEMORY_MMAP
622 && create->memory != V4L2_MEMORY_USERPTR) {
623 dprintk(1, "%s(): unsupported memory type\n", __func__);
624 return -EINVAL;
625 }
626
627 if (create->format.type != q->type) {
628 dprintk(1, "%s(): requested type is incorrect\n", __func__);
629 return -EINVAL;
630 }
631
632 /*
633 * Make sure all the required memory ops for given memory type
634 * are available.
635 */
636 if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
637 dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__);
638 return -EINVAL;
639 }
640
641 if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
642 dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__);
643 return -EINVAL;
644 }
645
646 if (q->num_buffers == VIDEO_MAX_FRAME) {
647 dprintk(1, "%s(): maximum number of buffers already allocated\n",
648 __func__);
649 return -ENOBUFS;
650 }
651
652 create->index = q->num_buffers;
653
654 if (!q->num_buffers) {
655 memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
656 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
657 q->memory = create->memory;
658 }
659
660 num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
661
662 /*
663 * Ask the driver, whether the requested number of buffers, planes per
664 * buffer and their sizes are acceptable
665 */
666 ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
667 &num_planes, q->plane_sizes, q->alloc_ctx);
668 if (ret)
669 return ret;
670
671 /* Finally, allocate buffers and video memory */
672 ret = __vb2_queue_alloc(q, create->memory, num_buffers,
673 num_planes);
674 if (ret < 0) {
675 dprintk(1, "Memory allocation failed with error: %d\n", ret);
676 return ret;
677 }
678
679 allocated_buffers = ret;
680
681 /*
682 * Check if driver can handle the so far allocated number of buffers.
683 */
684 if (ret < num_buffers) {
685 num_buffers = ret;
686
687 /*
688 * q->num_buffers contains the total number of buffers, that the
689 * queue driver has set up
690 */
691 ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
692 &num_planes, q->plane_sizes, q->alloc_ctx);
693
694 if (!ret && allocated_buffers < num_buffers)
695 ret = -ENOMEM;
696
697 /*
698 * Either the driver has accepted a smaller number of buffers,
699 * or .queue_setup() returned an error
700 */
701 }
702
703 q->num_buffers += allocated_buffers;
704
705 if (ret < 0) {
706 __vb2_queue_free(q, allocated_buffers);
707 return ret;
708 }
709
710 /*
711 * Return the number of successfully allocated buffers
712 * to the userspace.
713 */
714 create->count = allocated_buffers;
715
716 return 0;
717}
718EXPORT_SYMBOL_GPL(vb2_create_bufs);
719
720/**
582 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane 721 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
583 * @vb: vb2_buffer to which the plane in question belongs to 722 * @vb: vb2_buffer to which the plane in question belongs to
584 * @plane_no: plane number for which the address is to be returned 723 * @plane_no: plane number for which the address is to be returned
@@ -662,7 +801,7 @@ EXPORT_SYMBOL_GPL(vb2_buffer_done);
662 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in 801 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
663 * a v4l2_buffer by the userspace 802 * a v4l2_buffer by the userspace
664 */ 803 */
665static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, 804static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
666 struct v4l2_plane *v4l2_planes) 805 struct v4l2_plane *v4l2_planes)
667{ 806{
668 unsigned int plane; 807 unsigned int plane;
@@ -726,7 +865,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
726/** 865/**
727 * __qbuf_userptr() - handle qbuf of a USERPTR buffer 866 * __qbuf_userptr() - handle qbuf of a USERPTR buffer
728 */ 867 */
729static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b) 868static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
730{ 869{
731 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 870 struct v4l2_plane planes[VIDEO_MAX_PLANES];
732 struct vb2_queue *q = vb->vb2_queue; 871 struct vb2_queue *q = vb->vb2_queue;
@@ -815,7 +954,7 @@ err:
815/** 954/**
816 * __qbuf_mmap() - handle qbuf of an MMAP buffer 955 * __qbuf_mmap() - handle qbuf of an MMAP buffer
817 */ 956 */
818static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b) 957static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
819{ 958{
820 return __fill_vb2_buffer(vb, b, vb->v4l2_planes); 959 return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
821} 960}
@@ -832,6 +971,95 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
832 q->ops->buf_queue(vb); 971 q->ops->buf_queue(vb);
833} 972}
834 973
974static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
975{
976 struct vb2_queue *q = vb->vb2_queue;
977 int ret;
978
979 switch (q->memory) {
980 case V4L2_MEMORY_MMAP:
981 ret = __qbuf_mmap(vb, b);
982 break;
983 case V4L2_MEMORY_USERPTR:
984 ret = __qbuf_userptr(vb, b);
985 break;
986 default:
987 WARN(1, "Invalid queue type\n");
988 ret = -EINVAL;
989 }
990
991 if (!ret)
992 ret = call_qop(q, buf_prepare, vb);
993 if (ret)
994 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
995 else
996 vb->state = VB2_BUF_STATE_PREPARED;
997
998 return ret;
999}
1000
1001/**
1002 * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
1003 * @q: videobuf2 queue
1004 * @b: buffer structure passed from userspace to vidioc_prepare_buf
1005 * handler in driver
1006 *
1007 * Should be called from vidioc_prepare_buf ioctl handler of a driver.
1008 * This function:
1009 * 1) verifies the passed buffer,
1010 * 2) calls buf_prepare callback in the driver (if provided), in which
1011 * driver-specific buffer initialization can be performed,
1012 *
1013 * The return values from this function are intended to be directly returned
1014 * from vidioc_prepare_buf handler in driver.
1015 */
1016int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
1017{
1018 struct vb2_buffer *vb;
1019 int ret;
1020
1021 if (q->fileio) {
1022 dprintk(1, "%s(): file io in progress\n", __func__);
1023 return -EBUSY;
1024 }
1025
1026 if (b->type != q->type) {
1027 dprintk(1, "%s(): invalid buffer type\n", __func__);
1028 return -EINVAL;
1029 }
1030
1031 if (b->index >= q->num_buffers) {
1032 dprintk(1, "%s(): buffer index out of range\n", __func__);
1033 return -EINVAL;
1034 }
1035
1036 vb = q->bufs[b->index];
1037 if (NULL == vb) {
1038 /* Should never happen */
1039 dprintk(1, "%s(): buffer is NULL\n", __func__);
1040 return -EINVAL;
1041 }
1042
1043 if (b->memory != q->memory) {
1044 dprintk(1, "%s(): invalid memory type\n", __func__);
1045 return -EINVAL;
1046 }
1047
1048 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1049 dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
1050 return -EINVAL;
1051 }
1052
1053 ret = __buf_prepare(vb, b);
1054 if (ret < 0)
1055 return ret;
1056
1057 __fill_v4l2_buffer(vb, b);
1058
1059 return 0;
1060}
1061EXPORT_SYMBOL_GPL(vb2_prepare_buf);
1062
835/** 1063/**
836 * vb2_qbuf() - Queue a buffer from userspace 1064 * vb2_qbuf() - Queue a buffer from userspace
837 * @q: videobuf2 queue 1065 * @q: videobuf2 queue
@@ -841,8 +1069,8 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
841 * Should be called from vidioc_qbuf ioctl handler of a driver. 1069 * Should be called from vidioc_qbuf ioctl handler of a driver.
842 * This function: 1070 * This function:
843 * 1) verifies the passed buffer, 1071 * 1) verifies the passed buffer,
844 * 2) calls buf_prepare callback in the driver (if provided), in which 1072 * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
845 * driver-specific buffer initialization can be performed, 1073 * which driver-specific buffer initialization can be performed,
846 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue 1074 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
847 * callback for processing. 1075 * callback for processing.
848 * 1076 *
@@ -852,7 +1080,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
852int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) 1080int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
853{ 1081{
854 struct vb2_buffer *vb; 1082 struct vb2_buffer *vb;
855 int ret = 0; 1083 int ret;
856 1084
857 if (q->fileio) { 1085 if (q->fileio) {
858 dprintk(1, "qbuf: file io in progress\n"); 1086 dprintk(1, "qbuf: file io in progress\n");
@@ -881,29 +1109,18 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
881 return -EINVAL; 1109 return -EINVAL;
882 } 1110 }
883 1111
884 if (vb->state != VB2_BUF_STATE_DEQUEUED) { 1112 switch (vb->state) {
1113 case VB2_BUF_STATE_DEQUEUED:
1114 ret = __buf_prepare(vb, b);
1115 if (ret)
1116 return ret;
1117 case VB2_BUF_STATE_PREPARED:
1118 break;
1119 default:
885 dprintk(1, "qbuf: buffer already in use\n"); 1120 dprintk(1, "qbuf: buffer already in use\n");
886 return -EINVAL; 1121 return -EINVAL;
887 } 1122 }
888 1123
889 if (q->memory == V4L2_MEMORY_MMAP)
890 ret = __qbuf_mmap(vb, b);
891 else if (q->memory == V4L2_MEMORY_USERPTR)
892 ret = __qbuf_userptr(vb, b);
893 else {
894 WARN(1, "Invalid queue type\n");
895 return -EINVAL;
896 }
897
898 if (ret)
899 return ret;
900
901 ret = call_qop(q, buf_prepare, vb);
902 if (ret) {
903 dprintk(1, "qbuf: buffer preparation failed\n");
904 return ret;
905 }
906
907 /* 1124 /*
908 * Add to the queued buffers list, a buffer will stay on it until 1125 * Add to the queued buffers list, a buffer will stay on it until
909 * dequeued in dqbuf. 1126 * dequeued in dqbuf.
@@ -918,6 +1135,9 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
918 if (q->streaming) 1135 if (q->streaming)
919 __enqueue_in_driver(vb); 1136 __enqueue_in_driver(vb);
920 1137
1138 /* Fill buffer information for the userspace */
1139 __fill_v4l2_buffer(vb, b);
1140
921 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); 1141 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
922 return 0; 1142 return 0;
923} 1143}
@@ -1347,6 +1567,37 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
1347} 1567}
1348EXPORT_SYMBOL_GPL(vb2_mmap); 1568EXPORT_SYMBOL_GPL(vb2_mmap);
1349 1569
1570#ifndef CONFIG_MMU
1571unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
1572 unsigned long addr,
1573 unsigned long len,
1574 unsigned long pgoff,
1575 unsigned long flags)
1576{
1577 unsigned long off = pgoff << PAGE_SHIFT;
1578 struct vb2_buffer *vb;
1579 unsigned int buffer, plane;
1580 int ret;
1581
1582 if (q->memory != V4L2_MEMORY_MMAP) {
1583 dprintk(1, "Queue is not currently set up for mmap\n");
1584 return -EINVAL;
1585 }
1586
1587 /*
1588 * Find the plane corresponding to the offset passed by userspace.
1589 */
1590 ret = __find_plane_by_offset(q, off, &buffer, &plane);
1591 if (ret)
1592 return ret;
1593
1594 vb = q->bufs[buffer];
1595
1596 return (unsigned long)vb2_plane_vaddr(vb, plane);
1597}
1598EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
1599#endif
1600
1350static int __vb2_init_fileio(struct vb2_queue *q, int read); 1601static int __vb2_init_fileio(struct vb2_queue *q, int read);
1351static int __vb2_cleanup_fileio(struct vb2_queue *q); 1602static int __vb2_cleanup_fileio(struct vb2_queue *q);
1352 1603
@@ -1464,7 +1715,7 @@ void vb2_queue_release(struct vb2_queue *q)
1464{ 1715{
1465 __vb2_cleanup_fileio(q); 1716 __vb2_cleanup_fileio(q);
1466 __vb2_queue_cancel(q); 1717 __vb2_queue_cancel(q);
1467 __vb2_queue_free(q); 1718 __vb2_queue_free(q, q->num_buffers);
1468} 1719}
1469EXPORT_SYMBOL_GPL(vb2_queue_release); 1720EXPORT_SYMBOL_GPL(vb2_queue_release);
1470 1721
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 7cf94c09d99a..7d754fbcccbf 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -650,9 +650,9 @@ static void vivi_stop_generating(struct vivi_dev *dev)
650/* ------------------------------------------------------------------ 650/* ------------------------------------------------------------------
651 Videobuf operations 651 Videobuf operations
652 ------------------------------------------------------------------*/ 652 ------------------------------------------------------------------*/
653static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 653static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
654 unsigned int *nplanes, unsigned int sizes[], 654 unsigned int *nbuffers, unsigned int *nplanes,
655 void *alloc_ctxs[]) 655 unsigned int sizes[], void *alloc_ctxs[])
656{ 656{
657 struct vivi_dev *dev = vb2_get_drv_priv(vq); 657 struct vivi_dev *dev = vb2_get_drv_priv(vq);
658 unsigned long size; 658 unsigned long size;
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index d2856b6b2a62..720f99334a7f 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -913,9 +913,9 @@ request_done:
913} 913}
914 914
915static void s3cmci_dma_setup(struct s3cmci_host *host, 915static void s3cmci_dma_setup(struct s3cmci_host *host,
916 enum s3c2410_dmasrc source) 916 enum dma_data_direction source)
917{ 917{
918 static enum s3c2410_dmasrc last_source = -1; 918 static enum dma_data_direction last_source = -1;
919 static int setup_ok; 919 static int setup_ok;
920 920
921 if (last_source == source) 921 if (last_source == source)
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
1087 1087
1088 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); 1088 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
1089 1089
1090 s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW); 1090 s3cmci_dma_setup(host, rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
1091 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); 1091 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
1092 1092
1093 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 1093 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index ddb33cfd3543..7bf1e2015784 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -1674,6 +1674,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
1674 int result; 1674 int result;
1675 1675
1676 pr_debug("%s: called\n", __func__); 1676 pr_debug("%s: called\n", __func__);
1677
1678 udbg_shutdown_ps3gelic();
1679
1677 result = ps3_open_hv_device(dev); 1680 result = ps3_open_hv_device(dev);
1678 1681
1679 if (result) { 1682 if (result) {
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
index d3fadfbc3bcc..a93df6ac1909 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h
@@ -359,6 +359,12 @@ static inline void *port_priv(struct gelic_port *port)
359 return port->priv; 359 return port->priv;
360} 360}
361 361
362#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
363extern void udbg_shutdown_ps3gelic(void);
364#else
365static inline void udbg_shutdown_ps3gelic(void) {}
366#endif
367
362extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask); 368extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
363/* shared netdev ops */ 369/* shared netdev ops */
364extern void gelic_card_up(struct gelic_card *card); 370extern void gelic_card_up(struct gelic_card *card);
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index aeec35bc3789..fd85fa298e0f 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -681,9 +681,14 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
681 if (p != NULL && l > 0) 681 if (p != NULL && l > 0)
682 strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); 682 strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
683 683
684 /*
685 * CONFIG_CMDLINE is meant to be a default in case nothing else
686 * managed to set the command line, unless CONFIG_CMDLINE_FORCE
687 * is set in which case we override whatever was found earlier.
688 */
684#ifdef CONFIG_CMDLINE 689#ifdef CONFIG_CMDLINE
685#ifndef CONFIG_CMDLINE_FORCE 690#ifndef CONFIG_CMDLINE_FORCE
686 if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) 691 if (!((char *)data)[0])
687#endif 692#endif
688 strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); 693 strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
689#endif /* CONFIG_CMDLINE */ 694#endif /* CONFIG_CMDLINE */
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index ed5a6d3c26aa..cbd5d701c7e0 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -310,18 +310,21 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
310 struct device_node *np) 310 struct device_node *np)
311{ 311{
312 struct resource res; 312 struct resource res;
313 if (lookup) { 313
314 for(; lookup->name != NULL; lookup++) { 314 if (!lookup)
315 if (!of_device_is_compatible(np, lookup->compatible)) 315 return NULL;
316 continue; 316
317 if (of_address_to_resource(np, 0, &res)) 317 for(; lookup->name != NULL; lookup++) {
318 continue; 318 if (!of_device_is_compatible(np, lookup->compatible))
319 if (res.start != lookup->phys_addr) 319 continue;
320 continue; 320 if (of_address_to_resource(np, 0, &res))
321 pr_debug("%s: devname=%s\n", np->full_name, lookup->name); 321 continue;
322 return lookup; 322 if (res.start != lookup->phys_addr)
323 } 323 continue;
324 pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
325 return lookup;
324 } 326 }
327
325 return NULL; 328 return NULL;
326} 329}
327 330
@@ -329,8 +332,9 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
329 * of_platform_bus_create() - Create a device for a node and its children. 332 * of_platform_bus_create() - Create a device for a node and its children.
330 * @bus: device node of the bus to instantiate 333 * @bus: device node of the bus to instantiate
331 * @matches: match table for bus nodes 334 * @matches: match table for bus nodes
332 * disallow recursive creation of child buses 335 * @lookup: auxdata table for matching id and platform_data with device nodes
333 * @parent: parent for new device, or NULL for top level. 336 * @parent: parent for new device, or NULL for top level.
337 * @strict: require compatible property
334 * 338 *
335 * Creates a platform_device for the provided device_node, and optionally 339 * Creates a platform_device for the provided device_node, and optionally
336 * recursively create devices for all the child nodes. 340 * recursively create devices for all the child nodes.
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 2c540542b5af..a87e2728b2c3 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -231,6 +231,7 @@ void pxa2xx_configure_sockets(struct device *dev)
231 231
232 __raw_writel(mecr, MECR); 232 __raw_writel(mecr, MECR);
233} 233}
234EXPORT_SYMBOL(pxa2xx_configure_sockets);
234 235
235static const char *skt_names[] = { 236static const char *skt_names[] = {
236 "PCMCIA socket 0", 237 "PCMCIA socket 0",
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
index 4f09506ad8d4..6e7dcfd22ede 100644
--- a/drivers/pcmcia/pxa2xx_cm_x2xx.c
+++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c
@@ -12,9 +12,8 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14 14
15#include <asm/system.h>
16#include <asm/mach-types.h> 15#include <asm/mach-types.h>
17#include <mach/system.h> 16#include <mach/hardware.h>
18 17
19int cmx255_pcmcia_init(void); 18int cmx255_pcmcia_init(void);
20int cmx270_pcmcia_init(void); 19int cmx270_pcmcia_init(void);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 9b43ae94beba..a5a55da2a1ac 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -27,7 +27,7 @@
27 27
28static int dcssblk_open(struct block_device *bdev, fmode_t mode); 28static int dcssblk_open(struct block_device *bdev, fmode_t mode);
29static int dcssblk_release(struct gendisk *disk, fmode_t mode); 29static int dcssblk_release(struct gendisk *disk, fmode_t mode);
30static int dcssblk_make_request(struct request_queue *q, struct bio *bio); 30static void dcssblk_make_request(struct request_queue *q, struct bio *bio);
31static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum, 31static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
32 void **kaddr, unsigned long *pfn); 32 void **kaddr, unsigned long *pfn);
33 33
@@ -814,7 +814,7 @@ out:
814 return rc; 814 return rc;
815} 815}
816 816
817static int 817static void
818dcssblk_make_request(struct request_queue *q, struct bio *bio) 818dcssblk_make_request(struct request_queue *q, struct bio *bio)
819{ 819{
820 struct dcssblk_dev_info *dev_info; 820 struct dcssblk_dev_info *dev_info;
@@ -871,10 +871,9 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
871 bytes_done += bvec->bv_len; 871 bytes_done += bvec->bv_len;
872 } 872 }
873 bio_endio(bio, 0); 873 bio_endio(bio, 0);
874 return 0; 874 return;
875fail: 875fail:
876 bio_io_error(bio); 876 bio_io_error(bio);
877 return 0;
878} 877}
879 878
880static int 879static int
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 1f6a4d894e73..98f3e4ade924 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -181,7 +181,7 @@ static unsigned long xpram_highest_page_index(void)
181/* 181/*
182 * Block device make request function. 182 * Block device make request function.
183 */ 183 */
184static int xpram_make_request(struct request_queue *q, struct bio *bio) 184static void xpram_make_request(struct request_queue *q, struct bio *bio)
185{ 185{
186 xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data; 186 xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data;
187 struct bio_vec *bvec; 187 struct bio_vec *bvec;
@@ -221,10 +221,9 @@ static int xpram_make_request(struct request_queue *q, struct bio *bio)
221 } 221 }
222 set_bit(BIO_UPTODATE, &bio->bi_flags); 222 set_bit(BIO_UPTODATE, &bio->bi_flags);
223 bio_endio(bio, 0); 223 bio_endio(bio, 0);
224 return 0; 224 return;
225fail: 225fail:
226 bio_io_error(bio); 226 bio_io_error(bio);
227 return 0;
228} 227}
229 228
230static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo) 229static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo)
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 63de1c7cd0cb..049ea907e04a 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -62,7 +62,7 @@
62#include "bnx2fc_constants.h" 62#include "bnx2fc_constants.h"
63 63
64#define BNX2FC_NAME "bnx2fc" 64#define BNX2FC_NAME "bnx2fc"
65#define BNX2FC_VERSION "1.0.8" 65#define BNX2FC_VERSION "1.0.9"
66 66
67#define PFX "bnx2fc: " 67#define PFX "bnx2fc: "
68 68
@@ -145,6 +145,9 @@
145#define REC_RETRY_COUNT 1 145#define REC_RETRY_COUNT 1
146#define BNX2FC_NUM_ERR_BITS 63 146#define BNX2FC_NUM_ERR_BITS 63
147 147
148#define BNX2FC_RELOGIN_WAIT_TIME 200
149#define BNX2FC_RELOGIN_WAIT_CNT 10
150
148/* bnx2fc driver uses only one instance of fcoe_percpu_s */ 151/* bnx2fc driver uses only one instance of fcoe_percpu_s */
149extern struct fcoe_percpu_s bnx2fc_global; 152extern struct fcoe_percpu_s bnx2fc_global;
150 153
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c
index fd382fe33f6e..ce0ce3e32f33 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -268,17 +268,6 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
268 268
269 orig_io_req = cb_arg->aborted_io_req; 269 orig_io_req = cb_arg->aborted_io_req;
270 srr_req = cb_arg->io_req; 270 srr_req = cb_arg->io_req;
271 if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
272 BNX2FC_IO_DBG(srr_req, "srr_compl: xid - 0x%x completed",
273 orig_io_req->xid);
274 goto srr_compl_done;
275 }
276 if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
277 BNX2FC_IO_DBG(srr_req, "rec abts in prog "
278 "orig_io - 0x%x\n",
279 orig_io_req->xid);
280 goto srr_compl_done;
281 }
282 if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) { 271 if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) {
283 /* SRR timedout */ 272 /* SRR timedout */
284 BNX2FC_IO_DBG(srr_req, "srr timed out, abort " 273 BNX2FC_IO_DBG(srr_req, "srr timed out, abort "
@@ -290,6 +279,12 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
290 "failed. issue cleanup\n"); 279 "failed. issue cleanup\n");
291 bnx2fc_initiate_cleanup(srr_req); 280 bnx2fc_initiate_cleanup(srr_req);
292 } 281 }
282 if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
283 test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
284 BNX2FC_IO_DBG(srr_req, "srr_compl:xid 0x%x flags = %lx",
285 orig_io_req->xid, orig_io_req->req_flags);
286 goto srr_compl_done;
287 }
293 orig_io_req->srr_retry++; 288 orig_io_req->srr_retry++;
294 if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) { 289 if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
295 struct bnx2fc_rport *tgt = orig_io_req->tgt; 290 struct bnx2fc_rport *tgt = orig_io_req->tgt;
@@ -311,6 +306,12 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
311 } 306 }
312 goto srr_compl_done; 307 goto srr_compl_done;
313 } 308 }
309 if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
310 test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
311 BNX2FC_IO_DBG(srr_req, "srr_compl:xid - 0x%x flags = %lx",
312 orig_io_req->xid, orig_io_req->req_flags);
313 goto srr_compl_done;
314 }
314 mp_req = &(srr_req->mp_req); 315 mp_req = &(srr_req->mp_req);
315 fc_hdr = &(mp_req->resp_fc_hdr); 316 fc_hdr = &(mp_req->resp_fc_hdr);
316 resp_len = mp_req->resp_len; 317 resp_len = mp_req->resp_len;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 85bcc4b55965..8c6156a10d90 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
22 22
23#define DRV_MODULE_NAME "bnx2fc" 23#define DRV_MODULE_NAME "bnx2fc"
24#define DRV_MODULE_VERSION BNX2FC_VERSION 24#define DRV_MODULE_VERSION BNX2FC_VERSION
25#define DRV_MODULE_RELDATE "Oct 02, 2011" 25#define DRV_MODULE_RELDATE "Oct 21, 2011"
26 26
27 27
28static char version[] __devinitdata = 28static char version[] __devinitdata =
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 0c64d184d731..84a78af83f90 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1103,7 +1103,10 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
1103 struct fc_rport_libfc_priv *rp = rport->dd_data; 1103 struct fc_rport_libfc_priv *rp = rport->dd_data;
1104 struct bnx2fc_cmd *io_req; 1104 struct bnx2fc_cmd *io_req;
1105 struct fc_lport *lport; 1105 struct fc_lport *lport;
1106 struct fc_rport_priv *rdata;
1106 struct bnx2fc_rport *tgt; 1107 struct bnx2fc_rport *tgt;
1108 int logo_issued;
1109 int wait_cnt = 0;
1107 int rc = FAILED; 1110 int rc = FAILED;
1108 1111
1109 1112
@@ -1192,8 +1195,40 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
1192 } else { 1195 } else {
1193 printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) " 1196 printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
1194 "already in abts processing\n", io_req->xid); 1197 "already in abts processing\n", io_req->xid);
1198 if (cancel_delayed_work(&io_req->timeout_work))
1199 kref_put(&io_req->refcount,
1200 bnx2fc_cmd_release); /* drop timer hold */
1201 bnx2fc_initiate_cleanup(io_req);
1202
1203 spin_unlock_bh(&tgt->tgt_lock);
1204
1205 wait_for_completion(&io_req->tm_done);
1206
1207 spin_lock_bh(&tgt->tgt_lock);
1208 io_req->wait_for_comp = 0;
1209 rdata = io_req->tgt->rdata;
1210 logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
1211 &tgt->flags);
1195 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1212 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1196 spin_unlock_bh(&tgt->tgt_lock); 1213 spin_unlock_bh(&tgt->tgt_lock);
1214
1215 if (!logo_issued) {
1216 BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
1217 tgt->flags);
1218 mutex_lock(&lport->disc.disc_mutex);
1219 lport->tt.rport_logoff(rdata);
1220 mutex_unlock(&lport->disc.disc_mutex);
1221 do {
1222 msleep(BNX2FC_RELOGIN_WAIT_TIME);
1223 /*
1224 * If session not recovered, let SCSI-ml
1225 * escalate error recovery.
1226 */
1227 if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT)
1228 return FAILED;
1229 } while (!test_bit(BNX2FC_FLAG_SESSION_READY,
1230 &tgt->flags));
1231 }
1197 return SUCCESS; 1232 return SUCCESS;
1198 } 1233 }
1199 if (rc == FAILED) { 1234 if (rc == FAILED) {
@@ -1275,6 +1310,8 @@ void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req,
1275 io_req->refcount.refcount.counter, io_req->cmd_type); 1310 io_req->refcount.refcount.counter, io_req->cmd_type);
1276 bnx2fc_scsi_done(io_req, DID_ERROR); 1311 bnx2fc_scsi_done(io_req, DID_ERROR);
1277 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1312 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1313 if (io_req->wait_for_comp)
1314 complete(&io_req->tm_done);
1278} 1315}
1279 1316
1280void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, 1317void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index 7c05fd9dccfd..339ea23a8675 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -441,7 +441,15 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
441 441
442 spin_lock_irqsave(q->queue_lock, flags); 442 spin_lock_irqsave(q->queue_lock, flags);
443 sdev = q->queuedata; 443 sdev = q->queuedata;
444 if (sdev && sdev->scsi_dh_data) 444 if (!sdev) {
445 spin_unlock_irqrestore(q->queue_lock, flags);
446 err = SCSI_DH_NOSYS;
447 if (fn)
448 fn(data, err);
449 return err;
450 }
451
452 if (sdev->scsi_dh_data)
445 scsi_dh = sdev->scsi_dh_data->scsi_dh; 453 scsi_dh = sdev->scsi_dh_data->scsi_dh;
446 dev = get_device(&sdev->sdev_gendev); 454 dev = get_device(&sdev->sdev_gendev);
447 if (!scsi_dh || !dev || 455 if (!scsi_dh || !dev ||
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 627f4b5e5176..fe4df2da309c 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -507,7 +507,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
507 int len, k, off, valid_states = 0; 507 int len, k, off, valid_states = 0;
508 unsigned char *ucp; 508 unsigned char *ucp;
509 unsigned err; 509 unsigned err;
510 unsigned long expiry, interval = 1; 510 unsigned long expiry, interval = 1000;
511 511
512 expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT); 512 expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT);
513 retry: 513 retry:
@@ -734,6 +734,7 @@ static int alua_bus_attach(struct scsi_device *sdev)
734 spin_lock_irqsave(sdev->request_queue->queue_lock, flags); 734 spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
735 sdev->scsi_dh_data = scsi_dh_data; 735 sdev->scsi_dh_data = scsi_dh_data;
736 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); 736 spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
737 sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME);
737 738
738 return 0; 739 return 0;
739 740
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 61384ee4049b..cefbe44bb84a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2347,14 +2347,11 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
2347 goto done; 2347 goto done;
2348 2348
2349 mac = fr_cb(fp)->granted_mac; 2349 mac = fr_cb(fp)->granted_mac;
2350 if (is_zero_ether_addr(mac)) { 2350 /* pre-FIP */
2351 /* pre-FIP */ 2351 if (is_zero_ether_addr(mac))
2352 if (fcoe_ctlr_recv_flogi(fip, lport, fp)) { 2352 fcoe_ctlr_recv_flogi(fip, lport, fp);
2353 fc_frame_free(fp); 2353 if (!is_zero_ether_addr(mac))
2354 return; 2354 fcoe_update_src_mac(lport, mac);
2355 }
2356 }
2357 fcoe_update_src_mac(lport, mac);
2358done: 2355done:
2359 fc_lport_flogi_resp(seq, fp, lport); 2356 fc_lport_flogi_resp(seq, fp, lport);
2360} 2357}
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 4f7a5829ea4c..351dc0b86fab 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -286,6 +286,7 @@ static void scsi_host_dev_release(struct device *dev)
286{ 286{
287 struct Scsi_Host *shost = dev_to_shost(dev); 287 struct Scsi_Host *shost = dev_to_shost(dev);
288 struct device *parent = dev->parent; 288 struct device *parent = dev->parent;
289 struct request_queue *q;
289 290
290 scsi_proc_hostdir_rm(shost->hostt); 291 scsi_proc_hostdir_rm(shost->hostt);
291 292
@@ -293,9 +294,11 @@ static void scsi_host_dev_release(struct device *dev)
293 kthread_stop(shost->ehandler); 294 kthread_stop(shost->ehandler);
294 if (shost->work_q) 295 if (shost->work_q)
295 destroy_workqueue(shost->work_q); 296 destroy_workqueue(shost->work_q);
296 if (shost->uspace_req_q) { 297 q = shost->uspace_req_q;
297 kfree(shost->uspace_req_q->queuedata); 298 if (q) {
298 scsi_free_queue(shost->uspace_req_q); 299 kfree(q->queuedata);
300 q->queuedata = NULL;
301 scsi_free_queue(q);
299 } 302 }
300 303
301 scsi_destroy_command_freelist(shost); 304 scsi_destroy_command_freelist(shost);
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9825ecf34957..e76107b2ade3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -48,6 +48,7 @@
48#include <linux/bitmap.h> 48#include <linux/bitmap.h>
49#include <linux/atomic.h> 49#include <linux/atomic.h>
50#include <linux/kthread.h> 50#include <linux/kthread.h>
51#include <linux/jiffies.h>
51#include "hpsa_cmd.h" 52#include "hpsa_cmd.h"
52#include "hpsa.h" 53#include "hpsa.h"
53 54
@@ -127,6 +128,10 @@ static struct board_type products[] = {
127 128
128static int number_of_controllers; 129static int number_of_controllers;
129 130
131static struct list_head hpsa_ctlr_list = LIST_HEAD_INIT(hpsa_ctlr_list);
132static spinlock_t lockup_detector_lock;
133static struct task_struct *hpsa_lockup_detector;
134
130static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id); 135static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
131static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id); 136static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
132static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); 137static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
@@ -484,6 +489,7 @@ static struct scsi_host_template hpsa_driver_template = {
484#endif 489#endif
485 .sdev_attrs = hpsa_sdev_attrs, 490 .sdev_attrs = hpsa_sdev_attrs,
486 .shost_attrs = hpsa_shost_attrs, 491 .shost_attrs = hpsa_shost_attrs,
492 .max_sectors = 8192,
487}; 493};
488 494
489 495
@@ -566,16 +572,16 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
566 * assumes h->devlock is held 572 * assumes h->devlock is held
567 */ 573 */
568 int i, found = 0; 574 int i, found = 0;
569 DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA); 575 DECLARE_BITMAP(lun_taken, HPSA_MAX_DEVICES);
570 576
571 memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3); 577 memset(&lun_taken[0], 0, HPSA_MAX_DEVICES >> 3);
572 578
573 for (i = 0; i < h->ndevices; i++) { 579 for (i = 0; i < h->ndevices; i++) {
574 if (h->dev[i]->bus == bus && h->dev[i]->target != -1) 580 if (h->dev[i]->bus == bus && h->dev[i]->target != -1)
575 set_bit(h->dev[i]->target, lun_taken); 581 set_bit(h->dev[i]->target, lun_taken);
576 } 582 }
577 583
578 for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) { 584 for (i = 0; i < HPSA_MAX_DEVICES; i++) {
579 if (!test_bit(i, lun_taken)) { 585 if (!test_bit(i, lun_taken)) {
580 /* *bus = 1; */ 586 /* *bus = 1; */
581 *target = i; 587 *target = i;
@@ -598,7 +604,7 @@ static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
598 unsigned char addr1[8], addr2[8]; 604 unsigned char addr1[8], addr2[8];
599 struct hpsa_scsi_dev_t *sd; 605 struct hpsa_scsi_dev_t *sd;
600 606
601 if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) { 607 if (n >= HPSA_MAX_DEVICES) {
602 dev_err(&h->pdev->dev, "too many devices, some will be " 608 dev_err(&h->pdev->dev, "too many devices, some will be "
603 "inaccessible.\n"); 609 "inaccessible.\n");
604 return -1; 610 return -1;
@@ -673,7 +679,7 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
673 struct hpsa_scsi_dev_t *removed[], int *nremoved) 679 struct hpsa_scsi_dev_t *removed[], int *nremoved)
674{ 680{
675 /* assumes h->devlock is held */ 681 /* assumes h->devlock is held */
676 BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); 682 BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
677 removed[*nremoved] = h->dev[entry]; 683 removed[*nremoved] = h->dev[entry];
678 (*nremoved)++; 684 (*nremoved)++;
679 685
@@ -702,7 +708,7 @@ static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
702 int i; 708 int i;
703 struct hpsa_scsi_dev_t *sd; 709 struct hpsa_scsi_dev_t *sd;
704 710
705 BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); 711 BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
706 712
707 sd = h->dev[entry]; 713 sd = h->dev[entry];
708 removed[*nremoved] = h->dev[entry]; 714 removed[*nremoved] = h->dev[entry];
@@ -814,10 +820,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
814 int nadded, nremoved; 820 int nadded, nremoved;
815 struct Scsi_Host *sh = NULL; 821 struct Scsi_Host *sh = NULL;
816 822
817 added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA, 823 added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
818 GFP_KERNEL); 824 removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
819 removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA,
820 GFP_KERNEL);
821 825
822 if (!added || !removed) { 826 if (!added || !removed) {
823 dev_warn(&h->pdev->dev, "out of memory in " 827 dev_warn(&h->pdev->dev, "out of memory in "
@@ -1338,6 +1342,22 @@ static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
1338 wait_for_completion(&wait); 1342 wait_for_completion(&wait);
1339} 1343}
1340 1344
1345static void hpsa_scsi_do_simple_cmd_core_if_no_lockup(struct ctlr_info *h,
1346 struct CommandList *c)
1347{
1348 unsigned long flags;
1349
1350 /* If controller lockup detected, fake a hardware error. */
1351 spin_lock_irqsave(&h->lock, flags);
1352 if (unlikely(h->lockup_detected)) {
1353 spin_unlock_irqrestore(&h->lock, flags);
1354 c->err_info->CommandStatus = CMD_HARDWARE_ERR;
1355 } else {
1356 spin_unlock_irqrestore(&h->lock, flags);
1357 hpsa_scsi_do_simple_cmd_core(h, c);
1358 }
1359}
1360
1341static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h, 1361static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
1342 struct CommandList *c, int data_direction) 1362 struct CommandList *c, int data_direction)
1343{ 1363{
@@ -1735,7 +1755,6 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
1735 if (is_scsi_rev_5(h)) 1755 if (is_scsi_rev_5(h))
1736 return 0; /* p1210m doesn't need to do this. */ 1756 return 0; /* p1210m doesn't need to do this. */
1737 1757
1738#define MAX_MSA2XXX_ENCLOSURES 32
1739 if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) { 1758 if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
1740 dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX " 1759 dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
1741 "enclosures exceeded. Check your hardware " 1760 "enclosures exceeded. Check your hardware "
@@ -1846,8 +1865,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
1846 int raid_ctlr_position; 1865 int raid_ctlr_position;
1847 DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR); 1866 DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
1848 1867
1849 currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA, 1868 currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
1850 GFP_KERNEL);
1851 physdev_list = kzalloc(reportlunsize, GFP_KERNEL); 1869 physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
1852 logdev_list = kzalloc(reportlunsize, GFP_KERNEL); 1870 logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
1853 tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); 1871 tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
@@ -1870,6 +1888,13 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
1870 1888
1871 /* Allocate the per device structures */ 1889 /* Allocate the per device structures */
1872 for (i = 0; i < ndevs_to_allocate; i++) { 1890 for (i = 0; i < ndevs_to_allocate; i++) {
1891 if (i >= HPSA_MAX_DEVICES) {
1892 dev_warn(&h->pdev->dev, "maximum devices (%d) exceeded."
1893 " %d devices ignored.\n", HPSA_MAX_DEVICES,
1894 ndevs_to_allocate - HPSA_MAX_DEVICES);
1895 break;
1896 }
1897
1873 currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL); 1898 currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL);
1874 if (!currentsd[i]) { 1899 if (!currentsd[i]) {
1875 dev_warn(&h->pdev->dev, "out of memory at %s:%d\n", 1900 dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
@@ -1956,7 +1981,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
1956 default: 1981 default:
1957 break; 1982 break;
1958 } 1983 }
1959 if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA) 1984 if (ncurrent >= HPSA_MAX_DEVICES)
1960 break; 1985 break;
1961 } 1986 }
1962 adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent); 1987 adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
@@ -2048,8 +2073,14 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd,
2048 } 2073 }
2049 memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr)); 2074 memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
2050 2075
2051 /* Need a lock as this is being allocated from the pool */
2052 spin_lock_irqsave(&h->lock, flags); 2076 spin_lock_irqsave(&h->lock, flags);
2077 if (unlikely(h->lockup_detected)) {
2078 spin_unlock_irqrestore(&h->lock, flags);
2079 cmd->result = DID_ERROR << 16;
2080 done(cmd);
2081 return 0;
2082 }
2083 /* Need a lock as this is being allocated from the pool */
2053 c = cmd_alloc(h); 2084 c = cmd_alloc(h);
2054 spin_unlock_irqrestore(&h->lock, flags); 2085 spin_unlock_irqrestore(&h->lock, flags);
2055 if (c == NULL) { /* trouble... */ 2086 if (c == NULL) { /* trouble... */
@@ -2601,7 +2632,7 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
2601 c->SG[0].Len = iocommand.buf_size; 2632 c->SG[0].Len = iocommand.buf_size;
2602 c->SG[0].Ext = 0; /* we are not chaining*/ 2633 c->SG[0].Ext = 0; /* we are not chaining*/
2603 } 2634 }
2604 hpsa_scsi_do_simple_cmd_core(h, c); 2635 hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
2605 if (iocommand.buf_size > 0) 2636 if (iocommand.buf_size > 0)
2606 hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL); 2637 hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
2607 check_ioctl_unit_attention(h, c); 2638 check_ioctl_unit_attention(h, c);
@@ -2724,7 +2755,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
2724 c->SG[i].Ext = 0; 2755 c->SG[i].Ext = 0;
2725 } 2756 }
2726 } 2757 }
2727 hpsa_scsi_do_simple_cmd_core(h, c); 2758 hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
2728 if (sg_used) 2759 if (sg_used)
2729 hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL); 2760 hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
2730 check_ioctl_unit_attention(h, c); 2761 check_ioctl_unit_attention(h, c);
@@ -2872,6 +2903,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
2872 c->Request.Timeout = 0; 2903 c->Request.Timeout = 0;
2873 c->Request.CDB[0] = BMIC_WRITE; 2904 c->Request.CDB[0] = BMIC_WRITE;
2874 c->Request.CDB[6] = BMIC_CACHE_FLUSH; 2905 c->Request.CDB[6] = BMIC_CACHE_FLUSH;
2906 c->Request.CDB[7] = (size >> 8) & 0xFF;
2907 c->Request.CDB[8] = size & 0xFF;
2875 break; 2908 break;
2876 case TEST_UNIT_READY: 2909 case TEST_UNIT_READY:
2877 c->Request.CDBLen = 6; 2910 c->Request.CDBLen = 6;
@@ -3091,6 +3124,7 @@ static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id)
3091 if (interrupt_not_for_us(h)) 3124 if (interrupt_not_for_us(h))
3092 return IRQ_NONE; 3125 return IRQ_NONE;
3093 spin_lock_irqsave(&h->lock, flags); 3126 spin_lock_irqsave(&h->lock, flags);
3127 h->last_intr_timestamp = get_jiffies_64();
3094 while (interrupt_pending(h)) { 3128 while (interrupt_pending(h)) {
3095 raw_tag = get_next_completion(h); 3129 raw_tag = get_next_completion(h);
3096 while (raw_tag != FIFO_EMPTY) 3130 while (raw_tag != FIFO_EMPTY)
@@ -3110,6 +3144,7 @@ static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id)
3110 return IRQ_NONE; 3144 return IRQ_NONE;
3111 3145
3112 spin_lock_irqsave(&h->lock, flags); 3146 spin_lock_irqsave(&h->lock, flags);
3147 h->last_intr_timestamp = get_jiffies_64();
3113 raw_tag = get_next_completion(h); 3148 raw_tag = get_next_completion(h);
3114 while (raw_tag != FIFO_EMPTY) 3149 while (raw_tag != FIFO_EMPTY)
3115 raw_tag = next_command(h); 3150 raw_tag = next_command(h);
@@ -3126,6 +3161,7 @@ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
3126 if (interrupt_not_for_us(h)) 3161 if (interrupt_not_for_us(h))
3127 return IRQ_NONE; 3162 return IRQ_NONE;
3128 spin_lock_irqsave(&h->lock, flags); 3163 spin_lock_irqsave(&h->lock, flags);
3164 h->last_intr_timestamp = get_jiffies_64();
3129 while (interrupt_pending(h)) { 3165 while (interrupt_pending(h)) {
3130 raw_tag = get_next_completion(h); 3166 raw_tag = get_next_completion(h);
3131 while (raw_tag != FIFO_EMPTY) { 3167 while (raw_tag != FIFO_EMPTY) {
@@ -3146,6 +3182,7 @@ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
3146 u32 raw_tag; 3182 u32 raw_tag;
3147 3183
3148 spin_lock_irqsave(&h->lock, flags); 3184 spin_lock_irqsave(&h->lock, flags);
3185 h->last_intr_timestamp = get_jiffies_64();
3149 raw_tag = get_next_completion(h); 3186 raw_tag = get_next_completion(h);
3150 while (raw_tag != FIFO_EMPTY) { 3187 while (raw_tag != FIFO_EMPTY) {
3151 if (hpsa_tag_contains_index(raw_tag)) 3188 if (hpsa_tag_contains_index(raw_tag))
@@ -3300,6 +3337,13 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
3300 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 3337 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
3301 pmcsr |= PCI_D0; 3338 pmcsr |= PCI_D0;
3302 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); 3339 pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
3340
3341 /*
3342 * The P600 requires a small delay when changing states.
3343 * Otherwise we may think the board did not reset and we bail.
3344 * This for kdump only and is particular to the P600.
3345 */
3346 msleep(500);
3303 } 3347 }
3304 return 0; 3348 return 0;
3305} 3349}
@@ -4083,6 +4127,149 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
4083 kfree(h); 4127 kfree(h);
4084} 4128}
4085 4129
4130static void remove_ctlr_from_lockup_detector_list(struct ctlr_info *h)
4131{
4132 assert_spin_locked(&lockup_detector_lock);
4133 if (!hpsa_lockup_detector)
4134 return;
4135 if (h->lockup_detected)
4136 return; /* already stopped the lockup detector */
4137 list_del(&h->lockup_list);
4138}
4139
4140/* Called when controller lockup detected. */
4141static void fail_all_cmds_on_list(struct ctlr_info *h, struct list_head *list)
4142{
4143 struct CommandList *c = NULL;
4144
4145 assert_spin_locked(&h->lock);
4146 /* Mark all outstanding commands as failed and complete them. */
4147 while (!list_empty(list)) {
4148 c = list_entry(list->next, struct CommandList, list);
4149 c->err_info->CommandStatus = CMD_HARDWARE_ERR;
4150 finish_cmd(c, c->Header.Tag.lower);
4151 }
4152}
4153
4154static void controller_lockup_detected(struct ctlr_info *h)
4155{
4156 unsigned long flags;
4157
4158 assert_spin_locked(&lockup_detector_lock);
4159 remove_ctlr_from_lockup_detector_list(h);
4160 h->access.set_intr_mask(h, HPSA_INTR_OFF);
4161 spin_lock_irqsave(&h->lock, flags);
4162 h->lockup_detected = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
4163 spin_unlock_irqrestore(&h->lock, flags);
4164 dev_warn(&h->pdev->dev, "Controller lockup detected: 0x%08x\n",
4165 h->lockup_detected);
4166 pci_disable_device(h->pdev);
4167 spin_lock_irqsave(&h->lock, flags);
4168 fail_all_cmds_on_list(h, &h->cmpQ);
4169 fail_all_cmds_on_list(h, &h->reqQ);
4170 spin_unlock_irqrestore(&h->lock, flags);
4171}
4172
4173#define HEARTBEAT_SAMPLE_INTERVAL (10 * HZ)
4174#define HEARTBEAT_CHECK_MINIMUM_INTERVAL (HEARTBEAT_SAMPLE_INTERVAL / 2)
4175
4176static void detect_controller_lockup(struct ctlr_info *h)
4177{
4178 u64 now;
4179 u32 heartbeat;
4180 unsigned long flags;
4181
4182 assert_spin_locked(&lockup_detector_lock);
4183 now = get_jiffies_64();
4184 /* If we've received an interrupt recently, we're ok. */
4185 if (time_after64(h->last_intr_timestamp +
4186 (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
4187 return;
4188
4189 /*
4190 * If we've already checked the heartbeat recently, we're ok.
4191 * This could happen if someone sends us a signal. We
4192 * otherwise don't care about signals in this thread.
4193 */
4194 if (time_after64(h->last_heartbeat_timestamp +
4195 (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
4196 return;
4197
4198 /* If heartbeat has not changed since we last looked, we're not ok. */
4199 spin_lock_irqsave(&h->lock, flags);
4200 heartbeat = readl(&h->cfgtable->HeartBeat);
4201 spin_unlock_irqrestore(&h->lock, flags);
4202 if (h->last_heartbeat == heartbeat) {
4203 controller_lockup_detected(h);
4204 return;
4205 }
4206
4207 /* We're ok. */
4208 h->last_heartbeat = heartbeat;
4209 h->last_heartbeat_timestamp = now;
4210}
4211
4212static int detect_controller_lockup_thread(void *notused)
4213{
4214 struct ctlr_info *h;
4215 unsigned long flags;
4216
4217 while (1) {
4218 struct list_head *this, *tmp;
4219
4220 schedule_timeout_interruptible(HEARTBEAT_SAMPLE_INTERVAL);
4221 if (kthread_should_stop())
4222 break;
4223 spin_lock_irqsave(&lockup_detector_lock, flags);
4224 list_for_each_safe(this, tmp, &hpsa_ctlr_list) {
4225 h = list_entry(this, struct ctlr_info, lockup_list);
4226 detect_controller_lockup(h);
4227 }
4228 spin_unlock_irqrestore(&lockup_detector_lock, flags);
4229 }
4230 return 0;
4231}
4232
4233static void add_ctlr_to_lockup_detector_list(struct ctlr_info *h)
4234{
4235 unsigned long flags;
4236
4237 spin_lock_irqsave(&lockup_detector_lock, flags);
4238 list_add_tail(&h->lockup_list, &hpsa_ctlr_list);
4239 spin_unlock_irqrestore(&lockup_detector_lock, flags);
4240}
4241
4242static void start_controller_lockup_detector(struct ctlr_info *h)
4243{
4244 /* Start the lockup detector thread if not already started */
4245 if (!hpsa_lockup_detector) {
4246 spin_lock_init(&lockup_detector_lock);
4247 hpsa_lockup_detector =
4248 kthread_run(detect_controller_lockup_thread,
4249 NULL, "hpsa");
4250 }
4251 if (!hpsa_lockup_detector) {
4252 dev_warn(&h->pdev->dev,
4253 "Could not start lockup detector thread\n");
4254 return;
4255 }
4256 add_ctlr_to_lockup_detector_list(h);
4257}
4258
4259static void stop_controller_lockup_detector(struct ctlr_info *h)
4260{
4261 unsigned long flags;
4262
4263 spin_lock_irqsave(&lockup_detector_lock, flags);
4264 remove_ctlr_from_lockup_detector_list(h);
4265 /* If the list of ctlr's to monitor is empty, stop the thread */
4266 if (list_empty(&hpsa_ctlr_list)) {
4267 kthread_stop(hpsa_lockup_detector);
4268 hpsa_lockup_detector = NULL;
4269 }
4270 spin_unlock_irqrestore(&lockup_detector_lock, flags);
4271}
4272
4086static int __devinit hpsa_init_one(struct pci_dev *pdev, 4273static int __devinit hpsa_init_one(struct pci_dev *pdev,
4087 const struct pci_device_id *ent) 4274 const struct pci_device_id *ent)
4088{ 4275{
@@ -4120,7 +4307,6 @@ reinit_after_soft_reset:
4120 return -ENOMEM; 4307 return -ENOMEM;
4121 4308
4122 h->pdev = pdev; 4309 h->pdev = pdev;
4123 h->busy_initializing = 1;
4124 h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT; 4310 h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
4125 INIT_LIST_HEAD(&h->cmpQ); 4311 INIT_LIST_HEAD(&h->cmpQ);
4126 INIT_LIST_HEAD(&h->reqQ); 4312 INIT_LIST_HEAD(&h->reqQ);
@@ -4229,7 +4415,7 @@ reinit_after_soft_reset:
4229 4415
4230 hpsa_hba_inquiry(h); 4416 hpsa_hba_inquiry(h);
4231 hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ 4417 hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
4232 h->busy_initializing = 0; 4418 start_controller_lockup_detector(h);
4233 return 1; 4419 return 1;
4234 4420
4235clean4: 4421clean4:
@@ -4238,7 +4424,6 @@ clean4:
4238 free_irq(h->intr[h->intr_mode], h); 4424 free_irq(h->intr[h->intr_mode], h);
4239clean2: 4425clean2:
4240clean1: 4426clean1:
4241 h->busy_initializing = 0;
4242 kfree(h); 4427 kfree(h);
4243 return rc; 4428 return rc;
4244} 4429}
@@ -4293,10 +4478,11 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
4293 struct ctlr_info *h; 4478 struct ctlr_info *h;
4294 4479
4295 if (pci_get_drvdata(pdev) == NULL) { 4480 if (pci_get_drvdata(pdev) == NULL) {
4296 dev_err(&pdev->dev, "unable to remove device \n"); 4481 dev_err(&pdev->dev, "unable to remove device\n");
4297 return; 4482 return;
4298 } 4483 }
4299 h = pci_get_drvdata(pdev); 4484 h = pci_get_drvdata(pdev);
4485 stop_controller_lockup_detector(h);
4300 hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ 4486 hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */
4301 hpsa_shutdown(pdev); 4487 hpsa_shutdown(pdev);
4302 iounmap(h->vaddr); 4488 iounmap(h->vaddr);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 7f53ceaa7239..91edafb8c7e6 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -95,8 +95,6 @@ struct ctlr_info {
95 unsigned long *cmd_pool_bits; 95 unsigned long *cmd_pool_bits;
96 int nr_allocs; 96 int nr_allocs;
97 int nr_frees; 97 int nr_frees;
98 int busy_initializing;
99 int busy_scanning;
100 int scan_finished; 98 int scan_finished;
101 spinlock_t scan_lock; 99 spinlock_t scan_lock;
102 wait_queue_head_t scan_wait_queue; 100 wait_queue_head_t scan_wait_queue;
@@ -104,8 +102,7 @@ struct ctlr_info {
104 struct Scsi_Host *scsi_host; 102 struct Scsi_Host *scsi_host;
105 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ 103 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */
106 int ndevices; /* number of used elements in .dev[] array. */ 104 int ndevices; /* number of used elements in .dev[] array. */
107#define HPSA_MAX_SCSI_DEVS_PER_HBA 256 105 struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES];
108 struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
109 /* 106 /*
110 * Performant mode tables. 107 * Performant mode tables.
111 */ 108 */
@@ -124,6 +121,11 @@ struct ctlr_info {
124 unsigned char reply_pool_wraparound; 121 unsigned char reply_pool_wraparound;
125 u32 *blockFetchTable; 122 u32 *blockFetchTable;
126 unsigned char *hba_inquiry_data; 123 unsigned char *hba_inquiry_data;
124 u64 last_intr_timestamp;
125 u32 last_heartbeat;
126 u64 last_heartbeat_timestamp;
127 u32 lockup_detected;
128 struct list_head lockup_list;
127}; 129};
128#define HPSA_ABORT_MSG 0 130#define HPSA_ABORT_MSG 0
129#define HPSA_DEVICE_RESET_MSG 1 131#define HPSA_DEVICE_RESET_MSG 1
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 55d741b019db..3fd4715935c2 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -123,8 +123,11 @@ union u64bit {
123 123
124/* FIXME this is a per controller value (barf!) */ 124/* FIXME this is a per controller value (barf!) */
125#define HPSA_MAX_TARGETS_PER_CTLR 16 125#define HPSA_MAX_TARGETS_PER_CTLR 16
126#define HPSA_MAX_LUN 256 126#define HPSA_MAX_LUN 1024
127#define HPSA_MAX_PHYS_LUN 1024 127#define HPSA_MAX_PHYS_LUN 1024
128#define MAX_MSA2XXX_ENCLOSURES 32
129#define HPSA_MAX_DEVICES (HPSA_MAX_PHYS_LUN + HPSA_MAX_LUN + \
130 MAX_MSA2XXX_ENCLOSURES + 1) /* + 1 is for the controller itself */
128 131
129/* SCSI-3 Commands */ 132/* SCSI-3 Commands */
130#pragma pack(1) 133#pragma pack(1)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 73e24b48dced..fd860d952b28 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -9123,6 +9123,8 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
9123 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, 9123 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
9124 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 }, 9124 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
9125 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, 9125 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
9126 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C3, 0, 0, 0 },
9127 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
9126 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C4, 0, 0, 0 }, 9128 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C4, 0, 0, 0 },
9127 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, 9129 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
9128 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 }, 9130 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 6d257e0dd6a5..ac84736c1b9c 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -82,6 +82,7 @@
82 82
83#define IPR_SUBS_DEV_ID_57B4 0x033B 83#define IPR_SUBS_DEV_ID_57B4 0x033B
84#define IPR_SUBS_DEV_ID_57B2 0x035F 84#define IPR_SUBS_DEV_ID_57B2 0x035F
85#define IPR_SUBS_DEV_ID_57C3 0x0353
85#define IPR_SUBS_DEV_ID_57C4 0x0354 86#define IPR_SUBS_DEV_ID_57C4 0x0354
86#define IPR_SUBS_DEV_ID_57C6 0x0357 87#define IPR_SUBS_DEV_ID_57C6 0x0357
87#define IPR_SUBS_DEV_ID_57CC 0x035C 88#define IPR_SUBS_DEV_ID_57CC 0x035C
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index f07f30fada1b..e7fe9c4c85b8 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1350,7 +1350,7 @@ static void isci_user_parameters_get(struct sci_user_parameters *u)
1350 u->stp_max_occupancy_timeout = stp_max_occ_to; 1350 u->stp_max_occupancy_timeout = stp_max_occ_to;
1351 u->ssp_max_occupancy_timeout = ssp_max_occ_to; 1351 u->ssp_max_occupancy_timeout = ssp_max_occ_to;
1352 u->no_outbound_task_timeout = no_outbound_task_to; 1352 u->no_outbound_task_timeout = no_outbound_task_to;
1353 u->max_number_concurrent_device_spin_up = max_concurr_spinup; 1353 u->max_concurr_spinup = max_concurr_spinup;
1354} 1354}
1355 1355
1356static void sci_controller_initial_state_enter(struct sci_base_state_machine *sm) 1356static void sci_controller_initial_state_enter(struct sci_base_state_machine *sm)
@@ -1661,7 +1661,7 @@ static void sci_controller_set_default_config_parameters(struct isci_host *ihost
1661 ihost->oem_parameters.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; 1661 ihost->oem_parameters.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
1662 1662
1663 /* Default to APC mode. */ 1663 /* Default to APC mode. */
1664 ihost->oem_parameters.controller.max_concurrent_dev_spin_up = 1; 1664 ihost->oem_parameters.controller.max_concurr_spin_up = 1;
1665 1665
1666 /* Default to no SSC operation. */ 1666 /* Default to no SSC operation. */
1667 ihost->oem_parameters.controller.do_enable_ssc = false; 1667 ihost->oem_parameters.controller.do_enable_ssc = false;
@@ -1787,7 +1787,8 @@ int sci_oem_parameters_validate(struct sci_oem_params *oem)
1787 } else 1787 } else
1788 return -EINVAL; 1788 return -EINVAL;
1789 1789
1790 if (oem->controller.max_concurrent_dev_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT) 1790 if (oem->controller.max_concurr_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT ||
1791 oem->controller.max_concurr_spin_up < 1)
1791 return -EINVAL; 1792 return -EINVAL;
1792 1793
1793 return 0; 1794 return 0;
@@ -1810,6 +1811,16 @@ static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
1810 return SCI_FAILURE_INVALID_STATE; 1811 return SCI_FAILURE_INVALID_STATE;
1811} 1812}
1812 1813
1814static u8 max_spin_up(struct isci_host *ihost)
1815{
1816 if (ihost->user_parameters.max_concurr_spinup)
1817 return min_t(u8, ihost->user_parameters.max_concurr_spinup,
1818 MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT);
1819 else
1820 return min_t(u8, ihost->oem_parameters.controller.max_concurr_spin_up,
1821 MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT);
1822}
1823
1813static void power_control_timeout(unsigned long data) 1824static void power_control_timeout(unsigned long data)
1814{ 1825{
1815 struct sci_timer *tmr = (struct sci_timer *)data; 1826 struct sci_timer *tmr = (struct sci_timer *)data;
@@ -1839,8 +1850,7 @@ static void power_control_timeout(unsigned long data)
1839 if (iphy == NULL) 1850 if (iphy == NULL)
1840 continue; 1851 continue;
1841 1852
1842 if (ihost->power_control.phys_granted_power >= 1853 if (ihost->power_control.phys_granted_power >= max_spin_up(ihost))
1843 ihost->oem_parameters.controller.max_concurrent_dev_spin_up)
1844 break; 1854 break;
1845 1855
1846 ihost->power_control.requesters[i] = NULL; 1856 ihost->power_control.requesters[i] = NULL;
@@ -1865,8 +1875,7 @@ void sci_controller_power_control_queue_insert(struct isci_host *ihost,
1865{ 1875{
1866 BUG_ON(iphy == NULL); 1876 BUG_ON(iphy == NULL);
1867 1877
1868 if (ihost->power_control.phys_granted_power < 1878 if (ihost->power_control.phys_granted_power < max_spin_up(ihost)) {
1869 ihost->oem_parameters.controller.max_concurrent_dev_spin_up) {
1870 ihost->power_control.phys_granted_power++; 1879 ihost->power_control.phys_granted_power++;
1871 sci_phy_consume_power_handler(iphy); 1880 sci_phy_consume_power_handler(iphy);
1872 1881
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 43fe840fbe9c..a97edabcb85a 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -118,7 +118,7 @@ unsigned char phy_gen = 3;
118module_param(phy_gen, byte, 0); 118module_param(phy_gen, byte, 0);
119MODULE_PARM_DESC(phy_gen, "PHY generation (1: 1.5Gbps 2: 3.0Gbps 3: 6.0Gbps)"); 119MODULE_PARM_DESC(phy_gen, "PHY generation (1: 1.5Gbps 2: 3.0Gbps 3: 6.0Gbps)");
120 120
121unsigned char max_concurr_spinup = 1; 121unsigned char max_concurr_spinup;
122module_param(max_concurr_spinup, byte, 0); 122module_param(max_concurr_spinup, byte, 0);
123MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup"); 123MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
124 124
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 8e59c8865dcd..ac7f27749f97 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -145,48 +145,15 @@ static void sci_port_bcn_enable(struct isci_port *iport)
145 } 145 }
146} 146}
147 147
148/* called under sci_lock to stabilize phy:port associations */
149void isci_port_bcn_enable(struct isci_host *ihost, struct isci_port *iport)
150{
151 int i;
152
153 clear_bit(IPORT_BCN_BLOCKED, &iport->flags);
154 wake_up(&ihost->eventq);
155
156 if (!test_and_clear_bit(IPORT_BCN_PENDING, &iport->flags))
157 return;
158
159 for (i = 0; i < ARRAY_SIZE(iport->phy_table); i++) {
160 struct isci_phy *iphy = iport->phy_table[i];
161
162 if (!iphy)
163 continue;
164
165 ihost->sas_ha.notify_port_event(&iphy->sas_phy,
166 PORTE_BROADCAST_RCVD);
167 break;
168 }
169}
170
171static void isci_port_bc_change_received(struct isci_host *ihost, 148static void isci_port_bc_change_received(struct isci_host *ihost,
172 struct isci_port *iport, 149 struct isci_port *iport,
173 struct isci_phy *iphy) 150 struct isci_phy *iphy)
174{ 151{
175 if (iport && test_bit(IPORT_BCN_BLOCKED, &iport->flags)) { 152 dev_dbg(&ihost->pdev->dev,
176 dev_dbg(&ihost->pdev->dev, 153 "%s: isci_phy = %p, sas_phy = %p\n",
177 "%s: disabled BCN; isci_phy = %p, sas_phy = %p\n", 154 __func__, iphy, &iphy->sas_phy);
178 __func__, iphy, &iphy->sas_phy);
179 set_bit(IPORT_BCN_PENDING, &iport->flags);
180 atomic_inc(&iport->event);
181 wake_up(&ihost->eventq);
182 } else {
183 dev_dbg(&ihost->pdev->dev,
184 "%s: isci_phy = %p, sas_phy = %p\n",
185 __func__, iphy, &iphy->sas_phy);
186 155
187 ihost->sas_ha.notify_port_event(&iphy->sas_phy, 156 ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
188 PORTE_BROADCAST_RCVD);
189 }
190 sci_port_bcn_enable(iport); 157 sci_port_bcn_enable(iport);
191} 158}
192 159
@@ -278,9 +245,6 @@ static void isci_port_link_down(struct isci_host *isci_host,
278 /* check to see if this is the last phy on this port. */ 245 /* check to see if this is the last phy on this port. */
279 if (isci_phy->sas_phy.port && 246 if (isci_phy->sas_phy.port &&
280 isci_phy->sas_phy.port->num_phys == 1) { 247 isci_phy->sas_phy.port->num_phys == 1) {
281 atomic_inc(&isci_port->event);
282 isci_port_bcn_enable(isci_host, isci_port);
283
284 /* change the state for all devices on this port. The 248 /* change the state for all devices on this port. The
285 * next task sent to this device will be returned as 249 * next task sent to this device will be returned as
286 * SAS_TASK_UNDELIVERED, and the scsi mid layer will 250 * SAS_TASK_UNDELIVERED, and the scsi mid layer will
@@ -350,6 +314,34 @@ static void isci_port_stop_complete(struct isci_host *ihost,
350 dev_dbg(&ihost->pdev->dev, "Port stop complete\n"); 314 dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
351} 315}
352 316
317
318static bool is_port_ready_state(enum sci_port_states state)
319{
320 switch (state) {
321 case SCI_PORT_READY:
322 case SCI_PORT_SUB_WAITING:
323 case SCI_PORT_SUB_OPERATIONAL:
324 case SCI_PORT_SUB_CONFIGURING:
325 return true;
326 default:
327 return false;
328 }
329}
330
331/* flag dummy rnc hanling when exiting a ready state */
332static void port_state_machine_change(struct isci_port *iport,
333 enum sci_port_states state)
334{
335 struct sci_base_state_machine *sm = &iport->sm;
336 enum sci_port_states old_state = sm->current_state_id;
337
338 if (is_port_ready_state(old_state) && !is_port_ready_state(state))
339 iport->ready_exit = true;
340
341 sci_change_state(sm, state);
342 iport->ready_exit = false;
343}
344
353/** 345/**
354 * isci_port_hard_reset_complete() - This function is called by the sci core 346 * isci_port_hard_reset_complete() - This function is called by the sci core
355 * when the hard reset complete notification has been received. 347 * when the hard reset complete notification has been received.
@@ -368,6 +360,26 @@ static void isci_port_hard_reset_complete(struct isci_port *isci_port,
368 /* Save the status of the hard reset from the port. */ 360 /* Save the status of the hard reset from the port. */
369 isci_port->hard_reset_status = completion_status; 361 isci_port->hard_reset_status = completion_status;
370 362
363 if (completion_status != SCI_SUCCESS) {
364
365 /* The reset failed. The port state is now SCI_PORT_FAILED. */
366 if (isci_port->active_phy_mask == 0) {
367
368 /* Generate the link down now to the host, since it
369 * was intercepted by the hard reset state machine when
370 * it really happened.
371 */
372 isci_port_link_down(isci_port->isci_host,
373 &isci_port->isci_host->phys[
374 isci_port->last_active_phy],
375 isci_port);
376 }
377 /* Advance the port state so that link state changes will be
378 * noticed.
379 */
380 port_state_machine_change(isci_port, SCI_PORT_SUB_WAITING);
381
382 }
371 complete_all(&isci_port->hard_reset_complete); 383 complete_all(&isci_port->hard_reset_complete);
372} 384}
373 385
@@ -657,6 +669,8 @@ void sci_port_deactivate_phy(struct isci_port *iport, struct isci_phy *iphy,
657 struct isci_host *ihost = iport->owning_controller; 669 struct isci_host *ihost = iport->owning_controller;
658 670
659 iport->active_phy_mask &= ~(1 << iphy->phy_index); 671 iport->active_phy_mask &= ~(1 << iphy->phy_index);
672 if (!iport->active_phy_mask)
673 iport->last_active_phy = iphy->phy_index;
660 674
661 iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN; 675 iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
662 676
@@ -683,33 +697,6 @@ static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *i
683 } 697 }
684} 698}
685 699
686static bool is_port_ready_state(enum sci_port_states state)
687{
688 switch (state) {
689 case SCI_PORT_READY:
690 case SCI_PORT_SUB_WAITING:
691 case SCI_PORT_SUB_OPERATIONAL:
692 case SCI_PORT_SUB_CONFIGURING:
693 return true;
694 default:
695 return false;
696 }
697}
698
699/* flag dummy rnc hanling when exiting a ready state */
700static void port_state_machine_change(struct isci_port *iport,
701 enum sci_port_states state)
702{
703 struct sci_base_state_machine *sm = &iport->sm;
704 enum sci_port_states old_state = sm->current_state_id;
705
706 if (is_port_ready_state(old_state) && !is_port_ready_state(state))
707 iport->ready_exit = true;
708
709 sci_change_state(sm, state);
710 iport->ready_exit = false;
711}
712
713/** 700/**
714 * sci_port_general_link_up_handler - phy can be assigned to port? 701 * sci_port_general_link_up_handler - phy can be assigned to port?
715 * @sci_port: sci_port object for which has a phy that has gone link up. 702 * @sci_port: sci_port object for which has a phy that has gone link up.
@@ -1622,7 +1609,8 @@ void sci_port_construct(struct isci_port *iport, u8 index,
1622 iport->logical_port_index = SCIC_SDS_DUMMY_PORT; 1609 iport->logical_port_index = SCIC_SDS_DUMMY_PORT;
1623 iport->physical_port_index = index; 1610 iport->physical_port_index = index;
1624 iport->active_phy_mask = 0; 1611 iport->active_phy_mask = 0;
1625 iport->ready_exit = false; 1612 iport->last_active_phy = 0;
1613 iport->ready_exit = false;
1626 1614
1627 iport->owning_controller = ihost; 1615 iport->owning_controller = ihost;
1628 1616
@@ -1648,7 +1636,6 @@ void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
1648 init_completion(&iport->start_complete); 1636 init_completion(&iport->start_complete);
1649 iport->isci_host = ihost; 1637 iport->isci_host = ihost;
1650 isci_port_change_state(iport, isci_freed); 1638 isci_port_change_state(iport, isci_freed);
1651 atomic_set(&iport->event, 0);
1652} 1639}
1653 1640
1654/** 1641/**
@@ -1676,7 +1663,7 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
1676{ 1663{
1677 unsigned long flags; 1664 unsigned long flags;
1678 enum sci_status status; 1665 enum sci_status status;
1679 int idx, ret = TMF_RESP_FUNC_COMPLETE; 1666 int ret = TMF_RESP_FUNC_COMPLETE;
1680 1667
1681 dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n", 1668 dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
1682 __func__, iport); 1669 __func__, iport);
@@ -1697,8 +1684,13 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
1697 "%s: iport = %p; hard reset completion\n", 1684 "%s: iport = %p; hard reset completion\n",
1698 __func__, iport); 1685 __func__, iport);
1699 1686
1700 if (iport->hard_reset_status != SCI_SUCCESS) 1687 if (iport->hard_reset_status != SCI_SUCCESS) {
1701 ret = TMF_RESP_FUNC_FAILED; 1688 ret = TMF_RESP_FUNC_FAILED;
1689
1690 dev_err(&ihost->pdev->dev,
1691 "%s: iport = %p; hard reset failed (0x%x)\n",
1692 __func__, iport, iport->hard_reset_status);
1693 }
1702 } else { 1694 } else {
1703 ret = TMF_RESP_FUNC_FAILED; 1695 ret = TMF_RESP_FUNC_FAILED;
1704 1696
@@ -1718,18 +1710,6 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
1718 "%s: iport = %p; hard reset failed " 1710 "%s: iport = %p; hard reset failed "
1719 "(0x%x) - driving explicit link fail for all phys\n", 1711 "(0x%x) - driving explicit link fail for all phys\n",
1720 __func__, iport, iport->hard_reset_status); 1712 __func__, iport, iport->hard_reset_status);
1721
1722 /* Down all phys in the port. */
1723 spin_lock_irqsave(&ihost->scic_lock, flags);
1724 for (idx = 0; idx < SCI_MAX_PHYS; ++idx) {
1725 struct isci_phy *iphy = iport->phy_table[idx];
1726
1727 if (!iphy)
1728 continue;
1729 sci_phy_stop(iphy);
1730 sci_phy_start(iphy);
1731 }
1732 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1733 } 1713 }
1734 return ret; 1714 return ret;
1735} 1715}
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h
index b50ecd4e8f9c..cb5ffbc38603 100644
--- a/drivers/scsi/isci/port.h
+++ b/drivers/scsi/isci/port.h
@@ -77,7 +77,6 @@ enum isci_status {
77 77
78/** 78/**
79 * struct isci_port - isci direct attached sas port object 79 * struct isci_port - isci direct attached sas port object
80 * @event: counts bcns and port stop events (for bcn filtering)
81 * @ready_exit: several states constitute 'ready'. When exiting ready we 80 * @ready_exit: several states constitute 'ready'. When exiting ready we
82 * need to take extra port-teardown actions that are 81 * need to take extra port-teardown actions that are
83 * skipped when exiting to another 'ready' state. 82 * skipped when exiting to another 'ready' state.
@@ -92,10 +91,6 @@ enum isci_status {
92 */ 91 */
93struct isci_port { 92struct isci_port {
94 enum isci_status status; 93 enum isci_status status;
95 #define IPORT_BCN_BLOCKED 0
96 #define IPORT_BCN_PENDING 1
97 unsigned long flags;
98 atomic_t event;
99 struct isci_host *isci_host; 94 struct isci_host *isci_host;
100 struct asd_sas_port sas_port; 95 struct asd_sas_port sas_port;
101 struct list_head remote_dev_list; 96 struct list_head remote_dev_list;
@@ -109,6 +104,7 @@ struct isci_port {
109 u8 logical_port_index; 104 u8 logical_port_index;
110 u8 physical_port_index; 105 u8 physical_port_index;
111 u8 active_phy_mask; 106 u8 active_phy_mask;
107 u8 last_active_phy;
112 u16 reserved_rni; 108 u16 reserved_rni;
113 u16 reserved_tag; 109 u16 reserved_tag;
114 u32 started_request_count; 110 u32 started_request_count;
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h
index dc007e692f4e..2c75248ca326 100644
--- a/drivers/scsi/isci/probe_roms.h
+++ b/drivers/scsi/isci/probe_roms.h
@@ -112,7 +112,7 @@ struct sci_user_parameters {
112 * This field specifies the maximum number of direct attached devices 112 * This field specifies the maximum number of direct attached devices
113 * that can have power supplied to them simultaneously. 113 * that can have power supplied to them simultaneously.
114 */ 114 */
115 u8 max_number_concurrent_device_spin_up; 115 u8 max_concurr_spinup;
116 116
117 /** 117 /**
118 * This field specifies the number of seconds to allow a phy to consume 118 * This field specifies the number of seconds to allow a phy to consume
@@ -219,7 +219,7 @@ struct sci_bios_oem_param_block_hdr {
219struct sci_oem_params { 219struct sci_oem_params {
220 struct { 220 struct {
221 uint8_t mode_type; 221 uint8_t mode_type;
222 uint8_t max_concurrent_dev_spin_up; 222 uint8_t max_concurr_spin_up;
223 uint8_t do_enable_ssc; 223 uint8_t do_enable_ssc;
224 uint8_t reserved; 224 uint8_t reserved;
225 } controller; 225 } controller;
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index fbf9ce28c3f5..b207cd3b15a0 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -1438,88 +1438,3 @@ int isci_remote_device_found(struct domain_device *domain_dev)
1438 1438
1439 return status == SCI_SUCCESS ? 0 : -ENODEV; 1439 return status == SCI_SUCCESS ? 0 : -ENODEV;
1440} 1440}
1441/**
1442 * isci_device_is_reset_pending() - This function will check if there is any
1443 * pending reset condition on the device.
1444 * @request: This parameter is the isci_device object.
1445 *
1446 * true if there is a reset pending for the device.
1447 */
1448bool isci_device_is_reset_pending(
1449 struct isci_host *isci_host,
1450 struct isci_remote_device *isci_device)
1451{
1452 struct isci_request *isci_request;
1453 struct isci_request *tmp_req;
1454 bool reset_is_pending = false;
1455 unsigned long flags;
1456
1457 dev_dbg(&isci_host->pdev->dev,
1458 "%s: isci_device = %p\n", __func__, isci_device);
1459
1460 spin_lock_irqsave(&isci_host->scic_lock, flags);
1461
1462 /* Check for reset on all pending requests. */
1463 list_for_each_entry_safe(isci_request, tmp_req,
1464 &isci_device->reqs_in_process, dev_node) {
1465 dev_dbg(&isci_host->pdev->dev,
1466 "%s: isci_device = %p request = %p\n",
1467 __func__, isci_device, isci_request);
1468
1469 if (isci_request->ttype == io_task) {
1470 struct sas_task *task = isci_request_access_task(
1471 isci_request);
1472
1473 spin_lock(&task->task_state_lock);
1474 if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
1475 reset_is_pending = true;
1476 spin_unlock(&task->task_state_lock);
1477 }
1478 }
1479
1480 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1481
1482 dev_dbg(&isci_host->pdev->dev,
1483 "%s: isci_device = %p reset_is_pending = %d\n",
1484 __func__, isci_device, reset_is_pending);
1485
1486 return reset_is_pending;
1487}
1488
1489/**
1490 * isci_device_clear_reset_pending() - This function will clear if any pending
1491 * reset condition flags on the device.
1492 * @request: This parameter is the isci_device object.
1493 *
1494 * true if there is a reset pending for the device.
1495 */
1496void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev)
1497{
1498 struct isci_request *isci_request;
1499 struct isci_request *tmp_req;
1500 unsigned long flags = 0;
1501
1502 dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n",
1503 __func__, idev, ihost);
1504
1505 spin_lock_irqsave(&ihost->scic_lock, flags);
1506
1507 /* Clear reset pending on all pending requests. */
1508 list_for_each_entry_safe(isci_request, tmp_req,
1509 &idev->reqs_in_process, dev_node) {
1510 dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n",
1511 __func__, idev, isci_request);
1512
1513 if (isci_request->ttype == io_task) {
1514
1515 unsigned long flags2;
1516 struct sas_task *task = isci_request_access_task(
1517 isci_request);
1518
1519 spin_lock_irqsave(&task->task_state_lock, flags2);
1520 task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
1521 spin_unlock_irqrestore(&task->task_state_lock, flags2);
1522 }
1523 }
1524 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1525}
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h
index e1747ea0d0ea..483ee50152f3 100644
--- a/drivers/scsi/isci/remote_device.h
+++ b/drivers/scsi/isci/remote_device.h
@@ -132,10 +132,7 @@ void isci_remote_device_nuke_requests(struct isci_host *ihost,
132 struct isci_remote_device *idev); 132 struct isci_remote_device *idev);
133void isci_remote_device_gone(struct domain_device *domain_dev); 133void isci_remote_device_gone(struct domain_device *domain_dev);
134int isci_remote_device_found(struct domain_device *domain_dev); 134int isci_remote_device_found(struct domain_device *domain_dev);
135bool isci_device_is_reset_pending(struct isci_host *ihost, 135
136 struct isci_remote_device *idev);
137void isci_device_clear_reset_pending(struct isci_host *ihost,
138 struct isci_remote_device *idev);
139/** 136/**
140 * sci_remote_device_stop() - This method will stop both transmission and 137 * sci_remote_device_stop() - This method will stop both transmission and
141 * reception of link activity for the supplied remote device. This method 138 * reception of link activity for the supplied remote device. This method
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 565a9f0a9bc2..192cb48d849a 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -191,7 +191,7 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
191 191
192 task_iu->task_func = isci_tmf->tmf_code; 192 task_iu->task_func = isci_tmf->tmf_code;
193 task_iu->task_tag = 193 task_iu->task_tag =
194 (ireq->ttype == tmf_task) ? 194 (test_bit(IREQ_TMF, &ireq->flags)) ?
195 isci_tmf->io_tag : 195 isci_tmf->io_tag :
196 SCI_CONTROLLER_INVALID_IO_TAG; 196 SCI_CONTROLLER_INVALID_IO_TAG;
197} 197}
@@ -516,7 +516,7 @@ sci_io_request_construct_sata(struct isci_request *ireq,
516 struct domain_device *dev = ireq->target_device->domain_dev; 516 struct domain_device *dev = ireq->target_device->domain_dev;
517 517
518 /* check for management protocols */ 518 /* check for management protocols */
519 if (ireq->ttype == tmf_task) { 519 if (test_bit(IREQ_TMF, &ireq->flags)) {
520 struct isci_tmf *tmf = isci_request_access_tmf(ireq); 520 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
521 521
522 if (tmf->tmf_code == isci_tmf_sata_srst_high || 522 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
@@ -632,7 +632,7 @@ enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
632 enum sci_status status = SCI_SUCCESS; 632 enum sci_status status = SCI_SUCCESS;
633 633
634 /* check for management protocols */ 634 /* check for management protocols */
635 if (ireq->ttype == tmf_task) { 635 if (test_bit(IREQ_TMF, &ireq->flags)) {
636 struct isci_tmf *tmf = isci_request_access_tmf(ireq); 636 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
637 637
638 if (tmf->tmf_code == isci_tmf_sata_srst_high || 638 if (tmf->tmf_code == isci_tmf_sata_srst_high ||
@@ -2630,14 +2630,8 @@ static void isci_task_save_for_upper_layer_completion(
2630 switch (task_notification_selection) { 2630 switch (task_notification_selection) {
2631 2631
2632 case isci_perform_normal_io_completion: 2632 case isci_perform_normal_io_completion:
2633
2634 /* Normal notification (task_done) */ 2633 /* Normal notification (task_done) */
2635 dev_dbg(&host->pdev->dev, 2634
2636 "%s: Normal - task = %p, response=%d (%d), status=%d (%d)\n",
2637 __func__,
2638 task,
2639 task->task_status.resp, response,
2640 task->task_status.stat, status);
2641 /* Add to the completed list. */ 2635 /* Add to the completed list. */
2642 list_add(&request->completed_node, 2636 list_add(&request->completed_node,
2643 &host->requests_to_complete); 2637 &host->requests_to_complete);
@@ -2650,13 +2644,6 @@ static void isci_task_save_for_upper_layer_completion(
2650 /* No notification to libsas because this request is 2644 /* No notification to libsas because this request is
2651 * already in the abort path. 2645 * already in the abort path.
2652 */ 2646 */
2653 dev_dbg(&host->pdev->dev,
2654 "%s: Aborted - task = %p, response=%d (%d), status=%d (%d)\n",
2655 __func__,
2656 task,
2657 task->task_status.resp, response,
2658 task->task_status.stat, status);
2659
2660 /* Wake up whatever process was waiting for this 2647 /* Wake up whatever process was waiting for this
2661 * request to complete. 2648 * request to complete.
2662 */ 2649 */
@@ -2673,30 +2660,22 @@ static void isci_task_save_for_upper_layer_completion(
2673 2660
2674 case isci_perform_error_io_completion: 2661 case isci_perform_error_io_completion:
2675 /* Use sas_task_abort */ 2662 /* Use sas_task_abort */
2676 dev_dbg(&host->pdev->dev,
2677 "%s: Error - task = %p, response=%d (%d), status=%d (%d)\n",
2678 __func__,
2679 task,
2680 task->task_status.resp, response,
2681 task->task_status.stat, status);
2682 /* Add to the aborted list. */ 2663 /* Add to the aborted list. */
2683 list_add(&request->completed_node, 2664 list_add(&request->completed_node,
2684 &host->requests_to_errorback); 2665 &host->requests_to_errorback);
2685 break; 2666 break;
2686 2667
2687 default: 2668 default:
2688 dev_dbg(&host->pdev->dev,
2689 "%s: Unknown - task = %p, response=%d (%d), status=%d (%d)\n",
2690 __func__,
2691 task,
2692 task->task_status.resp, response,
2693 task->task_status.stat, status);
2694
2695 /* Add to the error to libsas list. */ 2669 /* Add to the error to libsas list. */
2696 list_add(&request->completed_node, 2670 list_add(&request->completed_node,
2697 &host->requests_to_errorback); 2671 &host->requests_to_errorback);
2698 break; 2672 break;
2699 } 2673 }
2674 dev_dbg(&host->pdev->dev,
2675 "%s: %d - task = %p, response=%d (%d), status=%d (%d)\n",
2676 __func__, task_notification_selection, task,
2677 (task) ? task->task_status.resp : 0, response,
2678 (task) ? task->task_status.stat : 0, status);
2700} 2679}
2701 2680
2702static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) 2681static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis)
@@ -2728,9 +2707,9 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
2728 struct sas_task *task = isci_request_access_task(request); 2707 struct sas_task *task = isci_request_access_task(request);
2729 struct ssp_response_iu *resp_iu; 2708 struct ssp_response_iu *resp_iu;
2730 unsigned long task_flags; 2709 unsigned long task_flags;
2731 struct isci_remote_device *idev = isci_lookup_device(task->dev); 2710 struct isci_remote_device *idev = request->target_device;
2732 enum service_response response = SAS_TASK_UNDELIVERED; 2711 enum service_response response = SAS_TASK_UNDELIVERED;
2733 enum exec_status status = SAS_ABORTED_TASK; 2712 enum exec_status status = SAS_ABORTED_TASK;
2734 enum isci_request_status request_status; 2713 enum isci_request_status request_status;
2735 enum isci_completion_selection complete_to_host 2714 enum isci_completion_selection complete_to_host
2736 = isci_perform_normal_io_completion; 2715 = isci_perform_normal_io_completion;
@@ -3061,7 +3040,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
3061 3040
3062 /* complete the io request to the core. */ 3041 /* complete the io request to the core. */
3063 sci_controller_complete_io(ihost, request->target_device, request); 3042 sci_controller_complete_io(ihost, request->target_device, request);
3064 isci_put_device(idev);
3065 3043
3066 /* set terminated handle so it cannot be completed or 3044 /* set terminated handle so it cannot be completed or
3067 * terminated again, and to cause any calls into abort 3045 * terminated again, and to cause any calls into abort
@@ -3080,7 +3058,7 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
3080 /* XXX as hch said always creating an internal sas_task for tmf 3058 /* XXX as hch said always creating an internal sas_task for tmf
3081 * requests would simplify the driver 3059 * requests would simplify the driver
3082 */ 3060 */
3083 task = ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL; 3061 task = (test_bit(IREQ_TMF, &ireq->flags)) ? NULL : isci_request_access_task(ireq);
3084 3062
3085 /* all unaccelerated request types (non ssp or ncq) handled with 3063 /* all unaccelerated request types (non ssp or ncq) handled with
3086 * substates 3064 * substates
@@ -3564,7 +3542,7 @@ static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost,
3564 3542
3565 ireq = isci_request_from_tag(ihost, tag); 3543 ireq = isci_request_from_tag(ihost, tag);
3566 ireq->ttype_ptr.io_task_ptr = task; 3544 ireq->ttype_ptr.io_task_ptr = task;
3567 ireq->ttype = io_task; 3545 clear_bit(IREQ_TMF, &ireq->flags);
3568 task->lldd_task = ireq; 3546 task->lldd_task = ireq;
3569 3547
3570 return ireq; 3548 return ireq;
@@ -3578,7 +3556,7 @@ struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
3578 3556
3579 ireq = isci_request_from_tag(ihost, tag); 3557 ireq = isci_request_from_tag(ihost, tag);
3580 ireq->ttype_ptr.tmf_task_ptr = isci_tmf; 3558 ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
3581 ireq->ttype = tmf_task; 3559 set_bit(IREQ_TMF, &ireq->flags);
3582 3560
3583 return ireq; 3561 return ireq;
3584} 3562}
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index f720b97b7bb5..be38933dd6df 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -77,11 +77,6 @@ enum isci_request_status {
77 dead = 0x07 77 dead = 0x07
78}; 78};
79 79
80enum task_type {
81 io_task = 0,
82 tmf_task = 1
83};
84
85enum sci_request_protocol { 80enum sci_request_protocol {
86 SCIC_NO_PROTOCOL, 81 SCIC_NO_PROTOCOL,
87 SCIC_SMP_PROTOCOL, 82 SCIC_SMP_PROTOCOL,
@@ -116,7 +111,6 @@ struct isci_request {
116 #define IREQ_ACTIVE 3 111 #define IREQ_ACTIVE 3
117 unsigned long flags; 112 unsigned long flags;
118 /* XXX kill ttype and ttype_ptr, allocate full sas_task */ 113 /* XXX kill ttype and ttype_ptr, allocate full sas_task */
119 enum task_type ttype;
120 union ttype_ptr_union { 114 union ttype_ptr_union {
121 struct sas_task *io_task_ptr; /* When ttype==io_task */ 115 struct sas_task *io_task_ptr; /* When ttype==io_task */
122 struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ 116 struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index e2d9418683ce..66ad3dc89498 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -212,16 +212,27 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
212 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; 212 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
213 spin_unlock_irqrestore(&task->task_state_lock, flags); 213 spin_unlock_irqrestore(&task->task_state_lock, flags);
214 214
215 /* Indicate QUEUE_FULL so that the scsi 215 if (test_bit(IDEV_GONE, &idev->flags)) {
216 * midlayer retries. if the request 216
217 * failed for remote device reasons, 217 /* Indicate that the device
218 * it gets returned as 218 * is gone.
219 * SAS_TASK_UNDELIVERED next time 219 */
220 * through. 220 isci_task_refuse(ihost, task,
221 */ 221 SAS_TASK_UNDELIVERED,
222 isci_task_refuse(ihost, task, 222 SAS_DEVICE_UNKNOWN);
223 SAS_TASK_COMPLETE, 223 } else {
224 SAS_QUEUE_FULL); 224 /* Indicate QUEUE_FULL so that
225 * the scsi midlayer retries.
226 * If the request failed for
227 * remote device reasons, it
228 * gets returned as
229 * SAS_TASK_UNDELIVERED next
230 * time through.
231 */
232 isci_task_refuse(ihost, task,
233 SAS_TASK_COMPLETE,
234 SAS_QUEUE_FULL);
235 }
225 } 236 }
226 } 237 }
227 } 238 }
@@ -243,7 +254,7 @@ static enum sci_status isci_sata_management_task_request_build(struct isci_reque
243 struct isci_tmf *isci_tmf; 254 struct isci_tmf *isci_tmf;
244 enum sci_status status; 255 enum sci_status status;
245 256
246 if (tmf_task != ireq->ttype) 257 if (!test_bit(IREQ_TMF, &ireq->flags))
247 return SCI_FAILURE; 258 return SCI_FAILURE;
248 259
249 isci_tmf = isci_request_access_tmf(ireq); 260 isci_tmf = isci_request_access_tmf(ireq);
@@ -327,6 +338,60 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
327 return ireq; 338 return ireq;
328} 339}
329 340
341/**
342* isci_request_mark_zombie() - This function must be called with scic_lock held.
343*/
344static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq)
345{
346 struct completion *tmf_completion = NULL;
347 struct completion *req_completion;
348
349 /* Set the request state to "dead". */
350 ireq->status = dead;
351
352 req_completion = ireq->io_request_completion;
353 ireq->io_request_completion = NULL;
354
355 if (test_bit(IREQ_TMF, &ireq->flags)) {
356 /* Break links with the TMF request. */
357 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
358
359 /* In the case where a task request is dying,
360 * the thread waiting on the complete will sit and
361 * timeout unless we wake it now. Since the TMF
362 * has a default error status, complete it here
363 * to wake the waiting thread.
364 */
365 if (tmf) {
366 tmf_completion = tmf->complete;
367 tmf->complete = NULL;
368 }
369 ireq->ttype_ptr.tmf_task_ptr = NULL;
370 dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n",
371 __func__, tmf->tmf_code, tmf->io_tag);
372 } else {
373 /* Break links with the sas_task - the callback is done
374 * elsewhere.
375 */
376 struct sas_task *task = isci_request_access_task(ireq);
377
378 if (task)
379 task->lldd_task = NULL;
380
381 ireq->ttype_ptr.io_task_ptr = NULL;
382 }
383
384 dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n",
385 ireq->io_tag);
386
387 /* Don't force waiting threads to timeout. */
388 if (req_completion)
389 complete(req_completion);
390
391 if (tmf_completion != NULL)
392 complete(tmf_completion);
393}
394
330static int isci_task_execute_tmf(struct isci_host *ihost, 395static int isci_task_execute_tmf(struct isci_host *ihost,
331 struct isci_remote_device *idev, 396 struct isci_remote_device *idev,
332 struct isci_tmf *tmf, unsigned long timeout_ms) 397 struct isci_tmf *tmf, unsigned long timeout_ms)
@@ -364,6 +429,7 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
364 429
365 /* Assign the pointer to the TMF's completion kernel wait structure. */ 430 /* Assign the pointer to the TMF's completion kernel wait structure. */
366 tmf->complete = &completion; 431 tmf->complete = &completion;
432 tmf->status = SCI_FAILURE_TIMEOUT;
367 433
368 ireq = isci_task_request_build(ihost, idev, tag, tmf); 434 ireq = isci_task_request_build(ihost, idev, tag, tmf);
369 if (!ireq) 435 if (!ireq)
@@ -399,18 +465,35 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
399 msecs_to_jiffies(timeout_ms)); 465 msecs_to_jiffies(timeout_ms));
400 466
401 if (timeleft == 0) { 467 if (timeleft == 0) {
468 /* The TMF did not complete - this could be because
469 * of an unplug. Terminate the TMF request now.
470 */
402 spin_lock_irqsave(&ihost->scic_lock, flags); 471 spin_lock_irqsave(&ihost->scic_lock, flags);
403 472
404 if (tmf->cb_state_func != NULL) 473 if (tmf->cb_state_func != NULL)
405 tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data); 474 tmf->cb_state_func(isci_tmf_timed_out, tmf,
475 tmf->cb_data);
406 476
407 sci_controller_terminate_request(ihost, 477 sci_controller_terminate_request(ihost, idev, ireq);
408 idev,
409 ireq);
410 478
411 spin_unlock_irqrestore(&ihost->scic_lock, flags); 479 spin_unlock_irqrestore(&ihost->scic_lock, flags);
412 480
413 wait_for_completion(tmf->complete); 481 timeleft = wait_for_completion_timeout(
482 &completion,
483 msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
484
485 if (!timeleft) {
486 /* Strange condition - the termination of the TMF
487 * request timed-out.
488 */
489 spin_lock_irqsave(&ihost->scic_lock, flags);
490
491 /* If the TMF status has not changed, kill it. */
492 if (tmf->status == SCI_FAILURE_TIMEOUT)
493 isci_request_mark_zombie(ihost, ireq);
494
495 spin_unlock_irqrestore(&ihost->scic_lock, flags);
496 }
414 } 497 }
415 498
416 isci_print_tmf(tmf); 499 isci_print_tmf(tmf);
@@ -501,48 +584,17 @@ static enum isci_request_status isci_task_validate_request_to_abort(
501 return old_state; 584 return old_state;
502} 585}
503 586
504/** 587static int isci_request_is_dealloc_managed(enum isci_request_status stat)
505* isci_request_cleanup_completed_loiterer() - This function will take care of
506* the final cleanup on any request which has been explicitly terminated.
507* @isci_host: This parameter specifies the ISCI host object
508* @isci_device: This is the device to which the request is pending.
509* @isci_request: This parameter specifies the terminated request object.
510* @task: This parameter is the libsas I/O request.
511*/
512static void isci_request_cleanup_completed_loiterer(
513 struct isci_host *isci_host,
514 struct isci_remote_device *isci_device,
515 struct isci_request *isci_request,
516 struct sas_task *task)
517{ 588{
518 unsigned long flags; 589 switch (stat) {
519 590 case aborted:
520 dev_dbg(&isci_host->pdev->dev, 591 case aborting:
521 "%s: isci_device=%p, request=%p, task=%p\n", 592 case terminating:
522 __func__, isci_device, isci_request, task); 593 case completed:
523 594 case dead:
524 if (task != NULL) { 595 return true;
525 596 default:
526 spin_lock_irqsave(&task->task_state_lock, flags); 597 return false;
527 task->lldd_task = NULL;
528
529 task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
530
531 isci_set_task_doneflags(task);
532
533 /* If this task is not in the abort path, call task_done. */
534 if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
535
536 spin_unlock_irqrestore(&task->task_state_lock, flags);
537 task->task_done(task);
538 } else
539 spin_unlock_irqrestore(&task->task_state_lock, flags);
540 }
541
542 if (isci_request != NULL) {
543 spin_lock_irqsave(&isci_host->scic_lock, flags);
544 list_del_init(&isci_request->dev_node);
545 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
546 } 598 }
547} 599}
548 600
@@ -563,11 +615,9 @@ static void isci_terminate_request_core(struct isci_host *ihost,
563 enum sci_status status = SCI_SUCCESS; 615 enum sci_status status = SCI_SUCCESS;
564 bool was_terminated = false; 616 bool was_terminated = false;
565 bool needs_cleanup_handling = false; 617 bool needs_cleanup_handling = false;
566 enum isci_request_status request_status;
567 unsigned long flags; 618 unsigned long flags;
568 unsigned long termination_completed = 1; 619 unsigned long termination_completed = 1;
569 struct completion *io_request_completion; 620 struct completion *io_request_completion;
570 struct sas_task *task;
571 621
572 dev_dbg(&ihost->pdev->dev, 622 dev_dbg(&ihost->pdev->dev,
573 "%s: device = %p; request = %p\n", 623 "%s: device = %p; request = %p\n",
@@ -577,10 +627,6 @@ static void isci_terminate_request_core(struct isci_host *ihost,
577 627
578 io_request_completion = isci_request->io_request_completion; 628 io_request_completion = isci_request->io_request_completion;
579 629
580 task = (isci_request->ttype == io_task)
581 ? isci_request_access_task(isci_request)
582 : NULL;
583
584 /* Note that we are not going to control 630 /* Note that we are not going to control
585 * the target to abort the request. 631 * the target to abort the request.
586 */ 632 */
@@ -619,42 +665,27 @@ static void isci_terminate_request_core(struct isci_host *ihost,
619 __func__, isci_request, io_request_completion); 665 __func__, isci_request, io_request_completion);
620 666
621 /* Wait here for the request to complete. */ 667 /* Wait here for the request to complete. */
622 #define TERMINATION_TIMEOUT_MSEC 500
623 termination_completed 668 termination_completed
624 = wait_for_completion_timeout( 669 = wait_for_completion_timeout(
625 io_request_completion, 670 io_request_completion,
626 msecs_to_jiffies(TERMINATION_TIMEOUT_MSEC)); 671 msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
627 672
628 if (!termination_completed) { 673 if (!termination_completed) {
629 674
630 /* The request to terminate has timed out. */ 675 /* The request to terminate has timed out. */
631 spin_lock_irqsave(&ihost->scic_lock, 676 spin_lock_irqsave(&ihost->scic_lock, flags);
632 flags);
633 677
634 /* Check for state changes. */ 678 /* Check for state changes. */
635 if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) { 679 if (!test_bit(IREQ_TERMINATED,
680 &isci_request->flags)) {
636 681
637 /* The best we can do is to have the 682 /* The best we can do is to have the
638 * request die a silent death if it 683 * request die a silent death if it
639 * ever really completes. 684 * ever really completes.
640 *
641 * Set the request state to "dead",
642 * and clear the task pointer so that
643 * an actual completion event callback
644 * doesn't do anything.
645 */ 685 */
646 isci_request->status = dead; 686 isci_request_mark_zombie(ihost,
647 isci_request->io_request_completion 687 isci_request);
648 = NULL; 688 needs_cleanup_handling = true;
649
650 if (isci_request->ttype == io_task) {
651
652 /* Break links with the
653 * sas_task.
654 */
655 isci_request->ttype_ptr.io_task_ptr
656 = NULL;
657 }
658 } else 689 } else
659 termination_completed = 1; 690 termination_completed = 1;
660 691
@@ -691,29 +722,28 @@ static void isci_terminate_request_core(struct isci_host *ihost,
691 * needs to be detached and freed here. 722 * needs to be detached and freed here.
692 */ 723 */
693 spin_lock_irqsave(&isci_request->state_lock, flags); 724 spin_lock_irqsave(&isci_request->state_lock, flags);
694 request_status = isci_request->status; 725
695 726 needs_cleanup_handling
696 if ((isci_request->ttype == io_task) /* TMFs are in their own thread */ 727 = isci_request_is_dealloc_managed(
697 && ((request_status == aborted) 728 isci_request->status);
698 || (request_status == aborting) 729
699 || (request_status == terminating)
700 || (request_status == completed)
701 || (request_status == dead)
702 )
703 ) {
704
705 /* The completion routine won't free a request in
706 * the aborted/aborting/etc. states, so we do
707 * it here.
708 */
709 needs_cleanup_handling = true;
710 }
711 spin_unlock_irqrestore(&isci_request->state_lock, flags); 730 spin_unlock_irqrestore(&isci_request->state_lock, flags);
712 731
713 } 732 }
714 if (needs_cleanup_handling) 733 if (needs_cleanup_handling) {
715 isci_request_cleanup_completed_loiterer( 734
716 ihost, idev, isci_request, task); 735 dev_dbg(&ihost->pdev->dev,
736 "%s: cleanup isci_device=%p, request=%p\n",
737 __func__, idev, isci_request);
738
739 if (isci_request != NULL) {
740 spin_lock_irqsave(&ihost->scic_lock, flags);
741 isci_free_tag(ihost, isci_request->io_tag);
742 isci_request_change_state(isci_request, unallocated);
743 list_del_init(&isci_request->dev_node);
744 spin_unlock_irqrestore(&ihost->scic_lock, flags);
745 }
746 }
717 } 747 }
718} 748}
719 749
@@ -772,7 +802,9 @@ void isci_terminate_pending_requests(struct isci_host *ihost,
772 dev_dbg(&ihost->pdev->dev, 802 dev_dbg(&ihost->pdev->dev,
773 "%s: idev=%p request=%p; task=%p old_state=%d\n", 803 "%s: idev=%p request=%p; task=%p old_state=%d\n",
774 __func__, idev, ireq, 804 __func__, idev, ireq,
775 ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL, 805 (!test_bit(IREQ_TMF, &ireq->flags)
806 ? isci_request_access_task(ireq)
807 : NULL),
776 old_state); 808 old_state);
777 809
778 /* If the old_state is started: 810 /* If the old_state is started:
@@ -889,22 +921,14 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
889 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", 921 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
890 __func__, domain_device, isci_host, isci_device); 922 __func__, domain_device, isci_host, isci_device);
891 923
892 if (isci_device) 924 if (!isci_device) {
893 set_bit(IDEV_EH, &isci_device->flags); 925 /* If the device is gone, stop the escalations. */
926 dev_dbg(&isci_host->pdev->dev, "%s: No dev\n", __func__);
894 927
895 /* If there is a device reset pending on any request in the 928 ret = TMF_RESP_FUNC_COMPLETE;
896 * device's list, fail this LUN reset request in order to
897 * escalate to the device reset.
898 */
899 if (!isci_device ||
900 isci_device_is_reset_pending(isci_host, isci_device)) {
901 dev_dbg(&isci_host->pdev->dev,
902 "%s: No dev (%p), or "
903 "RESET PENDING: domain_device=%p\n",
904 __func__, isci_device, domain_device);
905 ret = TMF_RESP_FUNC_FAILED;
906 goto out; 929 goto out;
907 } 930 }
931 set_bit(IDEV_EH, &isci_device->flags);
908 932
909 /* Send the task management part of the reset. */ 933 /* Send the task management part of the reset. */
910 if (sas_protocol_ata(domain_device->tproto)) { 934 if (sas_protocol_ata(domain_device->tproto)) {
@@ -1013,7 +1037,7 @@ int isci_task_abort_task(struct sas_task *task)
1013 struct isci_tmf tmf; 1037 struct isci_tmf tmf;
1014 int ret = TMF_RESP_FUNC_FAILED; 1038 int ret = TMF_RESP_FUNC_FAILED;
1015 unsigned long flags; 1039 unsigned long flags;
1016 bool any_dev_reset = false; 1040 int perform_termination = 0;
1017 1041
1018 /* Get the isci_request reference from the task. Note that 1042 /* Get the isci_request reference from the task. Note that
1019 * this check does not depend on the pending request list 1043 * this check does not depend on the pending request list
@@ -1035,89 +1059,34 @@ int isci_task_abort_task(struct sas_task *task)
1035 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 1059 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1036 1060
1037 dev_dbg(&isci_host->pdev->dev, 1061 dev_dbg(&isci_host->pdev->dev,
1038 "%s: task = %p\n", __func__, task); 1062 "%s: dev = %p, task = %p, old_request == %p\n",
1039 1063 __func__, isci_device, task, old_request);
1040 if (!isci_device || !old_request)
1041 goto out;
1042
1043 set_bit(IDEV_EH, &isci_device->flags);
1044
1045 /* This version of the driver will fail abort requests for
1046 * SATA/STP. Failing the abort request this way will cause the
1047 * SCSI error handler thread to escalate to LUN reset
1048 */
1049 if (sas_protocol_ata(task->task_proto)) {
1050 dev_dbg(&isci_host->pdev->dev,
1051 " task %p is for a STP/SATA device;"
1052 " returning TMF_RESP_FUNC_FAILED\n"
1053 " to cause a LUN reset...\n", task);
1054 goto out;
1055 }
1056 1064
1057 dev_dbg(&isci_host->pdev->dev, 1065 if (isci_device)
1058 "%s: old_request == %p\n", __func__, old_request); 1066 set_bit(IDEV_EH, &isci_device->flags);
1059
1060 any_dev_reset = isci_device_is_reset_pending(isci_host, isci_device);
1061
1062 spin_lock_irqsave(&task->task_state_lock, flags);
1063
1064 any_dev_reset = any_dev_reset || (task->task_state_flags & SAS_TASK_NEED_DEV_RESET);
1065 1067
1066 /* If the extraction of the request reference from the task 1068 /* Device reset conditions signalled in task_state_flags are the
1067 * failed, then the request has been completed (or if there is a 1069 * responsbility of libsas to observe at the start of the error
1068 * pending reset then this abort request function must be failed 1070 * handler thread.
1069 * in order to escalate to the target reset).
1070 */ 1071 */
1071 if ((old_request == NULL) || any_dev_reset) { 1072 if (!isci_device || !old_request) {
1072 1073 /* The request has already completed and there
1073 /* If the device reset task flag is set, fail the task 1074 * is nothing to do here other than to set the task
1074 * management request. Otherwise, the original request 1075 * done bit, and indicate that the task abort function
1075 * has completed. 1076 * was sucessful.
1076 */ 1077 */
1077 if (any_dev_reset) { 1078 spin_lock_irqsave(&task->task_state_lock, flags);
1078 1079 task->task_state_flags |= SAS_TASK_STATE_DONE;
1079 /* Turn off the task's DONE to make sure this 1080 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
1080 * task is escalated to a target reset. 1081 SAS_TASK_STATE_PENDING);
1081 */ 1082 spin_unlock_irqrestore(&task->task_state_lock, flags);
1082 task->task_state_flags &= ~SAS_TASK_STATE_DONE;
1083
1084 /* Make the reset happen as soon as possible. */
1085 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
1086
1087 spin_unlock_irqrestore(&task->task_state_lock, flags);
1088
1089 /* Fail the task management request in order to
1090 * escalate to the target reset.
1091 */
1092 ret = TMF_RESP_FUNC_FAILED;
1093
1094 dev_dbg(&isci_host->pdev->dev,
1095 "%s: Failing task abort in order to "
1096 "escalate to target reset because\n"
1097 "SAS_TASK_NEED_DEV_RESET is set for "
1098 "task %p on dev %p\n",
1099 __func__, task, isci_device);
1100
1101
1102 } else {
1103 /* The request has already completed and there
1104 * is nothing to do here other than to set the task
1105 * done bit, and indicate that the task abort function
1106 * was sucessful.
1107 */
1108 isci_set_task_doneflags(task);
1109
1110 spin_unlock_irqrestore(&task->task_state_lock, flags);
1111 1083
1112 ret = TMF_RESP_FUNC_COMPLETE; 1084 ret = TMF_RESP_FUNC_COMPLETE;
1113 1085
1114 dev_dbg(&isci_host->pdev->dev, 1086 dev_dbg(&isci_host->pdev->dev,
1115 "%s: abort task not needed for %p\n", 1087 "%s: abort task not needed for %p\n",
1116 __func__, task); 1088 __func__, task);
1117 }
1118 goto out; 1089 goto out;
1119 } else {
1120 spin_unlock_irqrestore(&task->task_state_lock, flags);
1121 } 1090 }
1122 1091
1123 spin_lock_irqsave(&isci_host->scic_lock, flags); 1092 spin_lock_irqsave(&isci_host->scic_lock, flags);
@@ -1146,24 +1115,44 @@ int isci_task_abort_task(struct sas_task *task)
1146 goto out; 1115 goto out;
1147 } 1116 }
1148 if (task->task_proto == SAS_PROTOCOL_SMP || 1117 if (task->task_proto == SAS_PROTOCOL_SMP ||
1118 sas_protocol_ata(task->task_proto) ||
1149 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) { 1119 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) {
1150 1120
1151 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 1121 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1152 1122
1153 dev_dbg(&isci_host->pdev->dev, 1123 dev_dbg(&isci_host->pdev->dev,
1154 "%s: SMP request (%d)" 1124 "%s: %s request"
1155 " or complete_in_target (%d), thus no TMF\n", 1125 " or complete_in_target (%d), thus no TMF\n",
1156 __func__, (task->task_proto == SAS_PROTOCOL_SMP), 1126 __func__,
1127 ((task->task_proto == SAS_PROTOCOL_SMP)
1128 ? "SMP"
1129 : (sas_protocol_ata(task->task_proto)
1130 ? "SATA/STP"
1131 : "<other>")
1132 ),
1157 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)); 1133 test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags));
1158 1134
1159 /* Set the state on the task. */ 1135 if (test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) {
1160 isci_task_all_done(task); 1136 spin_lock_irqsave(&task->task_state_lock, flags);
1161 1137 task->task_state_flags |= SAS_TASK_STATE_DONE;
1162 ret = TMF_RESP_FUNC_COMPLETE; 1138 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
1139 SAS_TASK_STATE_PENDING);
1140 spin_unlock_irqrestore(&task->task_state_lock, flags);
1141 ret = TMF_RESP_FUNC_COMPLETE;
1142 } else {
1143 spin_lock_irqsave(&task->task_state_lock, flags);
1144 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
1145 SAS_TASK_STATE_PENDING);
1146 spin_unlock_irqrestore(&task->task_state_lock, flags);
1147 }
1163 1148
1164 /* Stopping and SMP devices are not sent a TMF, and are not 1149 /* STP and SMP devices are not sent a TMF, but the
1165 * reset, but the outstanding I/O request is terminated below. 1150 * outstanding I/O request is terminated below. This is
1151 * because SATA/STP and SMP discovery path timeouts directly
1152 * call the abort task interface for cleanup.
1166 */ 1153 */
1154 perform_termination = 1;
1155
1167 } else { 1156 } else {
1168 /* Fill in the tmf stucture */ 1157 /* Fill in the tmf stucture */
1169 isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort, 1158 isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort,
@@ -1172,22 +1161,24 @@ int isci_task_abort_task(struct sas_task *task)
1172 1161
1173 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 1162 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1174 1163
1175 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* half second timeout. */ 1164 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */
1176 ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, 1165 ret = isci_task_execute_tmf(isci_host, isci_device, &tmf,
1177 ISCI_ABORT_TASK_TIMEOUT_MS); 1166 ISCI_ABORT_TASK_TIMEOUT_MS);
1178 1167
1179 if (ret != TMF_RESP_FUNC_COMPLETE) 1168 if (ret == TMF_RESP_FUNC_COMPLETE)
1169 perform_termination = 1;
1170 else
1180 dev_dbg(&isci_host->pdev->dev, 1171 dev_dbg(&isci_host->pdev->dev,
1181 "%s: isci_task_send_tmf failed\n", 1172 "%s: isci_task_send_tmf failed\n", __func__);
1182 __func__);
1183 } 1173 }
1184 if (ret == TMF_RESP_FUNC_COMPLETE) { 1174 if (perform_termination) {
1185 set_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags); 1175 set_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags);
1186 1176
1187 /* Clean up the request on our side, and wait for the aborted 1177 /* Clean up the request on our side, and wait for the aborted
1188 * I/O to complete. 1178 * I/O to complete.
1189 */ 1179 */
1190 isci_terminate_request_core(isci_host, isci_device, old_request); 1180 isci_terminate_request_core(isci_host, isci_device,
1181 old_request);
1191 } 1182 }
1192 1183
1193 /* Make sure we do not leave a reference to aborted_io_completion */ 1184 /* Make sure we do not leave a reference to aborted_io_completion */
@@ -1288,7 +1279,8 @@ isci_task_request_complete(struct isci_host *ihost,
1288 enum sci_task_status completion_status) 1279 enum sci_task_status completion_status)
1289{ 1280{
1290 struct isci_tmf *tmf = isci_request_access_tmf(ireq); 1281 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
1291 struct completion *tmf_complete; 1282 struct completion *tmf_complete = NULL;
1283 struct completion *request_complete = ireq->io_request_completion;
1292 1284
1293 dev_dbg(&ihost->pdev->dev, 1285 dev_dbg(&ihost->pdev->dev,
1294 "%s: request = %p, status=%d\n", 1286 "%s: request = %p, status=%d\n",
@@ -1296,255 +1288,53 @@ isci_task_request_complete(struct isci_host *ihost,
1296 1288
1297 isci_request_change_state(ireq, completed); 1289 isci_request_change_state(ireq, completed);
1298 1290
1299 tmf->status = completion_status;
1300 set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); 1291 set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);
1301 1292
1302 if (tmf->proto == SAS_PROTOCOL_SSP) { 1293 if (tmf) {
1303 memcpy(&tmf->resp.resp_iu, 1294 tmf->status = completion_status;
1304 &ireq->ssp.rsp, 1295
1305 SSP_RESP_IU_MAX_SIZE); 1296 if (tmf->proto == SAS_PROTOCOL_SSP) {
1306 } else if (tmf->proto == SAS_PROTOCOL_SATA) { 1297 memcpy(&tmf->resp.resp_iu,
1307 memcpy(&tmf->resp.d2h_fis, 1298 &ireq->ssp.rsp,
1308 &ireq->stp.rsp, 1299 SSP_RESP_IU_MAX_SIZE);
1309 sizeof(struct dev_to_host_fis)); 1300 } else if (tmf->proto == SAS_PROTOCOL_SATA) {
1301 memcpy(&tmf->resp.d2h_fis,
1302 &ireq->stp.rsp,
1303 sizeof(struct dev_to_host_fis));
1304 }
1305 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
1306 tmf_complete = tmf->complete;
1310 } 1307 }
1311
1312 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
1313 tmf_complete = tmf->complete;
1314
1315 sci_controller_complete_io(ihost, ireq->target_device, ireq); 1308 sci_controller_complete_io(ihost, ireq->target_device, ireq);
1316 /* set the 'terminated' flag handle to make sure it cannot be terminated 1309 /* set the 'terminated' flag handle to make sure it cannot be terminated
1317 * or completed again. 1310 * or completed again.
1318 */ 1311 */
1319 set_bit(IREQ_TERMINATED, &ireq->flags); 1312 set_bit(IREQ_TERMINATED, &ireq->flags);
1320 1313
1321 isci_request_change_state(ireq, unallocated); 1314 /* As soon as something is in the terminate path, deallocation is
1322 list_del_init(&ireq->dev_node); 1315 * managed there. Note that the final non-managed state of a task
1323 1316 * request is "completed".
1324 /* The task management part completes last. */ 1317 */
1325 complete(tmf_complete); 1318 if ((ireq->status == completed) ||
1326} 1319 !isci_request_is_dealloc_managed(ireq->status)) {
1327 1320 isci_request_change_state(ireq, unallocated);
1328static void isci_smp_task_timedout(unsigned long _task) 1321 isci_free_tag(ihost, ireq->io_tag);
1329{ 1322 list_del_init(&ireq->dev_node);
1330 struct sas_task *task = (void *) _task;
1331 unsigned long flags;
1332
1333 spin_lock_irqsave(&task->task_state_lock, flags);
1334 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
1335 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
1336 spin_unlock_irqrestore(&task->task_state_lock, flags);
1337
1338 complete(&task->completion);
1339}
1340
1341static void isci_smp_task_done(struct sas_task *task)
1342{
1343 if (!del_timer(&task->timer))
1344 return;
1345 complete(&task->completion);
1346}
1347
1348static int isci_smp_execute_task(struct isci_host *ihost,
1349 struct domain_device *dev, void *req,
1350 int req_size, void *resp, int resp_size)
1351{
1352 int res, retry;
1353 struct sas_task *task = NULL;
1354
1355 for (retry = 0; retry < 3; retry++) {
1356 task = sas_alloc_task(GFP_KERNEL);
1357 if (!task)
1358 return -ENOMEM;
1359
1360 task->dev = dev;
1361 task->task_proto = dev->tproto;
1362 sg_init_one(&task->smp_task.smp_req, req, req_size);
1363 sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
1364
1365 task->task_done = isci_smp_task_done;
1366
1367 task->timer.data = (unsigned long) task;
1368 task->timer.function = isci_smp_task_timedout;
1369 task->timer.expires = jiffies + 10*HZ;
1370 add_timer(&task->timer);
1371
1372 res = isci_task_execute_task(task, 1, GFP_KERNEL);
1373
1374 if (res) {
1375 del_timer(&task->timer);
1376 dev_dbg(&ihost->pdev->dev,
1377 "%s: executing SMP task failed:%d\n",
1378 __func__, res);
1379 goto ex_err;
1380 }
1381
1382 wait_for_completion(&task->completion);
1383 res = -ECOMM;
1384 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
1385 dev_dbg(&ihost->pdev->dev,
1386 "%s: smp task timed out or aborted\n",
1387 __func__);
1388 isci_task_abort_task(task);
1389 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
1390 dev_dbg(&ihost->pdev->dev,
1391 "%s: SMP task aborted and not done\n",
1392 __func__);
1393 goto ex_err;
1394 }
1395 }
1396 if (task->task_status.resp == SAS_TASK_COMPLETE &&
1397 task->task_status.stat == SAM_STAT_GOOD) {
1398 res = 0;
1399 break;
1400 }
1401 if (task->task_status.resp == SAS_TASK_COMPLETE &&
1402 task->task_status.stat == SAS_DATA_UNDERRUN) {
1403 /* no error, but return the number of bytes of
1404 * underrun */
1405 res = task->task_status.residual;
1406 break;
1407 }
1408 if (task->task_status.resp == SAS_TASK_COMPLETE &&
1409 task->task_status.stat == SAS_DATA_OVERRUN) {
1410 res = -EMSGSIZE;
1411 break;
1412 } else {
1413 dev_dbg(&ihost->pdev->dev,
1414 "%s: task to dev %016llx response: 0x%x "
1415 "status 0x%x\n", __func__,
1416 SAS_ADDR(dev->sas_addr),
1417 task->task_status.resp,
1418 task->task_status.stat);
1419 sas_free_task(task);
1420 task = NULL;
1421 }
1422 }
1423ex_err:
1424 BUG_ON(retry == 3 && task != NULL);
1425 sas_free_task(task);
1426 return res;
1427}
1428
1429#define DISCOVER_REQ_SIZE 16
1430#define DISCOVER_RESP_SIZE 56
1431
1432int isci_smp_get_phy_attached_dev_type(struct isci_host *ihost,
1433 struct domain_device *dev,
1434 int phy_id, int *adt)
1435{
1436 struct smp_resp *disc_resp;
1437 u8 *disc_req;
1438 int res;
1439
1440 disc_resp = kzalloc(DISCOVER_RESP_SIZE, GFP_KERNEL);
1441 if (!disc_resp)
1442 return -ENOMEM;
1443
1444 disc_req = kzalloc(DISCOVER_REQ_SIZE, GFP_KERNEL);
1445 if (disc_req) {
1446 disc_req[0] = SMP_REQUEST;
1447 disc_req[1] = SMP_DISCOVER;
1448 disc_req[9] = phy_id;
1449 } else {
1450 kfree(disc_resp);
1451 return -ENOMEM;
1452 }
1453 res = isci_smp_execute_task(ihost, dev, disc_req, DISCOVER_REQ_SIZE,
1454 disc_resp, DISCOVER_RESP_SIZE);
1455 if (!res) {
1456 if (disc_resp->result != SMP_RESP_FUNC_ACC)
1457 res = disc_resp->result;
1458 else
1459 *adt = disc_resp->disc.attached_dev_type;
1460 } 1323 }
1461 kfree(disc_req);
1462 kfree(disc_resp);
1463
1464 return res;
1465}
1466
1467static void isci_wait_for_smp_phy_reset(struct isci_remote_device *idev, int phy_num)
1468{
1469 struct domain_device *dev = idev->domain_dev;
1470 struct isci_port *iport = idev->isci_port;
1471 struct isci_host *ihost = iport->isci_host;
1472 int res, iteration = 0, attached_device_type;
1473 #define STP_WAIT_MSECS 25000
1474 unsigned long tmo = msecs_to_jiffies(STP_WAIT_MSECS);
1475 unsigned long deadline = jiffies + tmo;
1476 enum {
1477 SMP_PHYWAIT_PHYDOWN,
1478 SMP_PHYWAIT_PHYUP,
1479 SMP_PHYWAIT_DONE
1480 } phy_state = SMP_PHYWAIT_PHYDOWN;
1481
1482 /* While there is time, wait for the phy to go away and come back */
1483 while (time_is_after_jiffies(deadline) && phy_state != SMP_PHYWAIT_DONE) {
1484 int event = atomic_read(&iport->event);
1485
1486 ++iteration;
1487
1488 tmo = wait_event_timeout(ihost->eventq,
1489 event != atomic_read(&iport->event) ||
1490 !test_bit(IPORT_BCN_BLOCKED, &iport->flags),
1491 tmo);
1492 /* link down, stop polling */
1493 if (!test_bit(IPORT_BCN_BLOCKED, &iport->flags))
1494 break;
1495 1324
1496 dev_dbg(&ihost->pdev->dev, 1325 /* "request_complete" is set if the task was being terminated. */
1497 "%s: iport %p, iteration %d," 1326 if (request_complete)
1498 " phase %d: time_remaining %lu, bcns = %d\n", 1327 complete(request_complete);
1499 __func__, iport, iteration, phy_state,
1500 tmo, test_bit(IPORT_BCN_PENDING, &iport->flags));
1501
1502 res = isci_smp_get_phy_attached_dev_type(ihost, dev, phy_num,
1503 &attached_device_type);
1504 tmo = deadline - jiffies;
1505
1506 if (res) {
1507 dev_dbg(&ihost->pdev->dev,
1508 "%s: iteration %d, phase %d:"
1509 " SMP error=%d, time_remaining=%lu\n",
1510 __func__, iteration, phy_state, res, tmo);
1511 break;
1512 }
1513 dev_dbg(&ihost->pdev->dev,
1514 "%s: iport %p, iteration %d,"
1515 " phase %d: time_remaining %lu, bcns = %d, "
1516 "attdevtype = %x\n",
1517 __func__, iport, iteration, phy_state,
1518 tmo, test_bit(IPORT_BCN_PENDING, &iport->flags),
1519 attached_device_type);
1520
1521 switch (phy_state) {
1522 case SMP_PHYWAIT_PHYDOWN:
1523 /* Has the device gone away? */
1524 if (!attached_device_type)
1525 phy_state = SMP_PHYWAIT_PHYUP;
1526
1527 break;
1528
1529 case SMP_PHYWAIT_PHYUP:
1530 /* Has the device come back? */
1531 if (attached_device_type)
1532 phy_state = SMP_PHYWAIT_DONE;
1533 break;
1534
1535 case SMP_PHYWAIT_DONE:
1536 break;
1537 }
1538 1328
1539 } 1329 /* The task management part completes last. */
1540 dev_dbg(&ihost->pdev->dev, "%s: done\n", __func__); 1330 if (tmf_complete)
1331 complete(tmf_complete);
1541} 1332}
1542 1333
1543static int isci_reset_device(struct isci_host *ihost, 1334static int isci_reset_device(struct isci_host *ihost,
1544 struct isci_remote_device *idev) 1335 struct isci_remote_device *idev)
1545{ 1336{
1546 struct sas_phy *phy = sas_find_local_phy(idev->domain_dev); 1337 struct sas_phy *phy = sas_find_local_phy(idev->domain_dev);
1547 struct isci_port *iport = idev->isci_port;
1548 enum sci_status status; 1338 enum sci_status status;
1549 unsigned long flags; 1339 unsigned long flags;
1550 int rc; 1340 int rc;
@@ -1564,13 +1354,6 @@ static int isci_reset_device(struct isci_host *ihost,
1564 } 1354 }
1565 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1355 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1566 1356
1567 /* Make sure all pending requests are able to be fully terminated. */
1568 isci_device_clear_reset_pending(ihost, idev);
1569
1570 /* If this is a device on an expander, disable BCN processing. */
1571 if (!scsi_is_sas_phy_local(phy))
1572 set_bit(IPORT_BCN_BLOCKED, &iport->flags);
1573
1574 rc = sas_phy_reset(phy, true); 1357 rc = sas_phy_reset(phy, true);
1575 1358
1576 /* Terminate in-progress I/O now. */ 1359 /* Terminate in-progress I/O now. */
@@ -1581,21 +1364,6 @@ static int isci_reset_device(struct isci_host *ihost,
1581 status = sci_remote_device_reset_complete(idev); 1364 status = sci_remote_device_reset_complete(idev);
1582 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1365 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1583 1366
1584 /* If this is a device on an expander, bring the phy back up. */
1585 if (!scsi_is_sas_phy_local(phy)) {
1586 /* A phy reset will cause the device to go away then reappear.
1587 * Since libsas will take action on incoming BCNs (eg. remove
1588 * a device going through an SMP phy-control driven reset),
1589 * we need to wait until the phy comes back up before letting
1590 * discovery proceed in libsas.
1591 */
1592 isci_wait_for_smp_phy_reset(idev, phy->number);
1593
1594 spin_lock_irqsave(&ihost->scic_lock, flags);
1595 isci_port_bcn_enable(ihost, idev->isci_port);
1596 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1597 }
1598
1599 if (status != SCI_SUCCESS) { 1367 if (status != SCI_SUCCESS) {
1600 dev_dbg(&ihost->pdev->dev, 1368 dev_dbg(&ihost->pdev->dev,
1601 "%s: sci_remote_device_reset_complete(%p) " 1369 "%s: sci_remote_device_reset_complete(%p) "
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index 15b18d158993..bc78c0a41d5c 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -58,6 +58,8 @@
58#include <scsi/sas_ata.h> 58#include <scsi/sas_ata.h>
59#include "host.h" 59#include "host.h"
60 60
61#define ISCI_TERMINATION_TIMEOUT_MSEC 500
62
61struct isci_request; 63struct isci_request;
62 64
63/** 65/**
@@ -224,35 +226,6 @@ enum isci_completion_selection {
224 isci_perform_error_io_completion /* Use sas_task_abort */ 226 isci_perform_error_io_completion /* Use sas_task_abort */
225}; 227};
226 228
227static inline void isci_set_task_doneflags(
228 struct sas_task *task)
229{
230 /* Since no futher action will be taken on this task,
231 * make sure to mark it complete from the lldd perspective.
232 */
233 task->task_state_flags |= SAS_TASK_STATE_DONE;
234 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
235 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
236}
237/**
238 * isci_task_all_done() - This function clears the task bits to indicate the
239 * LLDD is done with the task.
240 *
241 *
242 */
243static inline void isci_task_all_done(
244 struct sas_task *task)
245{
246 unsigned long flags;
247
248 /* Since no futher action will be taken on this task,
249 * make sure to mark it complete from the lldd perspective.
250 */
251 spin_lock_irqsave(&task->task_state_lock, flags);
252 isci_set_task_doneflags(task);
253 spin_unlock_irqrestore(&task->task_state_lock, flags);
254}
255
256/** 229/**
257 * isci_task_set_completion_status() - This function sets the completion status 230 * isci_task_set_completion_status() - This function sets the completion status
258 * for the request. 231 * for the request.
@@ -334,7 +307,9 @@ isci_task_set_completion_status(
334 /* Fall through to the normal case... */ 307 /* Fall through to the normal case... */
335 case isci_perform_normal_io_completion: 308 case isci_perform_normal_io_completion:
336 /* Normal notification (task_done) */ 309 /* Normal notification (task_done) */
337 isci_set_task_doneflags(task); 310 task->task_state_flags |= SAS_TASK_STATE_DONE;
311 task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
312 SAS_TASK_STATE_PENDING);
338 break; 313 break;
339 default: 314 default:
340 WARN_ONCE(1, "unknown task_notification_selection: %d\n", 315 WARN_ONCE(1, "unknown task_notification_selection: %d\n",
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 7c055fdca45d..1b22130035da 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -469,6 +469,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
469 struct fc_frame_header *fh = fc_frame_header_get(fp); 469 struct fc_frame_header *fh = fc_frame_header_get(fp);
470 int error; 470 int error;
471 u32 f_ctl; 471 u32 f_ctl;
472 u8 fh_type = fh->fh_type;
472 473
473 ep = fc_seq_exch(sp); 474 ep = fc_seq_exch(sp);
474 WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); 475 WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
@@ -493,7 +494,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
493 */ 494 */
494 error = lport->tt.frame_send(lport, fp); 495 error = lport->tt.frame_send(lport, fp);
495 496
496 if (fh->fh_type == FC_TYPE_BLS) 497 if (fh_type == FC_TYPE_BLS)
497 return error; 498 return error;
498 499
499 /* 500 /*
@@ -1792,6 +1793,9 @@ restart:
1792 goto restart; 1793 goto restart;
1793 } 1794 }
1794 } 1795 }
1796 pool->next_index = 0;
1797 pool->left = FC_XID_UNKNOWN;
1798 pool->right = FC_XID_UNKNOWN;
1795 spin_unlock_bh(&pool->lock); 1799 spin_unlock_bh(&pool->lock);
1796} 1800}
1797 1801
@@ -2280,6 +2284,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
2280 goto free_mempool; 2284 goto free_mempool;
2281 for_each_possible_cpu(cpu) { 2285 for_each_possible_cpu(cpu) {
2282 pool = per_cpu_ptr(mp->pool, cpu); 2286 pool = per_cpu_ptr(mp->pool, cpu);
2287 pool->next_index = 0;
2283 pool->left = FC_XID_UNKNOWN; 2288 pool->left = FC_XID_UNKNOWN;
2284 pool->right = FC_XID_UNKNOWN; 2289 pool->right = FC_XID_UNKNOWN;
2285 spin_lock_init(&pool->lock); 2290 spin_lock_init(&pool->lock);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 628f347404f9..2cb12b9cd3e8 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1030,16 +1030,8 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
1030 FCH_EVT_LIPRESET, 0); 1030 FCH_EVT_LIPRESET, 0);
1031 fc_vports_linkchange(lport); 1031 fc_vports_linkchange(lport);
1032 fc_lport_reset_locked(lport); 1032 fc_lport_reset_locked(lport);
1033 if (lport->link_up) { 1033 if (lport->link_up)
1034 /*
1035 * Wait upto resource allocation time out before
1036 * doing re-login since incomplete FIP exchanged
1037 * from last session may collide with exchanges
1038 * in new session.
1039 */
1040 msleep(lport->r_a_tov);
1041 fc_lport_enter_flogi(lport); 1034 fc_lport_enter_flogi(lport);
1042 }
1043} 1035}
1044 1036
1045/** 1037/**
@@ -1481,6 +1473,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1481 void *lp_arg) 1473 void *lp_arg)
1482{ 1474{
1483 struct fc_lport *lport = lp_arg; 1475 struct fc_lport *lport = lp_arg;
1476 struct fc_frame_header *fh;
1484 struct fc_els_flogi *flp; 1477 struct fc_els_flogi *flp;
1485 u32 did; 1478 u32 did;
1486 u16 csp_flags; 1479 u16 csp_flags;
@@ -1508,49 +1501,56 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1508 goto err; 1501 goto err;
1509 } 1502 }
1510 1503
1504 fh = fc_frame_header_get(fp);
1511 did = fc_frame_did(fp); 1505 did = fc_frame_did(fp);
1512 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did) { 1506 if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
1513 flp = fc_frame_payload_get(fp, sizeof(*flp)); 1507 fc_frame_payload_op(fp) != ELS_LS_ACC) {
1514 if (flp) { 1508 FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
1515 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1516 FC_SP_BB_DATA_MASK;
1517 if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
1518 mfs < lport->mfs)
1519 lport->mfs = mfs;
1520 csp_flags = ntohs(flp->fl_csp.sp_features);
1521 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1522 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1523 if (csp_flags & FC_SP_FT_EDTR)
1524 e_d_tov /= 1000000;
1525
1526 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1527
1528 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1529 if (e_d_tov > lport->e_d_tov)
1530 lport->e_d_tov = e_d_tov;
1531 lport->r_a_tov = 2 * e_d_tov;
1532 fc_lport_set_port_id(lport, did, fp);
1533 printk(KERN_INFO "host%d: libfc: "
1534 "Port (%6.6x) entered "
1535 "point-to-point mode\n",
1536 lport->host->host_no, did);
1537 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1538 get_unaligned_be64(
1539 &flp->fl_wwpn),
1540 get_unaligned_be64(
1541 &flp->fl_wwnn));
1542 } else {
1543 lport->e_d_tov = e_d_tov;
1544 lport->r_a_tov = r_a_tov;
1545 fc_host_fabric_name(lport->host) =
1546 get_unaligned_be64(&flp->fl_wwnn);
1547 fc_lport_set_port_id(lport, did, fp);
1548 fc_lport_enter_dns(lport);
1549 }
1550 }
1551 } else {
1552 FC_LPORT_DBG(lport, "FLOGI RJT or bad response\n");
1553 fc_lport_error(lport, fp); 1509 fc_lport_error(lport, fp);
1510 goto err;
1511 }
1512
1513 flp = fc_frame_payload_get(fp, sizeof(*flp));
1514 if (!flp) {
1515 FC_LPORT_DBG(lport, "FLOGI bad response\n");
1516 fc_lport_error(lport, fp);
1517 goto err;
1518 }
1519
1520 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1521 FC_SP_BB_DATA_MASK;
1522 if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
1523 mfs < lport->mfs)
1524 lport->mfs = mfs;
1525 csp_flags = ntohs(flp->fl_csp.sp_features);
1526 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1527 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1528 if (csp_flags & FC_SP_FT_EDTR)
1529 e_d_tov /= 1000000;
1530
1531 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1532
1533 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1534 if (e_d_tov > lport->e_d_tov)
1535 lport->e_d_tov = e_d_tov;
1536 lport->r_a_tov = 2 * e_d_tov;
1537 fc_lport_set_port_id(lport, did, fp);
1538 printk(KERN_INFO "host%d: libfc: "
1539 "Port (%6.6x) entered "
1540 "point-to-point mode\n",
1541 lport->host->host_no, did);
1542 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1543 get_unaligned_be64(
1544 &flp->fl_wwpn),
1545 get_unaligned_be64(
1546 &flp->fl_wwnn));
1547 } else {
1548 lport->e_d_tov = e_d_tov;
1549 lport->r_a_tov = r_a_tov;
1550 fc_host_fabric_name(lport->host) =
1551 get_unaligned_be64(&flp->fl_wwnn);
1552 fc_lport_set_port_id(lport, did, fp);
1553 fc_lport_enter_dns(lport);
1554 } 1554 }
1555 1555
1556out: 1556out:
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index 3105d5e8d908..8dc1b32918dd 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2010 LSI Corporation. 2 * Copyright (c) 2000-2011 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2.h 5 * Name: mpi2.h
@@ -8,7 +8,7 @@
8 * scatter/gather formats. 8 * scatter/gather formats.
9 * Creation Date: June 21, 2006 9 * Creation Date: June 21, 2006
10 * 10 *
11 * mpi2.h Version: 02.00.18 11 * mpi2.h Version: 02.00.20
12 * 12 *
13 * Version History 13 * Version History
14 * --------------- 14 * ---------------
@@ -66,6 +66,9 @@
66 * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT. 66 * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT.
67 * 11-10-10 02.00.18 Bumped MPI2_HEADER_VERSION_UNIT. 67 * 11-10-10 02.00.18 Bumped MPI2_HEADER_VERSION_UNIT.
68 * Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define. 68 * Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define.
69 * 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT.
70 * Added MPI2_FUNCTION_SEND_HOST_MESSAGE.
71 * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT.
69 * -------------------------------------------------------------------------- 72 * --------------------------------------------------------------------------
70 */ 73 */
71 74
@@ -91,7 +94,7 @@
91#define MPI2_VERSION_02_00 (0x0200) 94#define MPI2_VERSION_02_00 (0x0200)
92 95
93/* versioning for this MPI header set */ 96/* versioning for this MPI header set */
94#define MPI2_HEADER_VERSION_UNIT (0x12) 97#define MPI2_HEADER_VERSION_UNIT (0x14)
95#define MPI2_HEADER_VERSION_DEV (0x00) 98#define MPI2_HEADER_VERSION_DEV (0x00)
96#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) 99#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
97#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) 100#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -515,6 +518,8 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
515#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) 518#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F)
516/* Power Management Control */ 519/* Power Management Control */
517#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) 520#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30)
521/* Send Host Message */
522#define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31)
518/* beginning of product-specific range */ 523/* beginning of product-specific range */
519#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) 524#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0)
520/* end of product-specific range */ 525/* end of product-specific range */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index 61475a6480e3..cfd95b4e3004 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2010 LSI Corporation. 2 * Copyright (c) 2000-2011 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_cnfg.h 5 * Name: mpi2_cnfg.h
6 * Title: MPI Configuration messages and pages 6 * Title: MPI Configuration messages and pages
7 * Creation Date: November 10, 2006 7 * Creation Date: November 10, 2006
8 * 8 *
9 * mpi2_cnfg.h Version: 02.00.17 9 * mpi2_cnfg.h Version: 02.00.19
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -134,6 +134,12 @@
134 * to MPI2_CONFIG_PAGE_IO_UNIT_7. 134 * to MPI2_CONFIG_PAGE_IO_UNIT_7.
135 * Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define 135 * Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define
136 * and MPI2_CONFIG_PAGE_EXT_MAN_PS structure. 136 * and MPI2_CONFIG_PAGE_EXT_MAN_PS structure.
137 * 02-23-11 02.00.18 Added ProxyVF_ID field to MPI2_CONFIG_REQUEST.
138 * Added IO Unit Page 8, IO Unit Page 9,
139 * and IO Unit Page 10.
140 * Added SASNotifyPrimitiveMasks field to
141 * MPI2_CONFIG_PAGE_IOC_7.
142 * 03-09-11 02.00.19 Fixed IO Unit Page 10 (to match the spec).
137 * -------------------------------------------------------------------------- 143 * --------------------------------------------------------------------------
138 */ 144 */
139 145
@@ -329,7 +335,9 @@ typedef struct _MPI2_CONFIG_REQUEST
329 U8 VP_ID; /* 0x08 */ 335 U8 VP_ID; /* 0x08 */
330 U8 VF_ID; /* 0x09 */ 336 U8 VF_ID; /* 0x09 */
331 U16 Reserved1; /* 0x0A */ 337 U16 Reserved1; /* 0x0A */
332 U32 Reserved2; /* 0x0C */ 338 U8 Reserved2; /* 0x0C */
339 U8 ProxyVF_ID; /* 0x0D */
340 U16 Reserved4; /* 0x0E */
333 U32 Reserved3; /* 0x10 */ 341 U32 Reserved3; /* 0x10 */
334 MPI2_CONFIG_PAGE_HEADER Header; /* 0x14 */ 342 MPI2_CONFIG_PAGE_HEADER Header; /* 0x14 */
335 U32 PageAddress; /* 0x18 */ 343 U32 PageAddress; /* 0x18 */
@@ -915,6 +923,120 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
915#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01) 923#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01)
916#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02) 924#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02)
917 925
926/* IO Unit Page 8 */
927
928#define MPI2_IOUNIT8_NUM_THRESHOLDS (4)
929
930typedef struct _MPI2_IOUNIT8_SENSOR {
931 U16 Flags; /* 0x00 */
932 U16 Reserved1; /* 0x02 */
933 U16
934 Threshold[MPI2_IOUNIT8_NUM_THRESHOLDS]; /* 0x04 */
935 U32 Reserved2; /* 0x0C */
936 U32 Reserved3; /* 0x10 */
937 U32 Reserved4; /* 0x14 */
938} MPI2_IOUNIT8_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT8_SENSOR,
939Mpi2IOUnit8Sensor_t, MPI2_POINTER pMpi2IOUnit8Sensor_t;
940
941/* defines for IO Unit Page 8 Sensor Flags field */
942#define MPI2_IOUNIT8_SENSOR_FLAGS_T3_ENABLE (0x0008)
943#define MPI2_IOUNIT8_SENSOR_FLAGS_T2_ENABLE (0x0004)
944#define MPI2_IOUNIT8_SENSOR_FLAGS_T1_ENABLE (0x0002)
945#define MPI2_IOUNIT8_SENSOR_FLAGS_T0_ENABLE (0x0001)
946
947/*
948 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
949 * one and check the value returned for NumSensors at runtime.
950 */
951#ifndef MPI2_IOUNITPAGE8_SENSOR_ENTRIES
952#define MPI2_IOUNITPAGE8_SENSOR_ENTRIES (1)
953#endif
954
955typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_8 {
956 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
957 U32 Reserved1; /* 0x04 */
958 U32 Reserved2; /* 0x08 */
959 U8 NumSensors; /* 0x0C */
960 U8 PollingInterval; /* 0x0D */
961 U16 Reserved3; /* 0x0E */
962 MPI2_IOUNIT8_SENSOR
963 Sensor[MPI2_IOUNITPAGE8_SENSOR_ENTRIES];/* 0x10 */
964} MPI2_CONFIG_PAGE_IO_UNIT_8, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_8,
965Mpi2IOUnitPage8_t, MPI2_POINTER pMpi2IOUnitPage8_t;
966
967#define MPI2_IOUNITPAGE8_PAGEVERSION (0x00)
968
969
970/* IO Unit Page 9 */
971
972typedef struct _MPI2_IOUNIT9_SENSOR {
973 U16 CurrentTemperature; /* 0x00 */
974 U16 Reserved1; /* 0x02 */
975 U8 Flags; /* 0x04 */
976 U8 Reserved2; /* 0x05 */
977 U16 Reserved3; /* 0x06 */
978 U32 Reserved4; /* 0x08 */
979 U32 Reserved5; /* 0x0C */
980} MPI2_IOUNIT9_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT9_SENSOR,
981Mpi2IOUnit9Sensor_t, MPI2_POINTER pMpi2IOUnit9Sensor_t;
982
983/* defines for IO Unit Page 9 Sensor Flags field */
984#define MPI2_IOUNIT9_SENSOR_FLAGS_TEMP_VALID (0x01)
985
986/*
987 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
988 * one and check the value returned for NumSensors at runtime.
989 */
990#ifndef MPI2_IOUNITPAGE9_SENSOR_ENTRIES
991#define MPI2_IOUNITPAGE9_SENSOR_ENTRIES (1)
992#endif
993
994typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_9 {
995 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
996 U32 Reserved1; /* 0x04 */
997 U32 Reserved2; /* 0x08 */
998 U8 NumSensors; /* 0x0C */
999 U8 Reserved4; /* 0x0D */
1000 U16 Reserved3; /* 0x0E */
1001 MPI2_IOUNIT9_SENSOR
1002 Sensor[MPI2_IOUNITPAGE9_SENSOR_ENTRIES];/* 0x10 */
1003} MPI2_CONFIG_PAGE_IO_UNIT_9, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_9,
1004Mpi2IOUnitPage9_t, MPI2_POINTER pMpi2IOUnitPage9_t;
1005
1006#define MPI2_IOUNITPAGE9_PAGEVERSION (0x00)
1007
1008
1009/* IO Unit Page 10 */
1010
1011typedef struct _MPI2_IOUNIT10_FUNCTION {
1012 U8 CreditPercent; /* 0x00 */
1013 U8 Reserved1; /* 0x01 */
1014 U16 Reserved2; /* 0x02 */
1015} MPI2_IOUNIT10_FUNCTION, MPI2_POINTER PTR_MPI2_IOUNIT10_FUNCTION,
1016Mpi2IOUnit10Function_t, MPI2_POINTER pMpi2IOUnit10Function_t;
1017
1018/*
1019 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
1020 * one and check the value returned for NumFunctions at runtime.
1021 */
1022#ifndef MPI2_IOUNITPAGE10_FUNCTION_ENTRIES
1023#define MPI2_IOUNITPAGE10_FUNCTION_ENTRIES (1)
1024#endif
1025
1026typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10 {
1027 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
1028 U8 NumFunctions; /* 0x04 */
1029 U8 Reserved1; /* 0x05 */
1030 U16 Reserved2; /* 0x06 */
1031 U32 Reserved3; /* 0x08 */
1032 U32 Reserved4; /* 0x0C */
1033 MPI2_IOUNIT10_FUNCTION
1034 Function[MPI2_IOUNITPAGE10_FUNCTION_ENTRIES];/* 0x10 */
1035} MPI2_CONFIG_PAGE_IO_UNIT_10, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_10,
1036Mpi2IOUnitPage10_t, MPI2_POINTER pMpi2IOUnitPage10_t;
1037
1038#define MPI2_IOUNITPAGE10_PAGEVERSION (0x01)
1039
918 1040
919 1041
920/**************************************************************************** 1042/****************************************************************************
@@ -1022,12 +1144,12 @@ typedef struct _MPI2_CONFIG_PAGE_IOC_7
1022 U32 Reserved1; /* 0x04 */ 1144 U32 Reserved1; /* 0x04 */
1023 U32 EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/* 0x08 */ 1145 U32 EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/* 0x08 */
1024 U16 SASBroadcastPrimitiveMasks; /* 0x18 */ 1146 U16 SASBroadcastPrimitiveMasks; /* 0x18 */
1025 U16 Reserved2; /* 0x1A */ 1147 U16 SASNotifyPrimitiveMasks; /* 0x1A */
1026 U32 Reserved3; /* 0x1C */ 1148 U32 Reserved3; /* 0x1C */
1027} MPI2_CONFIG_PAGE_IOC_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_7, 1149} MPI2_CONFIG_PAGE_IOC_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_7,
1028 Mpi2IOCPage7_t, MPI2_POINTER pMpi2IOCPage7_t; 1150 Mpi2IOCPage7_t, MPI2_POINTER pMpi2IOCPage7_t;
1029 1151
1030#define MPI2_IOCPAGE7_PAGEVERSION (0x01) 1152#define MPI2_IOCPAGE7_PAGEVERSION (0x02)
1031 1153
1032 1154
1033/* IOC Page 8 */ 1155/* IOC Page 8 */
@@ -2070,16 +2192,16 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 {
2070#define MPI2_SASIOUNITPAGE8_PAGEVERSION (0x00) 2192#define MPI2_SASIOUNITPAGE8_PAGEVERSION (0x00)
2071 2193
2072/* defines for PowerManagementCapabilities field */ 2194/* defines for PowerManagementCapabilities field */
2073#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD (0x000001000) 2195#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD (0x00001000)
2074#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE (0x000000800) 2196#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE (0x00000800)
2075#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE (0x000000400) 2197#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE (0x00000400)
2076#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE (0x000000200) 2198#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE (0x00000200)
2077#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE (0x000000100) 2199#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE (0x00000100)
2078#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD (0x000000010) 2200#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD (0x00000010)
2079#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE (0x000000008) 2201#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE (0x00000008)
2080#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE (0x000000004) 2202#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE (0x00000004)
2081#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE (0x000000002) 2203#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE (0x00000002)
2082#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE (0x000000001) 2204#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE (0x00000001)
2083 2205
2084 2206
2085 2207
@@ -2266,6 +2388,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
2266/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ 2388/* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
2267 2389
2268/* values for SAS Device Page 0 Flags field */ 2390/* values for SAS Device Page 0 Flags field */
2391#define MPI2_SAS_DEVICE0_FLAGS_UNAUTHORIZED_DEVICE (0x8000)
2269#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000) 2392#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000)
2270#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800) 2393#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800)
2271#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) 2394#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index 1f0c190d336e..93d9b6956d05 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2010 LSI Corporation. 2 * Copyright (c) 2000-2011 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_ioc.h 5 * Name: mpi2_ioc.h
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages 6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: October 11, 2006 7 * Creation Date: October 11, 2006
8 * 8 *
9 * mpi2_ioc.h Version: 02.00.16 9 * mpi2_ioc.h Version: 02.00.17
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -104,6 +104,12 @@
104 * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete. 104 * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete.
105 * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define. 105 * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
106 * 11-10-10 02.00.16 Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC. 106 * 11-10-10 02.00.16 Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC.
107 * 02-23-11 02.00.17 Added SAS NOTIFY Primitive event, and added
108 * SASNotifyPrimitiveMasks field to
109 * MPI2_EVENT_NOTIFICATION_REQUEST.
110 * Added Temperature Threshold Event.
111 * Added Host Message Event.
112 * Added Send Host Message request and reply.
107 * -------------------------------------------------------------------------- 113 * --------------------------------------------------------------------------
108 */ 114 */
109 115
@@ -421,7 +427,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST
421 U32 Reserved6; /* 0x10 */ 427 U32 Reserved6; /* 0x10 */
422 U32 EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];/* 0x14 */ 428 U32 EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];/* 0x14 */
423 U16 SASBroadcastPrimitiveMasks; /* 0x24 */ 429 U16 SASBroadcastPrimitiveMasks; /* 0x24 */
424 U16 Reserved7; /* 0x26 */ 430 U16 SASNotifyPrimitiveMasks; /* 0x26 */
425 U32 Reserved8; /* 0x28 */ 431 U32 Reserved8; /* 0x28 */
426} MPI2_EVENT_NOTIFICATION_REQUEST, 432} MPI2_EVENT_NOTIFICATION_REQUEST,
427 MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REQUEST, 433 MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REQUEST,
@@ -476,6 +482,9 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
476#define MPI2_EVENT_GPIO_INTERRUPT (0x0023) 482#define MPI2_EVENT_GPIO_INTERRUPT (0x0023)
477#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024) 483#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024)
478#define MPI2_EVENT_SAS_QUIESCE (0x0025) 484#define MPI2_EVENT_SAS_QUIESCE (0x0025)
485#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE (0x0026)
486#define MPI2_EVENT_TEMP_THRESHOLD (0x0027)
487#define MPI2_EVENT_HOST_MESSAGE (0x0028)
479 488
480 489
481/* Log Entry Added Event data */ 490/* Log Entry Added Event data */
@@ -507,6 +516,39 @@ typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
507 MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT, 516 MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
508 Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t; 517 Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
509 518
519/* Temperature Threshold Event data */
520
521typedef struct _MPI2_EVENT_DATA_TEMPERATURE {
522 U16 Status; /* 0x00 */
523 U8 SensorNum; /* 0x02 */
524 U8 Reserved1; /* 0x03 */
525 U16 CurrentTemperature; /* 0x04 */
526 U16 Reserved2; /* 0x06 */
527 U32 Reserved3; /* 0x08 */
528 U32 Reserved4; /* 0x0C */
529} MPI2_EVENT_DATA_TEMPERATURE,
530MPI2_POINTER PTR_MPI2_EVENT_DATA_TEMPERATURE,
531Mpi2EventDataTemperature_t, MPI2_POINTER pMpi2EventDataTemperature_t;
532
533/* Temperature Threshold Event data Status bits */
534#define MPI2_EVENT_TEMPERATURE3_EXCEEDED (0x0008)
535#define MPI2_EVENT_TEMPERATURE2_EXCEEDED (0x0004)
536#define MPI2_EVENT_TEMPERATURE1_EXCEEDED (0x0002)
537#define MPI2_EVENT_TEMPERATURE0_EXCEEDED (0x0001)
538
539
540/* Host Message Event data */
541
542typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE {
543 U8 SourceVF_ID; /* 0x00 */
544 U8 Reserved1; /* 0x01 */
545 U16 Reserved2; /* 0x02 */
546 U32 Reserved3; /* 0x04 */
547 U32 HostData[1]; /* 0x08 */
548} MPI2_EVENT_DATA_HOST_MESSAGE, MPI2_POINTER PTR_MPI2_EVENT_DATA_HOST_MESSAGE,
549Mpi2EventDataHostMessage_t, MPI2_POINTER pMpi2EventDataHostMessage_t;
550
551
510/* Hard Reset Received Event data */ 552/* Hard Reset Received Event data */
511 553
512typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED 554typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -749,6 +791,24 @@ typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE
749#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07) 791#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07)
750#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08) 792#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08)
751 793
794/* SAS Notify Primitive Event data */
795
796typedef struct _MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE {
797 U8 PhyNum; /* 0x00 */
798 U8 Port; /* 0x01 */
799 U8 Reserved1; /* 0x02 */
800 U8 Primitive; /* 0x03 */
801} MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
802MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
803Mpi2EventDataSasNotifyPrimitive_t,
804MPI2_POINTER pMpi2EventDataSasNotifyPrimitive_t;
805
806/* defines for the Primitive field */
807#define MPI2_EVENT_NOTIFY_ENABLE_SPINUP (0x01)
808#define MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED (0x02)
809#define MPI2_EVENT_NOTIFY_RESERVED1 (0x03)
810#define MPI2_EVENT_NOTIFY_RESERVED2 (0x04)
811
752 812
753/* SAS Initiator Device Status Change Event data */ 813/* SAS Initiator Device Status Change Event data */
754 814
@@ -1001,6 +1061,53 @@ typedef struct _MPI2_EVENT_ACK_REPLY
1001 1061
1002 1062
1003/**************************************************************************** 1063/****************************************************************************
1064* SendHostMessage message
1065****************************************************************************/
1066
1067/* SendHostMessage Request message */
1068typedef struct _MPI2_SEND_HOST_MESSAGE_REQUEST {
1069 U16 HostDataLength; /* 0x00 */
1070 U8 ChainOffset; /* 0x02 */
1071 U8 Function; /* 0x03 */
1072 U16 Reserved1; /* 0x04 */
1073 U8 Reserved2; /* 0x06 */
1074 U8 MsgFlags; /* 0x07 */
1075 U8 VP_ID; /* 0x08 */
1076 U8 VF_ID; /* 0x09 */
1077 U16 Reserved3; /* 0x0A */
1078 U8 Reserved4; /* 0x0C */
1079 U8 DestVF_ID; /* 0x0D */
1080 U16 Reserved5; /* 0x0E */
1081 U32 Reserved6; /* 0x10 */
1082 U32 Reserved7; /* 0x14 */
1083 U32 Reserved8; /* 0x18 */
1084 U32 Reserved9; /* 0x1C */
1085 U32 Reserved10; /* 0x20 */
1086 U32 HostData[1]; /* 0x24 */
1087} MPI2_SEND_HOST_MESSAGE_REQUEST,
1088MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REQUEST,
1089Mpi2SendHostMessageRequest_t, MPI2_POINTER pMpi2SendHostMessageRequest_t;
1090
1091
1092/* SendHostMessage Reply message */
1093typedef struct _MPI2_SEND_HOST_MESSAGE_REPLY {
1094 U16 HostDataLength; /* 0x00 */
1095 U8 MsgLength; /* 0x02 */
1096 U8 Function; /* 0x03 */
1097 U16 Reserved1; /* 0x04 */
1098 U8 Reserved2; /* 0x06 */
1099 U8 MsgFlags; /* 0x07 */
1100 U8 VP_ID; /* 0x08 */
1101 U8 VF_ID; /* 0x09 */
1102 U16 Reserved3; /* 0x0A */
1103 U16 Reserved4; /* 0x0C */
1104 U16 IOCStatus; /* 0x0E */
1105 U32 IOCLogInfo; /* 0x10 */
1106} MPI2_SEND_HOST_MESSAGE_REPLY, MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REPLY,
1107Mpi2SendHostMessageReply_t, MPI2_POINTER pMpi2SendHostMessageReply_t;
1108
1109
1110/****************************************************************************
1004* FWDownload message 1111* FWDownload message
1005****************************************************************************/ 1112****************************************************************************/
1006 1113
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 81209ca87274..beda04a8404b 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -81,6 +81,15 @@ static int missing_delay[2] = {-1, -1};
81module_param_array(missing_delay, int, NULL, 0); 81module_param_array(missing_delay, int, NULL, 0);
82MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); 82MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
83 83
84static int mpt2sas_fwfault_debug;
85MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
86 "and halt firmware - (default=0)");
87
88static int disable_discovery = -1;
89module_param(disable_discovery, int, 0);
90MODULE_PARM_DESC(disable_discovery, " disable discovery ");
91
92
84/* diag_buffer_enable is bitwise 93/* diag_buffer_enable is bitwise
85 * bit 0 set = TRACE 94 * bit 0 set = TRACE
86 * bit 1 set = SNAPSHOT 95 * bit 1 set = SNAPSHOT
@@ -93,14 +102,6 @@ module_param(diag_buffer_enable, int, 0);
93MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " 102MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
94 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); 103 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
95 104
96static int mpt2sas_fwfault_debug;
97MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
98 "and halt firmware - (default=0)");
99
100static int disable_discovery = -1;
101module_param(disable_discovery, int, 0);
102MODULE_PARM_DESC(disable_discovery, " disable discovery ");
103
104/** 105/**
105 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. 106 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
106 * 107 *
@@ -691,6 +692,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
691 memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); 692 memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
692 } 693 }
693 ioc->base_cmds.status &= ~MPT2_CMD_PENDING; 694 ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
695
694 complete(&ioc->base_cmds.done); 696 complete(&ioc->base_cmds.done);
695 return 1; 697 return 1;
696} 698}
@@ -3470,6 +3472,58 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3470} 3472}
3471 3473
3472/** 3474/**
3475 * mpt2sas_port_enable_done - command completion routine for port enable
3476 * @ioc: per adapter object
3477 * @smid: system request message index
3478 * @msix_index: MSIX table index supplied by the OS
3479 * @reply: reply message frame(lower 32bit addr)
3480 *
3481 * Return 1 meaning mf should be freed from _base_interrupt
3482 * 0 means the mf is freed from this function.
3483 */
3484u8
3485mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
3486 u32 reply)
3487{
3488 MPI2DefaultReply_t *mpi_reply;
3489 u16 ioc_status;
3490
3491 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
3492 if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
3493 return 1;
3494
3495 if (ioc->port_enable_cmds.status == MPT2_CMD_NOT_USED)
3496 return 1;
3497
3498 ioc->port_enable_cmds.status |= MPT2_CMD_COMPLETE;
3499 if (mpi_reply) {
3500 ioc->port_enable_cmds.status |= MPT2_CMD_REPLY_VALID;
3501 memcpy(ioc->port_enable_cmds.reply, mpi_reply,
3502 mpi_reply->MsgLength*4);
3503 }
3504 ioc->port_enable_cmds.status &= ~MPT2_CMD_PENDING;
3505
3506 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
3507
3508 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
3509 ioc->port_enable_failed = 1;
3510
3511 if (ioc->is_driver_loading) {
3512 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
3513 mpt2sas_port_enable_complete(ioc);
3514 return 1;
3515 } else {
3516 ioc->start_scan_failed = ioc_status;
3517 ioc->start_scan = 0;
3518 return 1;
3519 }
3520 }
3521 complete(&ioc->port_enable_cmds.done);
3522 return 1;
3523}
3524
3525
3526/**
3473 * _base_send_port_enable - send port_enable(discovery stuff) to firmware 3527 * _base_send_port_enable - send port_enable(discovery stuff) to firmware
3474 * @ioc: per adapter object 3528 * @ioc: per adapter object
3475 * @sleep_flag: CAN_SLEEP or NO_SLEEP 3529 * @sleep_flag: CAN_SLEEP or NO_SLEEP
@@ -3480,67 +3534,151 @@ static int
3480_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) 3534_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3481{ 3535{
3482 Mpi2PortEnableRequest_t *mpi_request; 3536 Mpi2PortEnableRequest_t *mpi_request;
3483 u32 ioc_state; 3537 Mpi2PortEnableReply_t *mpi_reply;
3484 unsigned long timeleft; 3538 unsigned long timeleft;
3485 int r = 0; 3539 int r = 0;
3486 u16 smid; 3540 u16 smid;
3541 u16 ioc_status;
3487 3542
3488 printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name); 3543 printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
3489 3544
3490 if (ioc->base_cmds.status & MPT2_CMD_PENDING) { 3545 if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
3491 printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n", 3546 printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
3492 ioc->name, __func__); 3547 ioc->name, __func__);
3493 return -EAGAIN; 3548 return -EAGAIN;
3494 } 3549 }
3495 3550
3496 smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); 3551 smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
3497 if (!smid) { 3552 if (!smid) {
3498 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 3553 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
3499 ioc->name, __func__); 3554 ioc->name, __func__);
3500 return -EAGAIN; 3555 return -EAGAIN;
3501 } 3556 }
3502 3557
3503 ioc->base_cmds.status = MPT2_CMD_PENDING; 3558 ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
3504 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 3559 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
3505 ioc->base_cmds.smid = smid; 3560 ioc->port_enable_cmds.smid = smid;
3506 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); 3561 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
3507 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; 3562 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
3508 mpi_request->VF_ID = 0; /* TODO */
3509 mpi_request->VP_ID = 0;
3510 3563
3564 init_completion(&ioc->port_enable_cmds.done);
3511 mpt2sas_base_put_smid_default(ioc, smid); 3565 mpt2sas_base_put_smid_default(ioc, smid);
3512 init_completion(&ioc->base_cmds.done); 3566 timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done,
3513 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
3514 300*HZ); 3567 300*HZ);
3515 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { 3568 if (!(ioc->port_enable_cmds.status & MPT2_CMD_COMPLETE)) {
3516 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 3569 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
3517 ioc->name, __func__); 3570 ioc->name, __func__);
3518 _debug_dump_mf(mpi_request, 3571 _debug_dump_mf(mpi_request,
3519 sizeof(Mpi2PortEnableRequest_t)/4); 3572 sizeof(Mpi2PortEnableRequest_t)/4);
3520 if (ioc->base_cmds.status & MPT2_CMD_RESET) 3573 if (ioc->port_enable_cmds.status & MPT2_CMD_RESET)
3521 r = -EFAULT; 3574 r = -EFAULT;
3522 else 3575 else
3523 r = -ETIME; 3576 r = -ETIME;
3524 goto out; 3577 goto out;
3525 } else 3578 }
3526 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n", 3579 mpi_reply = ioc->port_enable_cmds.reply;
3527 ioc->name, __func__));
3528 3580
3529 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL, 3581 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
3530 60, sleep_flag); 3582 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
3531 if (ioc_state) { 3583 printk(MPT2SAS_ERR_FMT "%s: failed with (ioc_status=0x%08x)\n",
3532 printk(MPT2SAS_ERR_FMT "%s: failed going to operational state " 3584 ioc->name, __func__, ioc_status);
3533 " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
3534 r = -EFAULT; 3585 r = -EFAULT;
3586 goto out;
3535 } 3587 }
3536 out: 3588 out:
3537 ioc->base_cmds.status = MPT2_CMD_NOT_USED; 3589 ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
3538 printk(MPT2SAS_INFO_FMT "port enable: %s\n", 3590 printk(MPT2SAS_INFO_FMT "port enable: %s\n", ioc->name, ((r == 0) ?
3539 ioc->name, ((r == 0) ? "SUCCESS" : "FAILED")); 3591 "SUCCESS" : "FAILED"));
3540 return r; 3592 return r;
3541} 3593}
3542 3594
3543/** 3595/**
3596 * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply)
3597 * @ioc: per adapter object
3598 *
3599 * Returns 0 for success, non-zero for failure.
3600 */
3601int
3602mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc)
3603{
3604 Mpi2PortEnableRequest_t *mpi_request;
3605 u16 smid;
3606
3607 printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
3608
3609 if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
3610 printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
3611 ioc->name, __func__);
3612 return -EAGAIN;
3613 }
3614
3615 smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
3616 if (!smid) {
3617 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
3618 ioc->name, __func__);
3619 return -EAGAIN;
3620 }
3621
3622 ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
3623 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
3624 ioc->port_enable_cmds.smid = smid;
3625 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
3626 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
3627
3628 mpt2sas_base_put_smid_default(ioc, smid);
3629 return 0;
3630}
3631
3632/**
3633 * _base_determine_wait_on_discovery - desposition
3634 * @ioc: per adapter object
3635 *
3636 * Decide whether to wait on discovery to complete. Used to either
3637 * locate boot device, or report volumes ahead of physical devices.
3638 *
3639 * Returns 1 for wait, 0 for don't wait
3640 */
3641static int
3642_base_determine_wait_on_discovery(struct MPT2SAS_ADAPTER *ioc)
3643{
3644 /* We wait for discovery to complete if IR firmware is loaded.
3645 * The sas topology events arrive before PD events, so we need time to
3646 * turn on the bit in ioc->pd_handles to indicate PD
3647 * Also, it maybe required to report Volumes ahead of physical
3648 * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set.
3649 */
3650 if (ioc->ir_firmware)
3651 return 1;
3652
3653 /* if no Bios, then we don't need to wait */
3654 if (!ioc->bios_pg3.BiosVersion)
3655 return 0;
3656
3657 /* Bios is present, then we drop down here.
3658 *
3659 * If there any entries in the Bios Page 2, then we wait
3660 * for discovery to complete.
3661 */
3662
3663 /* Current Boot Device */
3664 if ((ioc->bios_pg2.CurrentBootDeviceForm &
3665 MPI2_BIOSPAGE2_FORM_MASK) ==
3666 MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
3667 /* Request Boot Device */
3668 (ioc->bios_pg2.ReqBootDeviceForm &
3669 MPI2_BIOSPAGE2_FORM_MASK) ==
3670 MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
3671 /* Alternate Request Boot Device */
3672 (ioc->bios_pg2.ReqAltBootDeviceForm &
3673 MPI2_BIOSPAGE2_FORM_MASK) ==
3674 MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED)
3675 return 0;
3676
3677 return 1;
3678}
3679
3680
3681/**
3544 * _base_unmask_events - turn on notification for this event 3682 * _base_unmask_events - turn on notification for this event
3545 * @ioc: per adapter object 3683 * @ioc: per adapter object
3546 * @event: firmware event 3684 * @event: firmware event
@@ -3962,6 +4100,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3962 skip_init_reply_post_host_index: 4100 skip_init_reply_post_host_index:
3963 4101
3964 _base_unmask_interrupts(ioc); 4102 _base_unmask_interrupts(ioc);
4103
3965 r = _base_event_notification(ioc, sleep_flag); 4104 r = _base_event_notification(ioc, sleep_flag);
3966 if (r) 4105 if (r)
3967 return r; 4106 return r;
@@ -3969,7 +4108,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3969 if (sleep_flag == CAN_SLEEP) 4108 if (sleep_flag == CAN_SLEEP)
3970 _base_static_config_pages(ioc); 4109 _base_static_config_pages(ioc);
3971 4110
3972 if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) { 4111
4112 if (ioc->is_driver_loading) {
4113
4114
4115
4116 ioc->wait_for_discovery_to_complete =
4117 _base_determine_wait_on_discovery(ioc);
4118 return r; /* scan_start and scan_finished support */
4119 }
4120
4121
4122 if (ioc->wait_for_discovery_to_complete && ioc->is_warpdrive) {
3973 if (ioc->manu_pg10.OEMIdentifier == 0x80) { 4123 if (ioc->manu_pg10.OEMIdentifier == 0x80) {
3974 hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & 4124 hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
3975 MFG_PAGE10_HIDE_SSDS_MASK); 4125 MFG_PAGE10_HIDE_SSDS_MASK);
@@ -3978,13 +4128,6 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3978 } 4128 }
3979 } 4129 }
3980 4130
3981 if (ioc->wait_for_port_enable_to_complete) {
3982 if (diag_buffer_enable != 0)
3983 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
3984 if (disable_discovery > 0)
3985 return r;
3986 }
3987
3988 r = _base_send_port_enable(ioc, sleep_flag); 4131 r = _base_send_port_enable(ioc, sleep_flag);
3989 if (r) 4132 if (r)
3990 return r; 4133 return r;
@@ -4121,6 +4264,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4121 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 4264 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
4122 ioc->base_cmds.status = MPT2_CMD_NOT_USED; 4265 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
4123 4266
4267 /* port_enable command bits */
4268 ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
4269 ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
4270
4124 /* transport internal command bits */ 4271 /* transport internal command bits */
4125 ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 4272 ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
4126 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 4273 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
@@ -4162,8 +4309,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4162 goto out_free_resources; 4309 goto out_free_resources;
4163 } 4310 }
4164 4311
4165 init_completion(&ioc->shost_recovery_done);
4166
4167 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 4312 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
4168 ioc->event_masks[i] = -1; 4313 ioc->event_masks[i] = -1;
4169 4314
@@ -4186,7 +4331,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4186 _base_update_missing_delay(ioc, missing_delay[0], 4331 _base_update_missing_delay(ioc, missing_delay[0],
4187 missing_delay[1]); 4332 missing_delay[1]);
4188 4333
4189 mpt2sas_base_start_watchdog(ioc);
4190 return 0; 4334 return 0;
4191 4335
4192 out_free_resources: 4336 out_free_resources:
@@ -4204,6 +4348,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
4204 kfree(ioc->scsih_cmds.reply); 4348 kfree(ioc->scsih_cmds.reply);
4205 kfree(ioc->config_cmds.reply); 4349 kfree(ioc->config_cmds.reply);
4206 kfree(ioc->base_cmds.reply); 4350 kfree(ioc->base_cmds.reply);
4351 kfree(ioc->port_enable_cmds.reply);
4207 kfree(ioc->ctl_cmds.reply); 4352 kfree(ioc->ctl_cmds.reply);
4208 kfree(ioc->ctl_cmds.sense); 4353 kfree(ioc->ctl_cmds.sense);
4209 kfree(ioc->pfacts); 4354 kfree(ioc->pfacts);
@@ -4243,6 +4388,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
4243 kfree(ioc->ctl_cmds.reply); 4388 kfree(ioc->ctl_cmds.reply);
4244 kfree(ioc->ctl_cmds.sense); 4389 kfree(ioc->ctl_cmds.sense);
4245 kfree(ioc->base_cmds.reply); 4390 kfree(ioc->base_cmds.reply);
4391 kfree(ioc->port_enable_cmds.reply);
4246 kfree(ioc->tm_cmds.reply); 4392 kfree(ioc->tm_cmds.reply);
4247 kfree(ioc->transport_cmds.reply); 4393 kfree(ioc->transport_cmds.reply);
4248 kfree(ioc->scsih_cmds.reply); 4394 kfree(ioc->scsih_cmds.reply);
@@ -4284,6 +4430,20 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
4284 mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid); 4430 mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid);
4285 complete(&ioc->base_cmds.done); 4431 complete(&ioc->base_cmds.done);
4286 } 4432 }
4433 if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
4434 ioc->port_enable_failed = 1;
4435 ioc->port_enable_cmds.status |= MPT2_CMD_RESET;
4436 mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid);
4437 if (ioc->is_driver_loading) {
4438 ioc->start_scan_failed =
4439 MPI2_IOCSTATUS_INTERNAL_ERROR;
4440 ioc->start_scan = 0;
4441 ioc->port_enable_cmds.status =
4442 MPT2_CMD_NOT_USED;
4443 } else
4444 complete(&ioc->port_enable_cmds.done);
4445
4446 }
4287 if (ioc->config_cmds.status & MPT2_CMD_PENDING) { 4447 if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
4288 ioc->config_cmds.status |= MPT2_CMD_RESET; 4448 ioc->config_cmds.status |= MPT2_CMD_RESET;
4289 mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); 4449 mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid);
@@ -4349,7 +4509,6 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
4349{ 4509{
4350 int r; 4510 int r;
4351 unsigned long flags; 4511 unsigned long flags;
4352 u8 pe_complete = ioc->wait_for_port_enable_to_complete;
4353 4512
4354 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, 4513 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
4355 __func__)); 4514 __func__));
@@ -4396,7 +4555,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
4396 /* If this hard reset is called while port enable is active, then 4555 /* If this hard reset is called while port enable is active, then
4397 * there is no reason to call make_ioc_operational 4556 * there is no reason to call make_ioc_operational
4398 */ 4557 */
4399 if (pe_complete) { 4558 if (ioc->is_driver_loading && ioc->port_enable_failed) {
4559 ioc->remove_host = 1;
4400 r = -EFAULT; 4560 r = -EFAULT;
4401 goto out; 4561 goto out;
4402 } 4562 }
@@ -4410,7 +4570,6 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
4410 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 4570 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
4411 ioc->ioc_reset_in_progress_status = r; 4571 ioc->ioc_reset_in_progress_status = r;
4412 ioc->shost_recovery = 0; 4572 ioc->shost_recovery = 0;
4413 complete(&ioc->shost_recovery_done);
4414 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 4573 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
4415 mutex_unlock(&ioc->reset_in_progress_mutex); 4574 mutex_unlock(&ioc->reset_in_progress_mutex);
4416 4575
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 59354dba68c0..3c3babc7d260 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,11 +69,11 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "09.100.00.01" 72#define MPT2SAS_DRIVER_VERSION "10.100.00.00"
73#define MPT2SAS_MAJOR_VERSION 09 73#define MPT2SAS_MAJOR_VERSION 10
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 00 75#define MPT2SAS_BUILD_VERSION 00
76#define MPT2SAS_RELEASE_VERSION 01 76#define MPT2SAS_RELEASE_VERSION 00
77 77
78/* 78/*
79 * Set MPT2SAS_SG_DEPTH value based on user input. 79 * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -655,7 +655,12 @@ enum mutex_type {
655 * @ignore_loginfos: ignore loginfos during task management 655 * @ignore_loginfos: ignore loginfos during task management
656 * @remove_host: flag for when driver unloads, to avoid sending dev resets 656 * @remove_host: flag for when driver unloads, to avoid sending dev resets
657 * @pci_error_recovery: flag to prevent ioc access until slot reset completes 657 * @pci_error_recovery: flag to prevent ioc access until slot reset completes
658 * @wait_for_port_enable_to_complete: 658 * @wait_for_discovery_to_complete: flag set at driver load time when
659 * waiting on reporting devices
660 * @is_driver_loading: flag set at driver load time
661 * @port_enable_failed: flag set when port enable has failed
662 * @start_scan: flag set from scan_start callback, cleared from _mpt2sas_fw_work
663 * @start_scan_failed: means port enable failed, return's the ioc_status
659 * @msix_enable: flag indicating msix is enabled 664 * @msix_enable: flag indicating msix is enabled
660 * @msix_vector_count: number msix vectors 665 * @msix_vector_count: number msix vectors
661 * @cpu_msix_table: table for mapping cpus to msix index 666 * @cpu_msix_table: table for mapping cpus to msix index
@@ -790,15 +795,20 @@ struct MPT2SAS_ADAPTER {
790 u8 shost_recovery; 795 u8 shost_recovery;
791 796
792 struct mutex reset_in_progress_mutex; 797 struct mutex reset_in_progress_mutex;
793 struct completion shost_recovery_done;
794 spinlock_t ioc_reset_in_progress_lock; 798 spinlock_t ioc_reset_in_progress_lock;
795 u8 ioc_link_reset_in_progress; 799 u8 ioc_link_reset_in_progress;
796 int ioc_reset_in_progress_status; 800 u8 ioc_reset_in_progress_status;
797 801
798 u8 ignore_loginfos; 802 u8 ignore_loginfos;
799 u8 remove_host; 803 u8 remove_host;
800 u8 pci_error_recovery; 804 u8 pci_error_recovery;
801 u8 wait_for_port_enable_to_complete; 805 u8 wait_for_discovery_to_complete;
806 struct completion port_enable_done;
807 u8 is_driver_loading;
808 u8 port_enable_failed;
809
810 u8 start_scan;
811 u16 start_scan_failed;
802 812
803 u8 msix_enable; 813 u8 msix_enable;
804 u16 msix_vector_count; 814 u16 msix_vector_count;
@@ -814,11 +824,13 @@ struct MPT2SAS_ADAPTER {
814 u8 scsih_cb_idx; 824 u8 scsih_cb_idx;
815 u8 ctl_cb_idx; 825 u8 ctl_cb_idx;
816 u8 base_cb_idx; 826 u8 base_cb_idx;
827 u8 port_enable_cb_idx;
817 u8 config_cb_idx; 828 u8 config_cb_idx;
818 u8 tm_tr_cb_idx; 829 u8 tm_tr_cb_idx;
819 u8 tm_tr_volume_cb_idx; 830 u8 tm_tr_volume_cb_idx;
820 u8 tm_sas_control_cb_idx; 831 u8 tm_sas_control_cb_idx;
821 struct _internal_cmd base_cmds; 832 struct _internal_cmd base_cmds;
833 struct _internal_cmd port_enable_cmds;
822 struct _internal_cmd transport_cmds; 834 struct _internal_cmd transport_cmds;
823 struct _internal_cmd scsih_cmds; 835 struct _internal_cmd scsih_cmds;
824 struct _internal_cmd tm_cmds; 836 struct _internal_cmd tm_cmds;
@@ -1001,6 +1013,8 @@ void mpt2sas_base_release_callback_handler(u8 cb_idx);
1001 1013
1002u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 1014u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
1003 u32 reply); 1015 u32 reply);
1016u8 mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1017 u8 msix_index, u32 reply);
1004void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr); 1018void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);
1005 1019
1006u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked); 1020u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked);
@@ -1015,6 +1029,8 @@ void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_ty
1015 1029
1016void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc); 1030void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
1017 1031
1032int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);
1033
1018/* scsih shared API */ 1034/* scsih shared API */
1019u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 1035u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
1020 u32 reply); 1036 u32 reply);
@@ -1032,6 +1048,8 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAP
1032struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( 1048struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address(
1033 struct MPT2SAS_ADAPTER *ioc, u64 sas_address); 1049 struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
1034 1050
1051void mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc);
1052
1035void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); 1053void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
1036 1054
1037/* config shared API */ 1055/* config shared API */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 2b1101076cfe..36ea0b2d8020 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -1356,6 +1356,9 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1356 Mpi2ConfigReply_t mpi_reply; 1356 Mpi2ConfigReply_t mpi_reply;
1357 int r, i, config_page_sz; 1357 int r, i, config_page_sz;
1358 u16 ioc_status; 1358 u16 ioc_status;
1359 int config_num;
1360 u16 element_type;
1361 u16 phys_disk_dev_handle;
1359 1362
1360 *volume_handle = 0; 1363 *volume_handle = 0;
1361 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1364 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
@@ -1371,35 +1374,53 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1371 if (r) 1374 if (r)
1372 goto out; 1375 goto out;
1373 1376
1374 mpi_request.PageAddress =
1375 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
1376 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1377 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1377 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 1378 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
1378 config_page = kmalloc(config_page_sz, GFP_KERNEL); 1379 config_page = kmalloc(config_page_sz, GFP_KERNEL);
1379 if (!config_page) 1380 if (!config_page) {
1380 goto out; 1381 r = -1;
1381 r = _config_request(ioc, &mpi_request, &mpi_reply,
1382 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1383 config_page_sz);
1384 if (r)
1385 goto out; 1382 goto out;
1386 1383 }
1387 r = -1; 1384 config_num = 0xff;
1388 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; 1385 while (1) {
1389 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 1386 mpi_request.PageAddress = cpu_to_le32(config_num +
1390 goto out; 1387 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
1391 for (i = 0; i < config_page->NumElements; i++) { 1388 r = _config_request(ioc, &mpi_request, &mpi_reply,
1392 if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) & 1389 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1393 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) != 1390 config_page_sz);
1394 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT) 1391 if (r)
1395 continue; 1392 goto out;
1396 if (le16_to_cpu(config_page->ConfigElement[i]. 1393 r = -1;
1397 PhysDiskDevHandle) == pd_handle) { 1394 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1398 *volume_handle = le16_to_cpu(config_page-> 1395 MPI2_IOCSTATUS_MASK;
1399 ConfigElement[i].VolDevHandle); 1396 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1400 r = 0;
1401 goto out; 1397 goto out;
1398 for (i = 0; i < config_page->NumElements; i++) {
1399 element_type = le16_to_cpu(config_page->
1400 ConfigElement[i].ElementFlags) &
1401 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
1402 if (element_type ==
1403 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
1404 element_type ==
1405 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
1406 phys_disk_dev_handle =
1407 le16_to_cpu(config_page->ConfigElement[i].
1408 PhysDiskDevHandle);
1409 if (phys_disk_dev_handle == pd_handle) {
1410 *volume_handle =
1411 le16_to_cpu(config_page->
1412 ConfigElement[i].VolDevHandle);
1413 r = 0;
1414 goto out;
1415 }
1416 } else if (element_type ==
1417 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
1418 *volume_handle = 0;
1419 r = 0;
1420 goto out;
1421 }
1402 } 1422 }
1423 config_num = config_page->ConfigNum;
1403 } 1424 }
1404 out: 1425 out:
1405 kfree(config_page); 1426 kfree(config_page);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 9adb0133d6fb..aabcb911706e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -1207,6 +1207,9 @@ _ctl_do_reset(void __user *arg)
1207 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1207 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1208 return -ENODEV; 1208 return -ENODEV;
1209 1209
1210 if (ioc->shost_recovery || ioc->pci_error_recovery ||
1211 ioc->is_driver_loading)
1212 return -EAGAIN;
1210 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, 1213 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1211 __func__)); 1214 __func__));
1212 1215
@@ -2178,7 +2181,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
2178 !ioc) 2181 !ioc)
2179 return -ENODEV; 2182 return -ENODEV;
2180 2183
2181 if (ioc->shost_recovery || ioc->pci_error_recovery) 2184 if (ioc->shost_recovery || ioc->pci_error_recovery ||
2185 ioc->is_driver_loading)
2182 return -EAGAIN; 2186 return -EAGAIN;
2183 2187
2184 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { 2188 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
@@ -2297,7 +2301,8 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
2297 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc) 2301 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
2298 return -ENODEV; 2302 return -ENODEV;
2299 2303
2300 if (ioc->shost_recovery || ioc->pci_error_recovery) 2304 if (ioc->shost_recovery || ioc->pci_error_recovery ||
2305 ioc->is_driver_loading)
2301 return -EAGAIN; 2306 return -EAGAIN;
2302 2307
2303 memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); 2308 memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 1da1aa1a11e2..8889b1babcac 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -71,6 +71,9 @@ static void _firmware_event_work(struct work_struct *work);
71 71
72static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid); 72static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
73 73
74static void _scsih_scan_start(struct Scsi_Host *shost);
75static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
76
74/* global parameters */ 77/* global parameters */
75LIST_HEAD(mpt2sas_ioc_list); 78LIST_HEAD(mpt2sas_ioc_list);
76 79
@@ -79,6 +82,7 @@ static u8 scsi_io_cb_idx = -1;
79static u8 tm_cb_idx = -1; 82static u8 tm_cb_idx = -1;
80static u8 ctl_cb_idx = -1; 83static u8 ctl_cb_idx = -1;
81static u8 base_cb_idx = -1; 84static u8 base_cb_idx = -1;
85static u8 port_enable_cb_idx = -1;
82static u8 transport_cb_idx = -1; 86static u8 transport_cb_idx = -1;
83static u8 scsih_cb_idx = -1; 87static u8 scsih_cb_idx = -1;
84static u8 config_cb_idx = -1; 88static u8 config_cb_idx = -1;
@@ -103,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN;
103module_param(max_lun, int, 0); 107module_param(max_lun, int, 0);
104MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); 108MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
105 109
110/* diag_buffer_enable is bitwise
111 * bit 0 set = TRACE
112 * bit 1 set = SNAPSHOT
113 * bit 2 set = EXTENDED
114 *
115 * Either bit can be set, or both
116 */
117static int diag_buffer_enable = -1;
118module_param(diag_buffer_enable, int, 0);
119MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
120 "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
121
106/** 122/**
107 * struct sense_info - common structure for obtaining sense keys 123 * struct sense_info - common structure for obtaining sense keys
108 * @skey: sense key 124 * @skey: sense key
@@ -117,8 +133,8 @@ struct sense_info {
117 133
118 134
119#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) 135#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
120#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) 136#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
121 137#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
122/** 138/**
123 * struct fw_event_work - firmware event struct 139 * struct fw_event_work - firmware event struct
124 * @list: link list framework 140 * @list: link list framework
@@ -372,31 +388,34 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
372 Mpi2SasDevicePage0_t sas_device_pg0; 388 Mpi2SasDevicePage0_t sas_device_pg0;
373 Mpi2ConfigReply_t mpi_reply; 389 Mpi2ConfigReply_t mpi_reply;
374 u32 ioc_status; 390 u32 ioc_status;
391 *sas_address = 0;
375 392
376 if (handle <= ioc->sas_hba.num_phys) { 393 if (handle <= ioc->sas_hba.num_phys) {
377 *sas_address = ioc->sas_hba.sas_address; 394 *sas_address = ioc->sas_hba.sas_address;
378 return 0; 395 return 0;
379 } else 396 }
380 *sas_address = 0;
381 397
382 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 398 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
383 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 399 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
384 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 400 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
385 ioc->name, __FILE__, __LINE__, __func__); 401 __FILE__, __LINE__, __func__);
386 return -ENXIO; 402 return -ENXIO;
387 } 403 }
388 404
389 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 405 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
390 MPI2_IOCSTATUS_MASK; 406 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
391 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 407 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
392 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" 408 return 0;
393 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
394 __FILE__, __LINE__, __func__);
395 return -EIO;
396 } 409 }
397 410
398 *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 411 /* we hit this becuase the given parent handle doesn't exist */
399 return 0; 412 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
413 return -ENXIO;
414 /* else error case */
415 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x), "
416 "failure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
417 __FILE__, __LINE__, __func__);
418 return -EIO;
400} 419}
401 420
402/** 421/**
@@ -424,7 +443,11 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
424 u16 slot; 443 u16 slot;
425 444
426 /* only process this function when driver loads */ 445 /* only process this function when driver loads */
427 if (!ioc->wait_for_port_enable_to_complete) 446 if (!ioc->is_driver_loading)
447 return;
448
449 /* no Bios, return immediately */
450 if (!ioc->bios_pg3.BiosVersion)
428 return; 451 return;
429 452
430 if (!is_raid) { 453 if (!is_raid) {
@@ -587,8 +610,15 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
587 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 610 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
588 611
589 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 612 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
590 sas_device->sas_address_parent)) 613 sas_device->sas_address_parent)) {
591 _scsih_sas_device_remove(ioc, sas_device); 614 _scsih_sas_device_remove(ioc, sas_device);
615 } else if (!sas_device->starget) {
616 if (!ioc->is_driver_loading)
617 mpt2sas_transport_port_remove(ioc,
618 sas_device->sas_address,
619 sas_device->sas_address_parent);
620 _scsih_sas_device_remove(ioc, sas_device);
621 }
592} 622}
593 623
594/** 624/**
@@ -1400,6 +1430,10 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1400{ 1430{
1401 struct MPT2SAS_TARGET *sas_target_priv_data; 1431 struct MPT2SAS_TARGET *sas_target_priv_data;
1402 struct scsi_target *starget; 1432 struct scsi_target *starget;
1433 struct Scsi_Host *shost;
1434 struct MPT2SAS_ADAPTER *ioc;
1435 struct _sas_device *sas_device;
1436 unsigned long flags;
1403 1437
1404 if (!sdev->hostdata) 1438 if (!sdev->hostdata)
1405 return; 1439 return;
@@ -1407,6 +1441,19 @@ _scsih_slave_destroy(struct scsi_device *sdev)
1407 starget = scsi_target(sdev); 1441 starget = scsi_target(sdev);
1408 sas_target_priv_data = starget->hostdata; 1442 sas_target_priv_data = starget->hostdata;
1409 sas_target_priv_data->num_luns--; 1443 sas_target_priv_data->num_luns--;
1444
1445 shost = dev_to_shost(&starget->dev);
1446 ioc = shost_priv(shost);
1447
1448 if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
1449 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1450 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1451 sas_target_priv_data->sas_address);
1452 if (sas_device)
1453 sas_device->starget = NULL;
1454 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1455 }
1456
1410 kfree(sdev->hostdata); 1457 kfree(sdev->hostdata);
1411 sdev->hostdata = NULL; 1458 sdev->hostdata = NULL;
1412} 1459}
@@ -1598,8 +1645,10 @@ _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
1598 * _scsih_get_volume_capabilities - volume capabilities 1645 * _scsih_get_volume_capabilities - volume capabilities
1599 * @ioc: per adapter object 1646 * @ioc: per adapter object
1600 * @sas_device: the raid_device object 1647 * @sas_device: the raid_device object
1648 *
1649 * Returns 0 for success, else 1
1601 */ 1650 */
1602static void 1651static int
1603_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, 1652_scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1604 struct _raid_device *raid_device) 1653 struct _raid_device *raid_device)
1605{ 1654{
@@ -1612,9 +1661,10 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1612 1661
1613 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, 1662 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1614 &num_pds)) || !num_pds) { 1663 &num_pds)) || !num_pds) {
1615 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1664 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1616 ioc->name, __FILE__, __LINE__, __func__); 1665 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1617 return; 1666 __func__));
1667 return 1;
1618 } 1668 }
1619 1669
1620 raid_device->num_pds = num_pds; 1670 raid_device->num_pds = num_pds;
@@ -1622,17 +1672,19 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1622 sizeof(Mpi2RaidVol0PhysDisk_t)); 1672 sizeof(Mpi2RaidVol0PhysDisk_t));
1623 vol_pg0 = kzalloc(sz, GFP_KERNEL); 1673 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1624 if (!vol_pg0) { 1674 if (!vol_pg0) {
1625 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1675 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1626 ioc->name, __FILE__, __LINE__, __func__); 1676 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1627 return; 1677 __func__));
1678 return 1;
1628 } 1679 }
1629 1680
1630 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, 1681 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1631 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { 1682 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1632 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1683 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1633 ioc->name, __FILE__, __LINE__, __func__); 1684 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
1685 __func__));
1634 kfree(vol_pg0); 1686 kfree(vol_pg0);
1635 return; 1687 return 1;
1636 } 1688 }
1637 1689
1638 raid_device->volume_type = vol_pg0->VolumeType; 1690 raid_device->volume_type = vol_pg0->VolumeType;
@@ -1652,6 +1704,7 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1652 } 1704 }
1653 1705
1654 kfree(vol_pg0); 1706 kfree(vol_pg0);
1707 return 0;
1655} 1708}
1656/** 1709/**
1657 * _scsih_disable_ddio - Disable direct I/O for all the volumes 1710 * _scsih_disable_ddio - Disable direct I/O for all the volumes
@@ -1922,13 +1975,20 @@ _scsih_slave_configure(struct scsi_device *sdev)
1922 sas_target_priv_data->handle); 1975 sas_target_priv_data->handle);
1923 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1976 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1924 if (!raid_device) { 1977 if (!raid_device) {
1925 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1978 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1926 ioc->name, __FILE__, __LINE__, __func__); 1979 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1927 return 0; 1980 __LINE__, __func__));
1981 return 1;
1928 } 1982 }
1929 1983
1930 _scsih_get_volume_capabilities(ioc, raid_device); 1984 _scsih_get_volume_capabilities(ioc, raid_device);
1931 1985
1986 if (_scsih_get_volume_capabilities(ioc, raid_device)) {
1987 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
1988 "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
1989 __LINE__, __func__));
1990 return 1;
1991 }
1932 /* 1992 /*
1933 * WARPDRIVE: Initialize the required data for Direct IO 1993 * WARPDRIVE: Initialize the required data for Direct IO
1934 */ 1994 */
@@ -2002,11 +2062,22 @@ _scsih_slave_configure(struct scsi_device *sdev)
2002 if (sas_device) { 2062 if (sas_device) {
2003 if (sas_target_priv_data->flags & 2063 if (sas_target_priv_data->flags &
2004 MPT_TARGET_FLAGS_RAID_COMPONENT) { 2064 MPT_TARGET_FLAGS_RAID_COMPONENT) {
2005 mpt2sas_config_get_volume_handle(ioc, 2065 if (mpt2sas_config_get_volume_handle(ioc,
2006 sas_device->handle, &sas_device->volume_handle); 2066 sas_device->handle, &sas_device->volume_handle)) {
2007 mpt2sas_config_get_volume_wwid(ioc, 2067 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2068 "failure at %s:%d/%s()!\n", ioc->name,
2069 __FILE__, __LINE__, __func__));
2070 return 1;
2071 }
2072 if (sas_device->volume_handle &&
2073 mpt2sas_config_get_volume_wwid(ioc,
2008 sas_device->volume_handle, 2074 sas_device->volume_handle,
2009 &sas_device->volume_wwid); 2075 &sas_device->volume_wwid)) {
2076 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2077 "failure at %s:%d/%s()!\n", ioc->name,
2078 __FILE__, __LINE__, __func__));
2079 return 1;
2080 }
2010 } 2081 }
2011 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { 2082 if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
2012 qdepth = MPT2SAS_SAS_QUEUE_DEPTH; 2083 qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
@@ -2035,6 +2106,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
2035 2106
2036 if (!ssp_target) 2107 if (!ssp_target)
2037 _scsih_display_sata_capabilities(ioc, sas_device, sdev); 2108 _scsih_display_sata_capabilities(ioc, sas_device, sdev);
2109 } else {
2110 dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
2111 "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
2112 __func__));
2113 return 1;
2038 } 2114 }
2039 2115
2040 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 2116 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
@@ -2714,22 +2790,38 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
2714 2790
2715 2791
2716/** 2792/**
2717 * _scsih_queue_rescan - queue a topology rescan from user context 2793 * _scsih_error_recovery_delete_devices - remove devices not responding
2718 * @ioc: per adapter object 2794 * @ioc: per adapter object
2719 * 2795 *
2720 * Return nothing. 2796 * Return nothing.
2721 */ 2797 */
2722static void 2798static void
2723_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc) 2799_scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
2724{ 2800{
2725 struct fw_event_work *fw_event; 2801 struct fw_event_work *fw_event;
2726 2802
2727 if (ioc->wait_for_port_enable_to_complete) 2803 if (ioc->is_driver_loading)
2728 return; 2804 return;
2805 fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
2806 fw_event->ioc = ioc;
2807 _scsih_fw_event_add(ioc, fw_event);
2808}
2809
2810/**
2811 * mpt2sas_port_enable_complete - port enable completed (fake event)
2812 * @ioc: per adapter object
2813 *
2814 * Return nothing.
2815 */
2816void
2817mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
2818{
2819 struct fw_event_work *fw_event;
2820
2729 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 2821 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
2730 if (!fw_event) 2822 if (!fw_event)
2731 return; 2823 return;
2732 fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET; 2824 fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
2733 fw_event->ioc = ioc; 2825 fw_event->ioc = ioc;
2734 _scsih_fw_event_add(ioc, fw_event); 2826 _scsih_fw_event_add(ioc, fw_event);
2735} 2827}
@@ -2977,14 +3069,27 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2977 Mpi2SCSITaskManagementRequest_t *mpi_request; 3069 Mpi2SCSITaskManagementRequest_t *mpi_request;
2978 u16 smid; 3070 u16 smid;
2979 struct _sas_device *sas_device; 3071 struct _sas_device *sas_device;
2980 struct MPT2SAS_TARGET *sas_target_priv_data; 3072 struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
3073 u64 sas_address = 0;
2981 unsigned long flags; 3074 unsigned long flags;
2982 struct _tr_list *delayed_tr; 3075 struct _tr_list *delayed_tr;
3076 u32 ioc_state;
2983 3077
2984 if (ioc->shost_recovery || ioc->remove_host || 3078 if (ioc->remove_host) {
2985 ioc->pci_error_recovery) { 3079 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
2986 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3080 "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
2987 "progress!\n", __func__, ioc->name)); 3081 return;
3082 } else if (ioc->pci_error_recovery) {
3083 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3084 "error recovery: handle(0x%04x)\n", __func__, ioc->name,
3085 handle));
3086 return;
3087 }
3088 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3089 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3090 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3091 "operational: handle(0x%04x)\n", __func__, ioc->name,
3092 handle));
2988 return; 3093 return;
2989 } 3094 }
2990 3095
@@ -2998,13 +3103,18 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2998 sas_device->starget->hostdata) { 3103 sas_device->starget->hostdata) {
2999 sas_target_priv_data = sas_device->starget->hostdata; 3104 sas_target_priv_data = sas_device->starget->hostdata;
3000 sas_target_priv_data->deleted = 1; 3105 sas_target_priv_data->deleted = 1;
3001 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT 3106 sas_address = sas_device->sas_address;
3002 "setting delete flag: handle(0x%04x), "
3003 "sas_addr(0x%016llx)\n", ioc->name, handle,
3004 (unsigned long long) sas_device->sas_address));
3005 } 3107 }
3006 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 3108 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
3007 3109
3110 if (sas_target_priv_data) {
3111 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
3112 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
3113 (unsigned long long)sas_address));
3114 _scsih_ublock_io_device(ioc, handle);
3115 sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
3116 }
3117
3008 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 3118 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
3009 if (!smid) { 3119 if (!smid) {
3010 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); 3120 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
@@ -3185,11 +3295,21 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
3185 mpt2sas_base_get_reply_virt_addr(ioc, reply); 3295 mpt2sas_base_get_reply_virt_addr(ioc, reply);
3186 Mpi2SasIoUnitControlRequest_t *mpi_request; 3296 Mpi2SasIoUnitControlRequest_t *mpi_request;
3187 u16 smid_sas_ctrl; 3297 u16 smid_sas_ctrl;
3298 u32 ioc_state;
3188 3299
3189 if (ioc->shost_recovery || ioc->remove_host || 3300 if (ioc->remove_host) {
3190 ioc->pci_error_recovery) { 3301 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
3191 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 3302 "removed\n", __func__, ioc->name));
3192 "progress!\n", __func__, ioc->name)); 3303 return 1;
3304 } else if (ioc->pci_error_recovery) {
3305 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
3306 "error recovery\n", __func__, ioc->name));
3307 return 1;
3308 }
3309 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
3310 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
3311 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
3312 "operational\n", __func__, ioc->name));
3193 return 1; 3313 return 1;
3194 } 3314 }
3195 3315
@@ -5099,7 +5219,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
5099 /* get device name */ 5219 /* get device name */
5100 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); 5220 sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
5101 5221
5102 if (ioc->wait_for_port_enable_to_complete) 5222 if (ioc->wait_for_discovery_to_complete)
5103 _scsih_sas_device_init_add(ioc, sas_device); 5223 _scsih_sas_device_init_add(ioc, sas_device);
5104 else 5224 else
5105 _scsih_sas_device_add(ioc, sas_device); 5225 _scsih_sas_device_add(ioc, sas_device);
@@ -5135,6 +5255,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
5135 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { 5255 if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
5136 sas_target_priv_data = sas_device_backup.starget->hostdata; 5256 sas_target_priv_data = sas_device_backup.starget->hostdata;
5137 sas_target_priv_data->deleted = 1; 5257 sas_target_priv_data->deleted = 1;
5258 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
5259 sas_target_priv_data->handle =
5260 MPT2SAS_INVALID_DEVICE_HANDLE;
5138 } 5261 }
5139 5262
5140 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 5263 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
@@ -5288,7 +5411,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5288 _scsih_sas_topology_change_event_debug(ioc, event_data); 5411 _scsih_sas_topology_change_event_debug(ioc, event_data);
5289#endif 5412#endif
5290 5413
5291 if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) 5414 if (ioc->remove_host || ioc->pci_error_recovery)
5292 return; 5415 return;
5293 5416
5294 if (!ioc->sas_hba.num_phys) 5417 if (!ioc->sas_hba.num_phys)
@@ -5349,6 +5472,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5349 switch (reason_code) { 5472 switch (reason_code) {
5350 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 5473 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
5351 5474
5475 if (ioc->shost_recovery)
5476 break;
5477
5352 if (link_rate == prev_link_rate) 5478 if (link_rate == prev_link_rate)
5353 break; 5479 break;
5354 5480
@@ -5362,6 +5488,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
5362 break; 5488 break;
5363 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 5489 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
5364 5490
5491 if (ioc->shost_recovery)
5492 break;
5493
5365 mpt2sas_transport_update_links(ioc, sas_address, 5494 mpt2sas_transport_update_links(ioc, sas_address,
5366 handle, phy_number, link_rate); 5495 handle, phy_number, link_rate);
5367 5496
@@ -5622,7 +5751,7 @@ broadcast_aen_retry:
5622 termination_count = 0; 5751 termination_count = 0;
5623 query_count = 0; 5752 query_count = 0;
5624 for (smid = 1; smid <= ioc->scsiio_depth; smid++) { 5753 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
5625 if (ioc->ioc_reset_in_progress_status) 5754 if (ioc->shost_recovery)
5626 goto out; 5755 goto out;
5627 scmd = _scsih_scsi_lookup_get(ioc, smid); 5756 scmd = _scsih_scsi_lookup_get(ioc, smid);
5628 if (!scmd) 5757 if (!scmd)
@@ -5644,7 +5773,7 @@ broadcast_aen_retry:
5644 lun = sas_device_priv_data->lun; 5773 lun = sas_device_priv_data->lun;
5645 query_count++; 5774 query_count++;
5646 5775
5647 if (ioc->ioc_reset_in_progress_status) 5776 if (ioc->shost_recovery)
5648 goto out; 5777 goto out;
5649 5778
5650 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 5779 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -5686,7 +5815,7 @@ broadcast_aen_retry:
5686 goto broadcast_aen_retry; 5815 goto broadcast_aen_retry;
5687 } 5816 }
5688 5817
5689 if (ioc->ioc_reset_in_progress_status) 5818 if (ioc->shost_recovery)
5690 goto out_no_lock; 5819 goto out_no_lock;
5691 5820
5692 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, 5821 r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
@@ -5725,7 +5854,7 @@ broadcast_aen_retry:
5725 ioc->name, __func__, query_count, termination_count)); 5854 ioc->name, __func__, query_count, termination_count));
5726 5855
5727 ioc->broadcast_aen_busy = 0; 5856 ioc->broadcast_aen_busy = 0;
5728 if (!ioc->ioc_reset_in_progress_status) 5857 if (!ioc->shost_recovery)
5729 _scsih_ublock_io_all_device(ioc); 5858 _scsih_ublock_io_all_device(ioc);
5730 mutex_unlock(&ioc->tm_cmds.mutex); 5859 mutex_unlock(&ioc->tm_cmds.mutex);
5731} 5860}
@@ -5789,8 +5918,11 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
5789static void 5918static void
5790_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach) 5919_scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
5791{ 5920{
5792 struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata; 5921 struct MPT2SAS_TARGET *sas_target_priv_data;
5793 5922
5923 if (starget == NULL)
5924 return;
5925 sas_target_priv_data = starget->hostdata;
5794 if (no_uld_attach) 5926 if (no_uld_attach)
5795 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT; 5927 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
5796 else 5928 else
@@ -5845,7 +5977,7 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
5845 raid_device->handle = handle; 5977 raid_device->handle = handle;
5846 raid_device->wwid = wwid; 5978 raid_device->wwid = wwid;
5847 _scsih_raid_device_add(ioc, raid_device); 5979 _scsih_raid_device_add(ioc, raid_device);
5848 if (!ioc->wait_for_port_enable_to_complete) { 5980 if (!ioc->wait_for_discovery_to_complete) {
5849 rc = scsi_add_device(ioc->shost, RAID_CHANNEL, 5981 rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
5850 raid_device->id, 0); 5982 raid_device->id, 0);
5851 if (rc) 5983 if (rc)
@@ -6127,6 +6259,10 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
6127 _scsih_sas_ir_config_change_event_debug(ioc, event_data); 6259 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
6128 6260
6129#endif 6261#endif
6262
6263 if (ioc->shost_recovery)
6264 return;
6265
6130 foreign_config = (le32_to_cpu(event_data->Flags) & 6266 foreign_config = (le32_to_cpu(event_data->Flags) &
6131 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; 6267 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
6132 6268
@@ -6185,6 +6321,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
6185 int rc; 6321 int rc;
6186 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 6322 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
6187 6323
6324 if (ioc->shost_recovery)
6325 return;
6326
6188 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 6327 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
6189 return; 6328 return;
6190 6329
@@ -6267,6 +6406,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
6267 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; 6406 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
6268 u64 sas_address; 6407 u64 sas_address;
6269 6408
6409 if (ioc->shost_recovery)
6410 return;
6411
6270 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 6412 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
6271 return; 6413 return;
6272 6414
@@ -6510,10 +6652,10 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6510 u32 device_info; 6652 u32 device_info;
6511 u16 slot; 6653 u16 slot;
6512 6654
6513 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6655 printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
6514 6656
6515 if (list_empty(&ioc->sas_device_list)) 6657 if (list_empty(&ioc->sas_device_list))
6516 return; 6658 goto out;
6517 6659
6518 handle = 0xFFFF; 6660 handle = 0xFFFF;
6519 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 6661 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -6532,6 +6674,9 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6532 _scsih_mark_responding_sas_device(ioc, sas_address, slot, 6674 _scsih_mark_responding_sas_device(ioc, sas_address, slot,
6533 handle); 6675 handle);
6534 } 6676 }
6677out:
6678 printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
6679 ioc->name);
6535} 6680}
6536 6681
6537/** 6682/**
@@ -6607,10 +6752,14 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6607 u16 handle; 6752 u16 handle;
6608 u8 phys_disk_num; 6753 u8 phys_disk_num;
6609 6754
6610 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6755 if (!ioc->ir_firmware)
6756 return;
6757
6758 printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
6759 ioc->name);
6611 6760
6612 if (list_empty(&ioc->raid_device_list)) 6761 if (list_empty(&ioc->raid_device_list))
6613 return; 6762 goto out;
6614 6763
6615 handle = 0xFFFF; 6764 handle = 0xFFFF;
6616 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, 6765 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -6649,6 +6798,9 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6649 set_bit(handle, ioc->pd_handles); 6798 set_bit(handle, ioc->pd_handles);
6650 } 6799 }
6651 } 6800 }
6801out:
6802 printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
6803 "complete\n", ioc->name);
6652} 6804}
6653 6805
6654/** 6806/**
@@ -6708,10 +6860,10 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6708 u64 sas_address; 6860 u64 sas_address;
6709 u16 handle; 6861 u16 handle;
6710 6862
6711 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 6863 printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
6712 6864
6713 if (list_empty(&ioc->sas_expander_list)) 6865 if (list_empty(&ioc->sas_expander_list))
6714 return; 6866 goto out;
6715 6867
6716 handle = 0xFFFF; 6868 handle = 0xFFFF;
6717 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, 6869 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -6730,6 +6882,8 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6730 _scsih_mark_responding_expander(ioc, sas_address, handle); 6882 _scsih_mark_responding_expander(ioc, sas_address, handle);
6731 } 6883 }
6732 6884
6885 out:
6886 printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
6733} 6887}
6734 6888
6735/** 6889/**
@@ -6745,6 +6899,8 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6745 struct _sas_node *sas_expander; 6899 struct _sas_node *sas_expander;
6746 struct _raid_device *raid_device, *raid_device_next; 6900 struct _raid_device *raid_device, *raid_device_next;
6747 6901
6902 printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
6903 ioc->name);
6748 6904
6749 list_for_each_entry_safe(sas_device, sas_device_next, 6905 list_for_each_entry_safe(sas_device, sas_device_next,
6750 &ioc->sas_device_list, list) { 6906 &ioc->sas_device_list, list) {
@@ -6764,6 +6920,9 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6764 _scsih_remove_device(ioc, sas_device); 6920 _scsih_remove_device(ioc, sas_device);
6765 } 6921 }
6766 6922
6923 if (!ioc->ir_firmware)
6924 goto retry_expander_search;
6925
6767 list_for_each_entry_safe(raid_device, raid_device_next, 6926 list_for_each_entry_safe(raid_device, raid_device_next,
6768 &ioc->raid_device_list, list) { 6927 &ioc->raid_device_list, list) {
6769 if (raid_device->responding) { 6928 if (raid_device->responding) {
@@ -6790,52 +6949,170 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6790 mpt2sas_expander_remove(ioc, sas_expander->sas_address); 6949 mpt2sas_expander_remove(ioc, sas_expander->sas_address);
6791 goto retry_expander_search; 6950 goto retry_expander_search;
6792 } 6951 }
6952 printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
6953 ioc->name);
6954 /* unblock devices */
6955 _scsih_ublock_io_all_device(ioc);
6956}
6957
6958static void
6959_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
6960 struct _sas_node *sas_expander, u16 handle)
6961{
6962 Mpi2ExpanderPage1_t expander_pg1;
6963 Mpi2ConfigReply_t mpi_reply;
6964 int i;
6965
6966 for (i = 0 ; i < sas_expander->num_phys ; i++) {
6967 if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
6968 &expander_pg1, i, handle))) {
6969 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
6970 ioc->name, __FILE__, __LINE__, __func__);
6971 return;
6972 }
6973
6974 mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
6975 le16_to_cpu(expander_pg1.AttachedDevHandle), i,
6976 expander_pg1.NegotiatedLinkRate >> 4);
6977 }
6793} 6978}
6794 6979
6795/** 6980/**
6796 * _scsih_hide_unhide_sas_devices - add/remove device to/from OS 6981 * _scsih_scan_for_devices_after_reset - scan for devices after host reset
6797 * @ioc: per adapter object 6982 * @ioc: per adapter object
6798 * 6983 *
6799 * Return nothing. 6984 * Return nothing.
6800 */ 6985 */
6801static void 6986static void
6802_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc) 6987_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
6803{ 6988{
6804 struct _sas_device *sas_device, *sas_device_next; 6989 Mpi2ExpanderPage0_t expander_pg0;
6990 Mpi2SasDevicePage0_t sas_device_pg0;
6991 Mpi2RaidVolPage1_t volume_pg1;
6992 Mpi2RaidVolPage0_t volume_pg0;
6993 Mpi2RaidPhysDiskPage0_t pd_pg0;
6994 Mpi2EventIrConfigElement_t element;
6995 Mpi2ConfigReply_t mpi_reply;
6996 u8 phys_disk_num;
6997 u16 ioc_status;
6998 u16 handle, parent_handle;
6999 u64 sas_address;
7000 struct _sas_device *sas_device;
7001 struct _sas_node *expander_device;
7002 static struct _raid_device *raid_device;
6805 7003
6806 if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag != 7004 printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
6807 MFG_PAGE10_HIDE_IF_VOL_PRESENT)
6808 return;
6809 7005
6810 if (ioc->hide_drives) { 7006 _scsih_sas_host_refresh(ioc);
6811 if (_scsih_get_num_volumes(ioc)) 7007
6812 return; 7008 /* expanders */
6813 ioc->hide_drives = 0; 7009 handle = 0xFFFF;
6814 list_for_each_entry_safe(sas_device, sas_device_next, 7010 while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
6815 &ioc->sas_device_list, list) { 7011 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
6816 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7012 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6817 sas_device->sas_address_parent)) { 7013 MPI2_IOCSTATUS_MASK;
6818 _scsih_sas_device_remove(ioc, sas_device); 7014 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
6819 } else if (!sas_device->starget) { 7015 break;
6820 mpt2sas_transport_port_remove(ioc, 7016 handle = le16_to_cpu(expander_pg0.DevHandle);
6821 sas_device->sas_address, 7017 expander_device = mpt2sas_scsih_expander_find_by_sas_address(
6822 sas_device->sas_address_parent); 7018 ioc, le64_to_cpu(expander_pg0.SASAddress));
6823 _scsih_sas_device_remove(ioc, sas_device); 7019 if (expander_device)
6824 } 7020 _scsih_refresh_expander_links(ioc, expander_device,
7021 handle);
7022 else
7023 _scsih_expander_add(ioc, handle);
7024 }
7025
7026 if (!ioc->ir_firmware)
7027 goto skip_to_sas;
7028
7029 /* phys disk */
7030 phys_disk_num = 0xFF;
7031 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
7032 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
7033 phys_disk_num))) {
7034 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7035 MPI2_IOCSTATUS_MASK;
7036 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7037 break;
7038 phys_disk_num = pd_pg0.PhysDiskNum;
7039 handle = le16_to_cpu(pd_pg0.DevHandle);
7040 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
7041 if (sas_device)
7042 continue;
7043 if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7044 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
7045 handle) != 0)
7046 continue;
7047 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7048 if (!_scsih_get_sas_address(ioc, parent_handle,
7049 &sas_address)) {
7050 mpt2sas_transport_update_links(ioc, sas_address,
7051 handle, sas_device_pg0.PhyNum,
7052 MPI2_SAS_NEG_LINK_RATE_1_5);
7053 set_bit(handle, ioc->pd_handles);
7054 _scsih_add_device(ioc, handle, 0, 1);
6825 } 7055 }
6826 } else { 7056 }
6827 if (!_scsih_get_num_volumes(ioc)) 7057
6828 return; 7058 /* volumes */
6829 ioc->hide_drives = 1; 7059 handle = 0xFFFF;
6830 list_for_each_entry_safe(sas_device, sas_device_next, 7060 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
6831 &ioc->sas_device_list, list) { 7061 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
6832 mpt2sas_transport_port_remove(ioc, 7062 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6833 sas_device->sas_address, 7063 MPI2_IOCSTATUS_MASK;
6834 sas_device->sas_address_parent); 7064 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7065 break;
7066 handle = le16_to_cpu(volume_pg1.DevHandle);
7067 raid_device = _scsih_raid_device_find_by_wwid(ioc,
7068 le64_to_cpu(volume_pg1.WWID));
7069 if (raid_device)
7070 continue;
7071 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
7072 &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
7073 sizeof(Mpi2RaidVolPage0_t)))
7074 continue;
7075 if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
7076 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
7077 volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
7078 memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
7079 element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
7080 element.VolDevHandle = volume_pg1.DevHandle;
7081 _scsih_sas_volume_add(ioc, &element);
6835 } 7082 }
6836 } 7083 }
7084
7085 skip_to_sas:
7086
7087 /* sas devices */
7088 handle = 0xFFFF;
7089 while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
7090 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
7091 handle))) {
7092 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7093 MPI2_IOCSTATUS_MASK;
7094 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7095 break;
7096 handle = le16_to_cpu(sas_device_pg0.DevHandle);
7097 if (!(_scsih_is_end_device(
7098 le32_to_cpu(sas_device_pg0.DeviceInfo))))
7099 continue;
7100 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
7101 le64_to_cpu(sas_device_pg0.SASAddress));
7102 if (sas_device)
7103 continue;
7104 parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
7105 if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
7106 mpt2sas_transport_update_links(ioc, sas_address, handle,
7107 sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
7108 _scsih_add_device(ioc, handle, 0, 0);
7109 }
7110 }
7111
7112 printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
6837} 7113}
6838 7114
7115
6839/** 7116/**
6840 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) 7117 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
6841 * @ioc: per adapter object 7118 * @ioc: per adapter object
@@ -6871,7 +7148,6 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6871 } 7148 }
6872 _scsih_fw_event_cleanup_queue(ioc); 7149 _scsih_fw_event_cleanup_queue(ioc);
6873 _scsih_flush_running_cmds(ioc); 7150 _scsih_flush_running_cmds(ioc);
6874 _scsih_queue_rescan(ioc);
6875 break; 7151 break;
6876 case MPT2_IOC_DONE_RESET: 7152 case MPT2_IOC_DONE_RESET:
6877 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " 7153 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
@@ -6881,6 +7157,13 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
6881 _scsih_search_responding_sas_devices(ioc); 7157 _scsih_search_responding_sas_devices(ioc);
6882 _scsih_search_responding_raid_devices(ioc); 7158 _scsih_search_responding_raid_devices(ioc);
6883 _scsih_search_responding_expanders(ioc); 7159 _scsih_search_responding_expanders(ioc);
7160 if (!ioc->is_driver_loading) {
7161 _scsih_prep_device_scan(ioc);
7162 _scsih_search_responding_sas_devices(ioc);
7163 _scsih_search_responding_raid_devices(ioc);
7164 _scsih_search_responding_expanders(ioc);
7165 _scsih_error_recovery_delete_devices(ioc);
7166 }
6884 break; 7167 break;
6885 } 7168 }
6886} 7169}
@@ -6898,7 +7181,6 @@ _firmware_event_work(struct work_struct *work)
6898{ 7181{
6899 struct fw_event_work *fw_event = container_of(work, 7182 struct fw_event_work *fw_event = container_of(work,
6900 struct fw_event_work, delayed_work.work); 7183 struct fw_event_work, delayed_work.work);
6901 unsigned long flags;
6902 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; 7184 struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
6903 7185
6904 /* the queue is being flushed so ignore this event */ 7186 /* the queue is being flushed so ignore this event */
@@ -6908,23 +7190,21 @@ _firmware_event_work(struct work_struct *work)
6908 return; 7190 return;
6909 } 7191 }
6910 7192
6911 if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) { 7193 switch (fw_event->event) {
6912 _scsih_fw_event_free(ioc, fw_event); 7194 case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
6913 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 7195 while (scsi_host_in_recovery(ioc->shost))
6914 if (ioc->shost_recovery) { 7196 ssleep(1);
6915 init_completion(&ioc->shost_recovery_done);
6916 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6917 flags);
6918 wait_for_completion(&ioc->shost_recovery_done);
6919 } else
6920 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6921 flags);
6922 _scsih_remove_unresponding_sas_devices(ioc); 7197 _scsih_remove_unresponding_sas_devices(ioc);
6923 _scsih_hide_unhide_sas_devices(ioc); 7198 _scsih_scan_for_devices_after_reset(ioc);
6924 return; 7199 break;
6925 } 7200 case MPT2SAS_PORT_ENABLE_COMPLETE:
7201 ioc->start_scan = 0;
6926 7202
6927 switch (fw_event->event) { 7203
7204
7205 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
7206 "from worker thread\n", ioc->name));
7207 break;
6928 case MPT2SAS_TURN_ON_FAULT_LED: 7208 case MPT2SAS_TURN_ON_FAULT_LED:
6929 _scsih_turn_on_fault_led(ioc, fw_event->device_handle); 7209 _scsih_turn_on_fault_led(ioc, fw_event->device_handle);
6930 break; 7210 break;
@@ -7121,6 +7401,8 @@ static struct scsi_host_template scsih_driver_template = {
7121 .slave_configure = _scsih_slave_configure, 7401 .slave_configure = _scsih_slave_configure,
7122 .target_destroy = _scsih_target_destroy, 7402 .target_destroy = _scsih_target_destroy,
7123 .slave_destroy = _scsih_slave_destroy, 7403 .slave_destroy = _scsih_slave_destroy,
7404 .scan_finished = _scsih_scan_finished,
7405 .scan_start = _scsih_scan_start,
7124 .change_queue_depth = _scsih_change_queue_depth, 7406 .change_queue_depth = _scsih_change_queue_depth,
7125 .change_queue_type = _scsih_change_queue_type, 7407 .change_queue_type = _scsih_change_queue_type,
7126 .eh_abort_handler = _scsih_abort, 7408 .eh_abort_handler = _scsih_abort,
@@ -7381,7 +7663,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7381 unsigned long flags; 7663 unsigned long flags;
7382 int rc; 7664 int rc;
7383 7665
7666 /* no Bios, return immediately */
7667 if (!ioc->bios_pg3.BiosVersion)
7668 return;
7669
7384 device = NULL; 7670 device = NULL;
7671 is_raid = 0;
7385 if (ioc->req_boot_device.device) { 7672 if (ioc->req_boot_device.device) {
7386 device = ioc->req_boot_device.device; 7673 device = ioc->req_boot_device.device;
7387 is_raid = ioc->req_boot_device.is_raid; 7674 is_raid = ioc->req_boot_device.is_raid;
@@ -7417,8 +7704,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7417 sas_device->sas_address_parent)) { 7704 sas_device->sas_address_parent)) {
7418 _scsih_sas_device_remove(ioc, sas_device); 7705 _scsih_sas_device_remove(ioc, sas_device);
7419 } else if (!sas_device->starget) { 7706 } else if (!sas_device->starget) {
7420 mpt2sas_transport_port_remove(ioc, sas_address, 7707 if (!ioc->is_driver_loading)
7421 sas_address_parent); 7708 mpt2sas_transport_port_remove(ioc, sas_address,
7709 sas_address_parent);
7422 _scsih_sas_device_remove(ioc, sas_device); 7710 _scsih_sas_device_remove(ioc, sas_device);
7423 } 7711 }
7424 } 7712 }
@@ -7462,22 +7750,28 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7462 /* SAS Device List */ 7750 /* SAS Device List */
7463 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, 7751 list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
7464 list) { 7752 list) {
7465 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7466 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7467 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7468 7753
7469 if (ioc->hide_drives) 7754 if (ioc->hide_drives)
7470 continue; 7755 continue;
7471 7756
7472 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7757 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
7473 sas_device->sas_address_parent)) { 7758 sas_device->sas_address_parent)) {
7474 _scsih_sas_device_remove(ioc, sas_device); 7759 list_del(&sas_device->list);
7760 kfree(sas_device);
7761 continue;
7475 } else if (!sas_device->starget) { 7762 } else if (!sas_device->starget) {
7476 mpt2sas_transport_port_remove(ioc, 7763 if (!ioc->is_driver_loading)
7477 sas_device->sas_address, 7764 mpt2sas_transport_port_remove(ioc,
7478 sas_device->sas_address_parent); 7765 sas_device->sas_address,
7479 _scsih_sas_device_remove(ioc, sas_device); 7766 sas_device->sas_address_parent);
7767 list_del(&sas_device->list);
7768 kfree(sas_device);
7769 continue;
7770
7480 } 7771 }
7772 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7773 list_move_tail(&sas_device->list, &ioc->sas_device_list);
7774 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7481 } 7775 }
7482} 7776}
7483 7777
@@ -7490,9 +7784,7 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7490static void 7784static void
7491_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc) 7785_scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7492{ 7786{
7493 u16 volume_mapping_flags = 7787 u16 volume_mapping_flags;
7494 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7495 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7496 7788
7497 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR)) 7789 if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
7498 return; /* return when IOC doesn't support initiator mode */ 7790 return; /* return when IOC doesn't support initiator mode */
@@ -7500,18 +7792,93 @@ _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
7500 _scsih_probe_boot_devices(ioc); 7792 _scsih_probe_boot_devices(ioc);
7501 7793
7502 if (ioc->ir_firmware) { 7794 if (ioc->ir_firmware) {
7503 if ((volume_mapping_flags & 7795 volume_mapping_flags =
7504 MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) { 7796 le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
7505 _scsih_probe_sas(ioc); 7797 MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
7798 if (volume_mapping_flags ==
7799 MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
7506 _scsih_probe_raid(ioc); 7800 _scsih_probe_raid(ioc);
7801 _scsih_probe_sas(ioc);
7507 } else { 7802 } else {
7508 _scsih_probe_raid(ioc);
7509 _scsih_probe_sas(ioc); 7803 _scsih_probe_sas(ioc);
7804 _scsih_probe_raid(ioc);
7510 } 7805 }
7511 } else 7806 } else
7512 _scsih_probe_sas(ioc); 7807 _scsih_probe_sas(ioc);
7513} 7808}
7514 7809
7810
7811/**
7812 * _scsih_scan_start - scsi lld callback for .scan_start
7813 * @shost: SCSI host pointer
7814 *
7815 * The shost has the ability to discover targets on its own instead
7816 * of scanning the entire bus. In our implemention, we will kick off
7817 * firmware discovery.
7818 */
7819static void
7820_scsih_scan_start(struct Scsi_Host *shost)
7821{
7822 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7823 int rc;
7824
7825 if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
7826 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
7827
7828 ioc->start_scan = 1;
7829 rc = mpt2sas_port_enable(ioc);
7830
7831 if (rc != 0)
7832 printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
7833}
7834
7835/**
7836 * _scsih_scan_finished - scsi lld callback for .scan_finished
7837 * @shost: SCSI host pointer
7838 * @time: elapsed time of the scan in jiffies
7839 *
7840 * This function will be called periodically until it returns 1 with the
7841 * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
7842 * we wait for firmware discovery to complete, then return 1.
7843 */
7844static int
7845_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
7846{
7847 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
7848
7849 if (time >= (300 * HZ)) {
7850 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7851 printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
7852 "(timeout=300s)\n", ioc->name);
7853 ioc->is_driver_loading = 0;
7854 return 1;
7855 }
7856
7857 if (ioc->start_scan)
7858 return 0;
7859
7860 if (ioc->start_scan_failed) {
7861 printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
7862 "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
7863 ioc->is_driver_loading = 0;
7864 ioc->wait_for_discovery_to_complete = 0;
7865 ioc->remove_host = 1;
7866 return 1;
7867 }
7868
7869 printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
7870 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
7871
7872 if (ioc->wait_for_discovery_to_complete) {
7873 ioc->wait_for_discovery_to_complete = 0;
7874 _scsih_probe_devices(ioc);
7875 }
7876 mpt2sas_base_start_watchdog(ioc);
7877 ioc->is_driver_loading = 0;
7878 return 1;
7879}
7880
7881
7515/** 7882/**
7516 * _scsih_probe - attach and add scsi host 7883 * _scsih_probe - attach and add scsi host
7517 * @pdev: PCI device struct 7884 * @pdev: PCI device struct
@@ -7548,6 +7915,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7548 ioc->tm_cb_idx = tm_cb_idx; 7915 ioc->tm_cb_idx = tm_cb_idx;
7549 ioc->ctl_cb_idx = ctl_cb_idx; 7916 ioc->ctl_cb_idx = ctl_cb_idx;
7550 ioc->base_cb_idx = base_cb_idx; 7917 ioc->base_cb_idx = base_cb_idx;
7918 ioc->port_enable_cb_idx = port_enable_cb_idx;
7551 ioc->transport_cb_idx = transport_cb_idx; 7919 ioc->transport_cb_idx = transport_cb_idx;
7552 ioc->scsih_cb_idx = scsih_cb_idx; 7920 ioc->scsih_cb_idx = scsih_cb_idx;
7553 ioc->config_cb_idx = config_cb_idx; 7921 ioc->config_cb_idx = config_cb_idx;
@@ -7620,14 +7988,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7620 goto out_thread_fail; 7988 goto out_thread_fail;
7621 } 7989 }
7622 7990
7623 ioc->wait_for_port_enable_to_complete = 1; 7991 ioc->is_driver_loading = 1;
7624 if ((mpt2sas_base_attach(ioc))) { 7992 if ((mpt2sas_base_attach(ioc))) {
7625 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 7993 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
7626 ioc->name, __FILE__, __LINE__, __func__); 7994 ioc->name, __FILE__, __LINE__, __func__);
7627 goto out_attach_fail; 7995 goto out_attach_fail;
7628 } 7996 }
7629 7997
7630 ioc->wait_for_port_enable_to_complete = 0; 7998 scsi_scan_host(shost);
7631 if (ioc->is_warpdrive) { 7999 if (ioc->is_warpdrive) {
7632 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) 8000 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
7633 ioc->hide_drives = 0; 8001 ioc->hide_drives = 0;
@@ -7650,6 +8018,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7650 out_thread_fail: 8018 out_thread_fail:
7651 list_del(&ioc->list); 8019 list_del(&ioc->list);
7652 scsi_remove_host(shost); 8020 scsi_remove_host(shost);
8021 scsi_host_put(shost);
7653 out_add_shost_fail: 8022 out_add_shost_fail:
7654 return -ENODEV; 8023 return -ENODEV;
7655} 8024}
@@ -7896,6 +8265,8 @@ _scsih_init(void)
7896 8265
7897 /* base internal commands callback handler */ 8266 /* base internal commands callback handler */
7898 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done); 8267 base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
8268 port_enable_cb_idx = mpt2sas_base_register_callback_handler(
8269 mpt2sas_port_enable_done);
7899 8270
7900 /* transport internal commands callback handler */ 8271 /* transport internal commands callback handler */
7901 transport_cb_idx = mpt2sas_base_register_callback_handler( 8272 transport_cb_idx = mpt2sas_base_register_callback_handler(
@@ -7950,6 +8321,7 @@ _scsih_exit(void)
7950 mpt2sas_base_release_callback_handler(scsi_io_cb_idx); 8321 mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
7951 mpt2sas_base_release_callback_handler(tm_cb_idx); 8322 mpt2sas_base_release_callback_handler(tm_cb_idx);
7952 mpt2sas_base_release_callback_handler(base_cb_idx); 8323 mpt2sas_base_release_callback_handler(base_cb_idx);
8324 mpt2sas_base_release_callback_handler(port_enable_cb_idx);
7953 mpt2sas_base_release_callback_handler(transport_cb_idx); 8325 mpt2sas_base_release_callback_handler(transport_cb_idx);
7954 mpt2sas_base_release_callback_handler(scsih_cb_idx); 8326 mpt2sas_base_release_callback_handler(scsih_cb_idx);
7955 mpt2sas_base_release_callback_handler(config_cb_idx); 8327 mpt2sas_base_release_callback_handler(config_cb_idx);
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 621b5e072758..6f589195746c 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -732,6 +732,16 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = {
732 .class_mask = 0, 732 .class_mask = 0,
733 .driver_data = chip_9485, 733 .driver_data = chip_9485,
734 }, 734 },
735 { PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */
736 { PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
737 { PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
738 { PCI_VDEVICE(OCZ, 0x1041), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
739 { PCI_VDEVICE(OCZ, 0x1042), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
740 { PCI_VDEVICE(OCZ, 0x1043), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
741 { PCI_VDEVICE(OCZ, 0x1044), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
742 { PCI_VDEVICE(OCZ, 0x1080), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
743 { PCI_VDEVICE(OCZ, 0x1083), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
744 { PCI_VDEVICE(OCZ, 0x1084), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
735 745
736 { } /* terminate list */ 746 { } /* terminate list */
737}; 747};
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index b86db84d6f32..5163edb925cb 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -4102,7 +4102,7 @@ static long pmcraid_chr_ioctl(
4102 struct pmcraid_ioctl_header *hdr = NULL; 4102 struct pmcraid_ioctl_header *hdr = NULL;
4103 int retval = -ENOTTY; 4103 int retval = -ENOTTY;
4104 4104
4105 hdr = kmalloc(GFP_KERNEL, sizeof(struct pmcraid_ioctl_header)); 4105 hdr = kmalloc(sizeof(struct pmcraid_ioctl_header), GFP_KERNEL);
4106 4106
4107 if (!hdr) { 4107 if (!hdr) {
4108 pmcraid_err("faile to allocate memory for ioctl header\n"); 4108 pmcraid_err("faile to allocate memory for ioctl header\n");
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 3474e86e98ab..2516adf1aeea 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2279,7 +2279,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
2279 ha = rsp->hw; 2279 ha = rsp->hw;
2280 2280
2281 /* Clear the interrupt, if enabled, for this response queue */ 2281 /* Clear the interrupt, if enabled, for this response queue */
2282 if (rsp->options & ~BIT_6) { 2282 if (!ha->flags.disable_msix_handshake) {
2283 reg = &ha->iobase->isp24; 2283 reg = &ha->iobase->isp24;
2284 spin_lock_irqsave(&ha->hardware_lock, flags); 2284 spin_lock_irqsave(&ha->hardware_lock, flags);
2285 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT); 2285 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index fc3f168decb4..b4d43ae76132 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1698,6 +1698,15 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
1698 1698
1699void scsi_free_queue(struct request_queue *q) 1699void scsi_free_queue(struct request_queue *q)
1700{ 1700{
1701 unsigned long flags;
1702
1703 WARN_ON(q->queuedata);
1704
1705 /* cause scsi_request_fn() to kill all non-finished requests */
1706 spin_lock_irqsave(q->queue_lock, flags);
1707 q->request_fn(q);
1708 spin_unlock_irqrestore(q->queue_lock, flags);
1709
1701 blk_cleanup_queue(q); 1710 blk_cleanup_queue(q);
1702} 1711}
1703 1712
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 44e8ca398efa..72273a0e5666 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -322,6 +322,7 @@ out_device_destroy:
322 scsi_device_set_state(sdev, SDEV_DEL); 322 scsi_device_set_state(sdev, SDEV_DEL);
323 transport_destroy_device(&sdev->sdev_gendev); 323 transport_destroy_device(&sdev->sdev_gendev);
324 put_device(&sdev->sdev_dev); 324 put_device(&sdev->sdev_dev);
325 scsi_free_queue(sdev->request_queue);
325 put_device(&sdev->sdev_gendev); 326 put_device(&sdev->sdev_gendev);
326out: 327out:
327 if (display_failure_msg) 328 if (display_failure_msg)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 1bcd65a509e6..96029e6d027f 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -520,7 +520,7 @@ fail_host_msg:
520/** 520/**
521 * iscsi_bsg_host_add - Create and add the bsg hooks to receive requests 521 * iscsi_bsg_host_add - Create and add the bsg hooks to receive requests
522 * @shost: shost for iscsi_host 522 * @shost: shost for iscsi_host
523 * @cls_host: iscsi_cls_host adding the structures to 523 * @ihost: iscsi_cls_host adding the structures to
524 */ 524 */
525static int 525static int
526iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) 526iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a7942e5c8be8..fa3a5918009c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2590,18 +2590,16 @@ static int sd_probe(struct device *dev)
2590 spin_unlock(&sd_index_lock); 2590 spin_unlock(&sd_index_lock);
2591 } while (error == -EAGAIN); 2591 } while (error == -EAGAIN);
2592 2592
2593 if (error) 2593 if (error) {
2594 sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n");
2594 goto out_put; 2595 goto out_put;
2595
2596 if (index >= SD_MAX_DISKS) {
2597 error = -ENODEV;
2598 sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n");
2599 goto out_free_index;
2600 } 2596 }
2601 2597
2602 error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); 2598 error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
2603 if (error) 2599 if (error) {
2600 sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name length exceeded.\n");
2604 goto out_free_index; 2601 goto out_free_index;
2602 }
2605 2603
2606 sdkp->device = sdp; 2604 sdkp->device = sdp;
2607 sdkp->driver = &sd_template; 2605 sdkp->driver = &sd_template;
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 6ad798bfd52a..4163f2910e3d 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -9,12 +9,6 @@
9#define SD_MAJORS 16 9#define SD_MAJORS 16
10 10
11/* 11/*
12 * This is limited by the naming scheme enforced in sd_probe,
13 * add another character to it if you really need more disks.
14 */
15#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26)
16
17/*
18 * Time out in seconds for disks and Magneto-opticals (which are slower). 12 * Time out in seconds for disks and Magneto-opticals (which are slower).
19 */ 13 */
20#define SD_TIMEOUT (30 * HZ) 14#define SD_TIMEOUT (30 * HZ)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 1871b8ae83ae..9b28f39bac26 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -462,14 +462,16 @@ static void st_scsi_execute_end(struct request *req, int uptodate)
462{ 462{
463 struct st_request *SRpnt = req->end_io_data; 463 struct st_request *SRpnt = req->end_io_data;
464 struct scsi_tape *STp = SRpnt->stp; 464 struct scsi_tape *STp = SRpnt->stp;
465 struct bio *tmp;
465 466
466 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 467 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
467 STp->buffer->cmdstat.residual = req->resid_len; 468 STp->buffer->cmdstat.residual = req->resid_len;
468 469
470 tmp = SRpnt->bio;
469 if (SRpnt->waiting) 471 if (SRpnt->waiting)
470 complete(SRpnt->waiting); 472 complete(SRpnt->waiting);
471 473
472 blk_rq_unmap_user(SRpnt->bio); 474 blk_rq_unmap_user(tmp);
473 __blk_put_request(req->q, req); 475 __blk_put_request(req->q, req);
474} 476}
475 477
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 595dacc7645f..019a7163572f 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -131,6 +131,12 @@
131#define RXBUSY (1<<2) 131#define RXBUSY (1<<2)
132#define TXBUSY (1<<3) 132#define TXBUSY (1<<3)
133 133
134struct s3c64xx_spi_dma_data {
135 unsigned ch;
136 enum dma_data_direction direction;
137 enum dma_ch dmach;
138};
139
134/** 140/**
135 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. 141 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
136 * @clk: Pointer to the spi clock. 142 * @clk: Pointer to the spi clock.
@@ -164,13 +170,14 @@ struct s3c64xx_spi_driver_data {
164 struct work_struct work; 170 struct work_struct work;
165 struct list_head queue; 171 struct list_head queue;
166 spinlock_t lock; 172 spinlock_t lock;
167 enum dma_ch rx_dmach;
168 enum dma_ch tx_dmach;
169 unsigned long sfr_start; 173 unsigned long sfr_start;
170 struct completion xfer_completion; 174 struct completion xfer_completion;
171 unsigned state; 175 unsigned state;
172 unsigned cur_mode, cur_bpw; 176 unsigned cur_mode, cur_bpw;
173 unsigned cur_speed; 177 unsigned cur_speed;
178 struct s3c64xx_spi_dma_data rx_dma;
179 struct s3c64xx_spi_dma_data tx_dma;
180 struct samsung_dma_ops *ops;
174}; 181};
175 182
176static struct s3c2410_dma_client s3c64xx_spi_dma_client = { 183static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -226,6 +233,78 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
226 writel(val, regs + S3C64XX_SPI_CH_CFG); 233 writel(val, regs + S3C64XX_SPI_CH_CFG);
227} 234}
228 235
236static void s3c64xx_spi_dmacb(void *data)
237{
238 struct s3c64xx_spi_driver_data *sdd;
239 struct s3c64xx_spi_dma_data *dma = data;
240 unsigned long flags;
241
242 if (dma->direction == DMA_FROM_DEVICE)
243 sdd = container_of(data,
244 struct s3c64xx_spi_driver_data, rx_dma);
245 else
246 sdd = container_of(data,
247 struct s3c64xx_spi_driver_data, tx_dma);
248
249 spin_lock_irqsave(&sdd->lock, flags);
250
251 if (dma->direction == DMA_FROM_DEVICE) {
252 sdd->state &= ~RXBUSY;
253 if (!(sdd->state & TXBUSY))
254 complete(&sdd->xfer_completion);
255 } else {
256 sdd->state &= ~TXBUSY;
257 if (!(sdd->state & RXBUSY))
258 complete(&sdd->xfer_completion);
259 }
260
261 spin_unlock_irqrestore(&sdd->lock, flags);
262}
263
264static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
265 unsigned len, dma_addr_t buf)
266{
267 struct s3c64xx_spi_driver_data *sdd;
268 struct samsung_dma_prep_info info;
269
270 if (dma->direction == DMA_FROM_DEVICE)
271 sdd = container_of((void *)dma,
272 struct s3c64xx_spi_driver_data, rx_dma);
273 else
274 sdd = container_of((void *)dma,
275 struct s3c64xx_spi_driver_data, tx_dma);
276
277 info.cap = DMA_SLAVE;
278 info.len = len;
279 info.fp = s3c64xx_spi_dmacb;
280 info.fp_param = dma;
281 info.direction = dma->direction;
282 info.buf = buf;
283
284 sdd->ops->prepare(dma->ch, &info);
285 sdd->ops->trigger(dma->ch);
286}
287
288static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
289{
290 struct samsung_dma_info info;
291
292 sdd->ops = samsung_dma_get_ops();
293
294 info.cap = DMA_SLAVE;
295 info.client = &s3c64xx_spi_dma_client;
296 info.width = sdd->cur_bpw / 8;
297
298 info.direction = sdd->rx_dma.direction;
299 info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
300 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info);
301 info.direction = sdd->tx_dma.direction;
302 info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
303 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info);
304
305 return 1;
306}
307
229static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, 308static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
230 struct spi_device *spi, 309 struct spi_device *spi,
231 struct spi_transfer *xfer, int dma_mode) 310 struct spi_transfer *xfer, int dma_mode)
@@ -258,10 +337,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
258 chcfg |= S3C64XX_SPI_CH_TXCH_ON; 337 chcfg |= S3C64XX_SPI_CH_TXCH_ON;
259 if (dma_mode) { 338 if (dma_mode) {
260 modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; 339 modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
261 s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); 340 prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma);
262 s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
263 xfer->tx_dma, xfer->len);
264 s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
265 } else { 341 } else {
266 switch (sdd->cur_bpw) { 342 switch (sdd->cur_bpw) {
267 case 32: 343 case 32:
@@ -293,10 +369,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
293 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) 369 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
294 | S3C64XX_SPI_PACKET_CNT_EN, 370 | S3C64XX_SPI_PACKET_CNT_EN,
295 regs + S3C64XX_SPI_PACKET_CNT); 371 regs + S3C64XX_SPI_PACKET_CNT);
296 s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8); 372 prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma);
297 s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
298 xfer->rx_dma, xfer->len);
299 s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
300 } 373 }
301 } 374 }
302 375
@@ -482,46 +555,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
482 } 555 }
483} 556}
484 557
485static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
486 int size, enum s3c2410_dma_buffresult res)
487{
488 struct s3c64xx_spi_driver_data *sdd = buf_id;
489 unsigned long flags;
490
491 spin_lock_irqsave(&sdd->lock, flags);
492
493 if (res == S3C2410_RES_OK)
494 sdd->state &= ~RXBUSY;
495 else
496 dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
497
498 /* If the other done */
499 if (!(sdd->state & TXBUSY))
500 complete(&sdd->xfer_completion);
501
502 spin_unlock_irqrestore(&sdd->lock, flags);
503}
504
505static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
506 int size, enum s3c2410_dma_buffresult res)
507{
508 struct s3c64xx_spi_driver_data *sdd = buf_id;
509 unsigned long flags;
510
511 spin_lock_irqsave(&sdd->lock, flags);
512
513 if (res == S3C2410_RES_OK)
514 sdd->state &= ~TXBUSY;
515 else
516 dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
517
518 /* If the other done */
519 if (!(sdd->state & RXBUSY))
520 complete(&sdd->xfer_completion);
521
522 spin_unlock_irqrestore(&sdd->lock, flags);
523}
524
525#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) 558#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
526 559
527static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, 560static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -696,12 +729,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
696 if (use_dma) { 729 if (use_dma) {
697 if (xfer->tx_buf != NULL 730 if (xfer->tx_buf != NULL
698 && (sdd->state & TXBUSY)) 731 && (sdd->state & TXBUSY))
699 s3c2410_dma_ctrl(sdd->tx_dmach, 732 sdd->ops->stop(sdd->tx_dma.ch);
700 S3C2410_DMAOP_FLUSH);
701 if (xfer->rx_buf != NULL 733 if (xfer->rx_buf != NULL
702 && (sdd->state & RXBUSY)) 734 && (sdd->state & RXBUSY))
703 s3c2410_dma_ctrl(sdd->rx_dmach, 735 sdd->ops->stop(sdd->rx_dma.ch);
704 S3C2410_DMAOP_FLUSH);
705 } 736 }
706 737
707 goto out; 738 goto out;
@@ -739,30 +770,6 @@ out:
739 msg->complete(msg->context); 770 msg->complete(msg->context);
740} 771}
741 772
742static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
743{
744 if (s3c2410_dma_request(sdd->rx_dmach,
745 &s3c64xx_spi_dma_client, NULL) < 0) {
746 dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
747 return 0;
748 }
749 s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
750 s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
751 sdd->sfr_start + S3C64XX_SPI_RX_DATA);
752
753 if (s3c2410_dma_request(sdd->tx_dmach,
754 &s3c64xx_spi_dma_client, NULL) < 0) {
755 dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
756 s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
757 return 0;
758 }
759 s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
760 s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
761 sdd->sfr_start + S3C64XX_SPI_TX_DATA);
762
763 return 1;
764}
765
766static void s3c64xx_spi_work(struct work_struct *work) 773static void s3c64xx_spi_work(struct work_struct *work)
767{ 774{
768 struct s3c64xx_spi_driver_data *sdd = container_of(work, 775 struct s3c64xx_spi_driver_data *sdd = container_of(work,
@@ -799,8 +806,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
799 spin_unlock_irqrestore(&sdd->lock, flags); 806 spin_unlock_irqrestore(&sdd->lock, flags);
800 807
801 /* Free DMA channels */ 808 /* Free DMA channels */
802 s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client); 809 sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
803 s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); 810 sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
804} 811}
805 812
806static int s3c64xx_spi_transfer(struct spi_device *spi, 813static int s3c64xx_spi_transfer(struct spi_device *spi,
@@ -1017,8 +1024,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1017 sdd->cntrlr_info = sci; 1024 sdd->cntrlr_info = sci;
1018 sdd->pdev = pdev; 1025 sdd->pdev = pdev;
1019 sdd->sfr_start = mem_res->start; 1026 sdd->sfr_start = mem_res->start;
1020 sdd->tx_dmach = dmatx_res->start; 1027 sdd->tx_dma.dmach = dmatx_res->start;
1021 sdd->rx_dmach = dmarx_res->start; 1028 sdd->tx_dma.direction = DMA_TO_DEVICE;
1029 sdd->rx_dma.dmach = dmarx_res->start;
1030 sdd->rx_dma.direction = DMA_FROM_DEVICE;
1022 1031
1023 sdd->cur_bpw = 8; 1032 sdd->cur_bpw = 8;
1024 1033
@@ -1106,7 +1115,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1106 pdev->id, master->num_chipselect); 1115 pdev->id, master->num_chipselect);
1107 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", 1116 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
1108 mem_res->end, mem_res->start, 1117 mem_res->end, mem_res->start,
1109 sdd->rx_dmach, sdd->tx_dmach); 1118 sdd->rx_dma.dmach, sdd->tx_dma.dmach);
1110 1119
1111 return 0; 1120 return 0;
1112 1121
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d132c27dfb3f..25cdff36a78a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -30,12 +30,6 @@ source "drivers/staging/et131x/Kconfig"
30 30
31source "drivers/staging/slicoss/Kconfig" 31source "drivers/staging/slicoss/Kconfig"
32 32
33source "drivers/staging/go7007/Kconfig"
34
35source "drivers/staging/cx25821/Kconfig"
36
37source "drivers/staging/cxd2099/Kconfig"
38
39source "drivers/staging/usbip/Kconfig" 33source "drivers/staging/usbip/Kconfig"
40 34
41source "drivers/staging/winbond/Kconfig" 35source "drivers/staging/winbond/Kconfig"
@@ -104,20 +98,12 @@ source "drivers/staging/wlags49_h25/Kconfig"
104 98
105source "drivers/staging/sm7xx/Kconfig" 99source "drivers/staging/sm7xx/Kconfig"
106 100
107source "drivers/staging/dt3155v4l/Kconfig"
108
109source "drivers/staging/crystalhd/Kconfig" 101source "drivers/staging/crystalhd/Kconfig"
110 102
111source "drivers/staging/cxt1e1/Kconfig" 103source "drivers/staging/cxt1e1/Kconfig"
112 104
113source "drivers/staging/xgifb/Kconfig" 105source "drivers/staging/xgifb/Kconfig"
114 106
115source "drivers/staging/lirc/Kconfig"
116
117source "drivers/staging/easycap/Kconfig"
118
119source "drivers/staging/solo6x10/Kconfig"
120
121source "drivers/staging/tidspbridge/Kconfig" 107source "drivers/staging/tidspbridge/Kconfig"
122 108
123source "drivers/staging/quickstart/Kconfig" 109source "drivers/staging/quickstart/Kconfig"
@@ -144,4 +130,6 @@ source "drivers/staging/mei/Kconfig"
144 130
145source "drivers/staging/nvec/Kconfig" 131source "drivers/staging/nvec/Kconfig"
146 132
133source "drivers/staging/media/Kconfig"
134
147endif # STAGING 135endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 936b7c22e18e..a25f3f26c7ff 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -4,12 +4,9 @@
4obj-$(CONFIG_STAGING) += staging.o 4obj-$(CONFIG_STAGING) += staging.o
5 5
6obj-y += serial/ 6obj-y += serial/
7obj-y += media/
7obj-$(CONFIG_ET131X) += et131x/ 8obj-$(CONFIG_ET131X) += et131x/
8obj-$(CONFIG_SLICOSS) += slicoss/ 9obj-$(CONFIG_SLICOSS) += slicoss/
9obj-$(CONFIG_VIDEO_GO7007) += go7007/
10obj-$(CONFIG_VIDEO_CX25821) += cx25821/
11obj-$(CONFIG_DVB_CXD2099) += cxd2099/
12obj-$(CONFIG_LIRC_STAGING) += lirc/
13obj-$(CONFIG_USBIP_CORE) += usbip/ 10obj-$(CONFIG_USBIP_CORE) += usbip/
14obj-$(CONFIG_W35UND) += winbond/ 11obj-$(CONFIG_W35UND) += winbond/
15obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
@@ -44,12 +41,9 @@ obj-$(CONFIG_ZCACHE) += zcache/
44obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ 41obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
45obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ 42obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
46obj-$(CONFIG_FB_SM7XX) += sm7xx/ 43obj-$(CONFIG_FB_SM7XX) += sm7xx/
47obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
48obj-$(CONFIG_CRYSTALHD) += crystalhd/ 44obj-$(CONFIG_CRYSTALHD) += crystalhd/
49obj-$(CONFIG_CXT1E1) += cxt1e1/ 45obj-$(CONFIG_CXT1E1) += cxt1e1/
50obj-$(CONFIG_FB_XGI) += xgifb/ 46obj-$(CONFIG_FB_XGI) += xgifb/
51obj-$(CONFIG_EASYCAP) += easycap/
52obj-$(CONFIG_SOLO6X10) += solo6x10/
53obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ 47obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
54obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ 48obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
55obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ 49obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
deleted file mode 100644
index a9ba50b9888b..000000000000
--- a/drivers/staging/cx25821/README
+++ /dev/null
@@ -1,6 +0,0 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4
5Please send patches to linux-media@vger.kernel.org
6
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
new file mode 100644
index 000000000000..7e5caa39ed3f
--- /dev/null
+++ b/drivers/staging/media/Kconfig
@@ -0,0 +1,37 @@
1menuconfig STAGING_MEDIA
2 bool "Media staging drivers"
3 default n
4 ---help---
5 This option allows you to select a number of media drivers that
6 don't have the "normal" Linux kernel quality level.
7 Most of them don't follow properly the V4L, DVB and/or RC API's,
8 so, they won't likely work fine with the existing applications.
9 That also means that, one fixed, their API's will change to match
10 the existing ones.
11
12 If you wish to work on these drivers, to help improve them, or
13 to report problems you have with them, please use the
14 linux-media@vger.kernel.org mailing list.
15
16 If in doubt, say N here.
17
18
19if STAGING_MEDIA
20
21# Please keep them in alphabetic order
22source "drivers/staging/media/as102/Kconfig"
23
24source "drivers/staging/media/cxd2099/Kconfig"
25
26source "drivers/staging/media/dt3155v4l/Kconfig"
27
28source "drivers/staging/media/easycap/Kconfig"
29
30source "drivers/staging/media/go7007/Kconfig"
31
32source "drivers/staging/media/solo6x10/Kconfig"
33
34# Keep LIRC at the end, as it has sub-menus
35source "drivers/staging/media/lirc/Kconfig"
36
37endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
new file mode 100644
index 000000000000..c69124cdb0d3
--- /dev/null
+++ b/drivers/staging/media/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_DVB_AS102) += as102/
2obj-$(CONFIG_DVB_CXD2099) += cxd2099/
3obj-$(CONFIG_EASYCAP) += easycap/
4obj-$(CONFIG_LIRC_STAGING) += lirc/
5obj-$(CONFIG_SOLO6X10) += solo6x10/
6obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
7obj-$(CONFIG_VIDEO_GO7007) += go7007/
diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig
new file mode 100644
index 000000000000..5865029db0f6
--- /dev/null
+++ b/drivers/staging/media/as102/Kconfig
@@ -0,0 +1,7 @@
1config DVB_AS102
2 tristate "Abilis AS102 DVB receiver"
3 depends on DVB_CORE && USB && I2C && INPUT
4 help
5 Choose Y or M here if you have a device containing an AS102
6
7 To compile this driver as a module, choose M here
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
new file mode 100644
index 000000000000..e7dbb6f814d5
--- /dev/null
+++ b/drivers/staging/media/as102/Makefile
@@ -0,0 +1,6 @@
1dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
2 as102_fe.o as102_usb_drv.o as10x_cmd_cfg.o
3
4obj-$(CONFIG_DVB_AS102) += dvb-as102.o
5
6EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
new file mode 100644
index 000000000000..d335c7d6fa0f
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -0,0 +1,351 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/mm.h>
26#include <linux/kref.h>
27#include <asm/uaccess.h>
28#include <linux/usb.h>
29
30/* header file for Usb device driver*/
31#include "as102_drv.h"
32#include "as102_fw.h"
33#include "dvbdev.h"
34
35int debug;
36module_param_named(debug, debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
38
39int dual_tuner;
40module_param_named(dual_tuner, dual_tuner, int, 0644);
41MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner config (default: off)");
42
43static int fw_upload = 1;
44module_param_named(fw_upload, fw_upload, int, 0644);
45MODULE_PARM_DESC(fw_upload, "Turn on/off default FW upload (default: on)");
46
47static int pid_filtering;
48module_param_named(pid_filtering, pid_filtering, int, 0644);
49MODULE_PARM_DESC(pid_filtering, "Activate HW PID filtering (default: off)");
50
51static int ts_auto_disable;
52module_param_named(ts_auto_disable, ts_auto_disable, int, 0644);
53MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)");
54
55int elna_enable = 1;
56module_param_named(elna_enable, elna_enable, int, 0644);
57MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)");
58
59#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
60DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
61#endif
62
63static void as102_stop_stream(struct as102_dev_t *dev)
64{
65 struct as102_bus_adapter_t *bus_adap;
66
67 if (dev != NULL)
68 bus_adap = &dev->bus_adap;
69 else
70 return;
71
72 if (bus_adap->ops->stop_stream != NULL)
73 bus_adap->ops->stop_stream(dev);
74
75 if (ts_auto_disable) {
76 if (mutex_lock_interruptible(&dev->bus_adap.lock))
77 return;
78
79 if (as10x_cmd_stop_streaming(bus_adap) < 0)
80 dprintk(debug, "as10x_cmd_stop_streaming failed\n");
81
82 mutex_unlock(&dev->bus_adap.lock);
83 }
84}
85
86static int as102_start_stream(struct as102_dev_t *dev)
87{
88 struct as102_bus_adapter_t *bus_adap;
89 int ret = -EFAULT;
90
91 if (dev != NULL)
92 bus_adap = &dev->bus_adap;
93 else
94 return ret;
95
96 if (bus_adap->ops->start_stream != NULL)
97 ret = bus_adap->ops->start_stream(dev);
98
99 if (ts_auto_disable) {
100 if (mutex_lock_interruptible(&dev->bus_adap.lock))
101 return -EFAULT;
102
103 ret = as10x_cmd_start_streaming(bus_adap);
104
105 mutex_unlock(&dev->bus_adap.lock);
106 }
107
108 return ret;
109}
110
111static int as10x_pid_filter(struct as102_dev_t *dev,
112 int index, u16 pid, int onoff) {
113
114 struct as102_bus_adapter_t *bus_adap = &dev->bus_adap;
115 int ret = -EFAULT;
116
117 ENTER();
118
119 if (mutex_lock_interruptible(&dev->bus_adap.lock)) {
120 dprintk(debug, "mutex_lock_interruptible(lock) failed !\n");
121 return -EBUSY;
122 }
123
124 switch (onoff) {
125 case 0:
126 ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
127 dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
128 index, pid, ret);
129 break;
130 case 1:
131 {
132 struct as10x_ts_filter filter;
133
134 filter.type = TS_PID_TYPE_TS;
135 filter.idx = 0xFF;
136 filter.pid = pid;
137
138 ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
139 dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
140 index, filter.idx, filter.pid, ret);
141 break;
142 }
143 }
144
145 mutex_unlock(&dev->bus_adap.lock);
146
147 LEAVE();
148 return ret;
149}
150
151static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
152{
153 int ret = 0;
154 struct dvb_demux *demux = dvbdmxfeed->demux;
155 struct as102_dev_t *as102_dev = demux->priv;
156
157 ENTER();
158
159 if (mutex_lock_interruptible(&as102_dev->sem))
160 return -ERESTARTSYS;
161
162 if (pid_filtering) {
163 as10x_pid_filter(as102_dev,
164 dvbdmxfeed->index, dvbdmxfeed->pid, 1);
165 }
166
167 if (as102_dev->streaming++ == 0)
168 ret = as102_start_stream(as102_dev);
169
170 mutex_unlock(&as102_dev->sem);
171 LEAVE();
172 return ret;
173}
174
175static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
176{
177 struct dvb_demux *demux = dvbdmxfeed->demux;
178 struct as102_dev_t *as102_dev = demux->priv;
179
180 ENTER();
181
182 if (mutex_lock_interruptible(&as102_dev->sem))
183 return -ERESTARTSYS;
184
185 if (--as102_dev->streaming == 0)
186 as102_stop_stream(as102_dev);
187
188 if (pid_filtering) {
189 as10x_pid_filter(as102_dev,
190 dvbdmxfeed->index, dvbdmxfeed->pid, 0);
191 }
192
193 mutex_unlock(&as102_dev->sem);
194 LEAVE();
195 return 0;
196}
197
198int as102_dvb_register(struct as102_dev_t *as102_dev)
199{
200 int ret = 0;
201 ENTER();
202
203 ret = dvb_register_adapter(&as102_dev->dvb_adap,
204 as102_dev->name,
205 THIS_MODULE,
206#if defined(CONFIG_AS102_USB)
207 &as102_dev->bus_adap.usb_dev->dev
208#elif defined(CONFIG_AS102_SPI)
209 &as102_dev->bus_adap.spi_dev->dev
210#else
211#error >>> dvb_register_adapter <<<
212#endif
213#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
214 , adapter_nr
215#endif
216 );
217 if (ret < 0) {
218 err("%s: dvb_register_adapter() failed (errno = %d)",
219 __func__, ret);
220 goto failed;
221 }
222
223 as102_dev->dvb_dmx.priv = as102_dev;
224 as102_dev->dvb_dmx.filternum = pid_filtering ? 16 : 256;
225 as102_dev->dvb_dmx.feednum = 256;
226 as102_dev->dvb_dmx.start_feed = as102_dvb_dmx_start_feed;
227 as102_dev->dvb_dmx.stop_feed = as102_dvb_dmx_stop_feed;
228
229 as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING |
230 DMX_SECTION_FILTERING;
231
232 as102_dev->dvb_dmxdev.filternum = as102_dev->dvb_dmx.filternum;
233 as102_dev->dvb_dmxdev.demux = &as102_dev->dvb_dmx.dmx;
234 as102_dev->dvb_dmxdev.capabilities = 0;
235
236 ret = dvb_dmx_init(&as102_dev->dvb_dmx);
237 if (ret < 0) {
238 err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret);
239 goto failed;
240 }
241
242 ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap);
243 if (ret < 0) {
244 err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__,
245 ret);
246 goto failed;
247 }
248
249 ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe);
250 if (ret < 0) {
251 err("%s: as102_dvb_register_frontend() failed (errno = %d)",
252 __func__, ret);
253 goto failed;
254 }
255
256 /* init bus mutex for token locking */
257 mutex_init(&as102_dev->bus_adap.lock);
258
259 /* init start / stop stream mutex */
260 mutex_init(&as102_dev->sem);
261
262#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
263 /*
264 * try to load as102 firmware. If firmware upload failed, we'll be
265 * able to upload it later.
266 */
267 if (fw_upload)
268 try_then_request_module(as102_fw_upload(&as102_dev->bus_adap),
269 "firmware_class");
270#endif
271
272failed:
273 LEAVE();
274 /* FIXME: free dvb_XXX */
275 return ret;
276}
277
278void as102_dvb_unregister(struct as102_dev_t *as102_dev)
279{
280 ENTER();
281
282 /* unregister as102 frontend */
283 as102_dvb_unregister_fe(&as102_dev->dvb_fe);
284
285 /* unregister demux device */
286 dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
287 dvb_dmx_release(&as102_dev->dvb_dmx);
288
289 /* unregister dvb adapter */
290 dvb_unregister_adapter(&as102_dev->dvb_adap);
291
292 LEAVE();
293}
294
295static int __init as102_driver_init(void)
296{
297 int ret = 0;
298
299 ENTER();
300
301 /* register this driver with the low level subsystem */
302#if defined(CONFIG_AS102_USB)
303 ret = usb_register(&as102_usb_driver);
304 if (ret)
305 err("usb_register failed (ret = %d)", ret);
306#endif
307#if defined(CONFIG_AS102_SPI)
308 ret = spi_register_driver(&as102_spi_driver);
309 if (ret)
310 printk(KERN_ERR "spi_register failed (ret = %d)", ret);
311#endif
312
313 LEAVE();
314 return ret;
315}
316
317/*
318 * Mandatory function : Adds a special section to the module indicating
319 * where initialisation function is defined
320 */
321module_init(as102_driver_init);
322
323/**
324 * as102_driver_exit - as102 driver exit point
325 *
326 * This function is called when device has to be removed.
327 */
328static void __exit as102_driver_exit(void)
329{
330 ENTER();
331 /* deregister this driver with the low level bus subsystem */
332#if defined(CONFIG_AS102_USB)
333 usb_deregister(&as102_usb_driver);
334#endif
335#if defined(CONFIG_AS102_SPI)
336 spi_unregister_driver(&as102_spi_driver);
337#endif
338 LEAVE();
339}
340
341/*
342 * required function for unload: Adds a special section to the module
343 * indicating where unload function is defined
344 */
345module_exit(as102_driver_exit);
346/* modinfo details */
347MODULE_DESCRIPTION(DRIVER_FULL_NAME);
348MODULE_LICENSE("GPL");
349MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");
350
351/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
new file mode 100644
index 000000000000..bcda635b5a99
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.h
@@ -0,0 +1,141 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#if defined(CONFIG_AS102_USB)
21#include <linux/usb.h>
22extern struct usb_driver as102_usb_driver;
23#endif
24
25#if defined(CONFIG_AS102_SPI)
26#include <linux/platform_device.h>
27#include <linux/spi/spi.h>
28#include <linux/cdev.h>
29
30extern struct spi_driver as102_spi_driver;
31#endif
32
33#include "dvb_demux.h"
34#include "dvb_frontend.h"
35#include "dmxdev.h"
36
37#define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
38#define DRIVER_NAME "as10x_usb"
39
40extern int debug;
41
42#define dprintk(debug, args...) \
43 do { if (debug) { \
44 printk(KERN_DEBUG "%s: ",__FUNCTION__); \
45 printk(args); \
46 } } while (0)
47
48#ifdef TRACE
49#define ENTER() printk(">> enter %s\n", __FUNCTION__)
50#define LEAVE() printk("<< leave %s\n", __FUNCTION__)
51#else
52#define ENTER()
53#define LEAVE()
54#endif
55
56#define AS102_DEVICE_MAJOR 192
57
58#define AS102_USB_BUF_SIZE 512
59#define MAX_STREAM_URB 32
60
61#include "as10x_cmd.h"
62
63#if defined(CONFIG_AS102_USB)
64#include "as102_usb_drv.h"
65#endif
66
67#if defined(CONFIG_AS102_SPI)
68#include "as10x_spi_drv.h"
69#endif
70
71
72struct as102_bus_adapter_t {
73#if defined(CONFIG_AS102_USB)
74 struct usb_device *usb_dev;
75#elif defined(CONFIG_AS102_SPI)
76 struct spi_device *spi_dev;
77 struct cdev cdev; /* spidev raw device */
78
79 struct timer_list timer;
80 struct completion xfer_done;
81#endif
82 /* bus token lock */
83 struct mutex lock;
84 /* low level interface for bus adapter */
85 union as10x_bus_token_t {
86#if defined(CONFIG_AS102_USB)
87 /* usb token */
88 struct as10x_usb_token_cmd_t usb;
89#endif
90#if defined(CONFIG_AS102_SPI)
91 /* spi token */
92 struct as10x_spi_token_cmd_t spi;
93#endif
94 } token;
95
96 /* token cmd xfer id */
97 uint16_t cmd_xid;
98
99 /* as10x command and response for dvb interface*/
100 struct as10x_cmd_t *cmd, *rsp;
101
102 /* bus adapter private ops callback */
103 struct as102_priv_ops_t *ops;
104};
105
106struct as102_dev_t {
107 const char *name;
108 struct as102_bus_adapter_t bus_adap;
109 struct list_head device_entry;
110 struct kref kref;
111 unsigned long minor;
112
113 struct dvb_adapter dvb_adap;
114 struct dvb_frontend dvb_fe;
115 struct dvb_demux dvb_dmx;
116 struct dmxdev dvb_dmxdev;
117
118 /* demodulator stats */
119 struct as10x_demod_stats demod_stats;
120 /* signal strength */
121 uint16_t signal_strength;
122 /* bit error rate */
123 uint32_t ber;
124
125 /* timer handle to trig ts stream download */
126 struct timer_list timer_handle;
127
128 struct mutex sem;
129 dma_addr_t dma_addr;
130 void *stream;
131 int streaming;
132 struct urb *stream_urb[MAX_STREAM_URB];
133};
134
135int as102_dvb_register(struct as102_dev_t *dev);
136void as102_dvb_unregister(struct as102_dev_t *dev);
137
138int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe);
139int as102_dvb_unregister_fe(struct dvb_frontend *dev);
140
141/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
new file mode 100644
index 000000000000..3550f905367e
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fe.c
@@ -0,0 +1,603 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/version.h>
21
22#include "as102_drv.h"
23#include "as10x_types.h"
24#include "as10x_cmd.h"
25
26extern int elna_enable;
27
28static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
29 struct as10x_tps *src);
30
31static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst,
32 struct dvb_frontend_parameters *src);
33
34static int as102_fe_set_frontend(struct dvb_frontend *fe,
35 struct dvb_frontend_parameters *params)
36{
37 int ret = 0;
38 struct as102_dev_t *dev;
39 struct as10x_tune_args tune_args = { 0 };
40
41 ENTER();
42
43 dev = (struct as102_dev_t *) fe->tuner_priv;
44 if (dev == NULL)
45 return -ENODEV;
46
47 if (mutex_lock_interruptible(&dev->bus_adap.lock))
48 return -EBUSY;
49
50 as102_fe_copy_tune_parameters(&tune_args, params);
51
52 /* send abilis command: SET_TUNE */
53 ret = as10x_cmd_set_tune(&dev->bus_adap, &tune_args);
54 if (ret != 0)
55 dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret);
56
57 mutex_unlock(&dev->bus_adap.lock);
58
59 LEAVE();
60 return (ret < 0) ? -EINVAL : 0;
61}
62
63static int as102_fe_get_frontend(struct dvb_frontend *fe,
64 struct dvb_frontend_parameters *p) {
65 int ret = 0;
66 struct as102_dev_t *dev;
67 struct as10x_tps tps = { 0 };
68
69 ENTER();
70
71 dev = (struct as102_dev_t *) fe->tuner_priv;
72 if (dev == NULL)
73 return -EINVAL;
74
75 if (mutex_lock_interruptible(&dev->bus_adap.lock))
76 return -EBUSY;
77
78 /* send abilis command: GET_TPS */
79 ret = as10x_cmd_get_tps(&dev->bus_adap, &tps);
80
81 if (ret == 0)
82 as10x_fe_copy_tps_parameters(p, &tps);
83
84 mutex_unlock(&dev->bus_adap.lock);
85
86 LEAVE();
87 return (ret < 0) ? -EINVAL : 0;
88}
89
90static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
91 struct dvb_frontend_tune_settings *settings) {
92 ENTER();
93
94#if 0
95 dprintk(debug, "step_size = %d\n", settings->step_size);
96 dprintk(debug, "max_drift = %d\n", settings->max_drift);
97 dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms,
98 1000);
99#endif
100
101 settings->min_delay_ms = 1000;
102
103 LEAVE();
104 return 0;
105}
106
107
108static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
109{
110 int ret = 0;
111 struct as102_dev_t *dev;
112 struct as10x_tune_status tstate = { 0 };
113
114 ENTER();
115
116 dev = (struct as102_dev_t *) fe->tuner_priv;
117 if (dev == NULL)
118 return -ENODEV;
119
120 if (mutex_lock_interruptible(&dev->bus_adap.lock))
121 return -EBUSY;
122
123 /* send abilis command: GET_TUNE_STATUS */
124 ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate);
125 if (ret < 0) {
126 dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n",
127 ret);
128 goto out;
129 }
130
131 dev->signal_strength = tstate.signal_strength;
132 dev->ber = tstate.BER;
133
134 switch (tstate.tune_state) {
135 case TUNE_STATUS_SIGNAL_DVB_OK:
136 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
137 break;
138 case TUNE_STATUS_STREAM_DETECTED:
139 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC;
140 break;
141 case TUNE_STATUS_STREAM_TUNED:
142 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
143 FE_HAS_LOCK;
144 break;
145 default:
146 *status = TUNE_STATUS_NOT_TUNED;
147 }
148
149 dprintk(debug, "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
150 tstate.tune_state, tstate.signal_strength,
151 tstate.PER, tstate.BER);
152
153 if (*status & FE_HAS_LOCK) {
154 if (as10x_cmd_get_demod_stats(&dev->bus_adap,
155 (struct as10x_demod_stats *) &dev->demod_stats) < 0) {
156 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
157 dprintk(debug, "as10x_cmd_get_demod_stats failed "
158 "(probably not tuned)\n");
159 } else {
160 dprintk(debug,
161 "demod status: fc: 0x%08x, bad fc: 0x%08x, "
162 "bytes corrected: 0x%08x , MER: 0x%04x\n",
163 dev->demod_stats.frame_count,
164 dev->demod_stats.bad_frame_count,
165 dev->demod_stats.bytes_fixed_by_rs,
166 dev->demod_stats.mer);
167 }
168 } else {
169 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
170 }
171
172out:
173 mutex_unlock(&dev->bus_adap.lock);
174 LEAVE();
175 return ret;
176}
177
178/*
179 * Note:
180 * - in AS102 SNR=MER
181 * - the SNR will be returned in linear terms, i.e. not in dB
182 * - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
183 * - the accuracy is >2dB for SNR values outside this range
184 */
185static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
186{
187 struct as102_dev_t *dev;
188
189 ENTER();
190
191 dev = (struct as102_dev_t *) fe->tuner_priv;
192 if (dev == NULL)
193 return -ENODEV;
194
195 *snr = dev->demod_stats.mer;
196
197 LEAVE();
198 return 0;
199}
200
201static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
202{
203 struct as102_dev_t *dev;
204
205 ENTER();
206
207 dev = (struct as102_dev_t *) fe->tuner_priv;
208 if (dev == NULL)
209 return -ENODEV;
210
211 *ber = dev->ber;
212
213 LEAVE();
214 return 0;
215}
216
217static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
218 u16 *strength)
219{
220 struct as102_dev_t *dev;
221
222 ENTER();
223
224 dev = (struct as102_dev_t *) fe->tuner_priv;
225 if (dev == NULL)
226 return -ENODEV;
227
228 *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);
229
230 LEAVE();
231 return 0;
232}
233
234static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
235{
236 struct as102_dev_t *dev;
237
238 ENTER();
239
240 dev = (struct as102_dev_t *) fe->tuner_priv;
241 if (dev == NULL)
242 return -ENODEV;
243
244 if (dev->demod_stats.has_started)
245 *ucblocks = dev->demod_stats.bad_frame_count;
246 else
247 *ucblocks = 0;
248
249 LEAVE();
250 return 0;
251}
252
253static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
254{
255 struct as102_dev_t *dev;
256 int ret;
257
258 ENTER();
259
260 dev = (struct as102_dev_t *) fe->tuner_priv;
261 if (dev == NULL)
262 return -ENODEV;
263
264 if (mutex_lock_interruptible(&dev->bus_adap.lock))
265 return -EBUSY;
266
267 if (acquire) {
268 if (elna_enable)
269 as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);
270
271 ret = as10x_cmd_turn_on(&dev->bus_adap);
272 } else {
273 ret = as10x_cmd_turn_off(&dev->bus_adap);
274 }
275
276 mutex_unlock(&dev->bus_adap.lock);
277
278 LEAVE();
279 return ret;
280}
281
282static struct dvb_frontend_ops as102_fe_ops = {
283 .info = {
284 .name = "Unknown AS102 device",
285 .type = FE_OFDM,
286 .frequency_min = 174000000,
287 .frequency_max = 862000000,
288 .frequency_stepsize = 166667,
289 .caps = FE_CAN_INVERSION_AUTO
290 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
291 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO
292 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
293 | FE_CAN_QAM_AUTO
294 | FE_CAN_TRANSMISSION_MODE_AUTO
295 | FE_CAN_GUARD_INTERVAL_AUTO
296 | FE_CAN_HIERARCHY_AUTO
297 | FE_CAN_RECOVER
298 | FE_CAN_MUTE_TS
299 },
300
301 .set_frontend = as102_fe_set_frontend,
302 .get_frontend = as102_fe_get_frontend,
303 .get_tune_settings = as102_fe_get_tune_settings,
304
305 .read_status = as102_fe_read_status,
306 .read_snr = as102_fe_read_snr,
307 .read_ber = as102_fe_read_ber,
308 .read_signal_strength = as102_fe_read_signal_strength,
309 .read_ucblocks = as102_fe_read_ucblocks,
310 .ts_bus_ctrl = as102_fe_ts_bus_ctrl,
311};
312
313int as102_dvb_unregister_fe(struct dvb_frontend *fe)
314{
315 /* unregister frontend */
316 dvb_unregister_frontend(fe);
317
318 /* detach frontend */
319 dvb_frontend_detach(fe);
320
321 return 0;
322}
323
324int as102_dvb_register_fe(struct as102_dev_t *as102_dev,
325 struct dvb_frontend *dvb_fe)
326{
327 int errno;
328 struct dvb_adapter *dvb_adap;
329
330 if (as102_dev == NULL)
331 return -EINVAL;
332
333 /* extract dvb_adapter */
334 dvb_adap = &as102_dev->dvb_adap;
335
336 /* init frontend callback ops */
337 memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
338 strncpy(dvb_fe->ops.info.name, as102_dev->name,
339 sizeof(dvb_fe->ops.info.name));
340
341 /* register dbvb frontend */
342 errno = dvb_register_frontend(dvb_adap, dvb_fe);
343 if (errno == 0)
344 dvb_fe->tuner_priv = as102_dev;
345
346 return errno;
347}
348
349static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
350 struct as10x_tps *as10x_tps)
351{
352
353 struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm;
354
355 /* extract consteallation */
356 switch (as10x_tps->constellation) {
357 case CONST_QPSK:
358 fe_tps->constellation = QPSK;
359 break;
360 case CONST_QAM16:
361 fe_tps->constellation = QAM_16;
362 break;
363 case CONST_QAM64:
364 fe_tps->constellation = QAM_64;
365 break;
366 }
367
368 /* extract hierarchy */
369 switch (as10x_tps->hierarchy) {
370 case HIER_NONE:
371 fe_tps->hierarchy_information = HIERARCHY_NONE;
372 break;
373 case HIER_ALPHA_1:
374 fe_tps->hierarchy_information = HIERARCHY_1;
375 break;
376 case HIER_ALPHA_2:
377 fe_tps->hierarchy_information = HIERARCHY_2;
378 break;
379 case HIER_ALPHA_4:
380 fe_tps->hierarchy_information = HIERARCHY_4;
381 break;
382 }
383
384 /* extract code rate HP */
385 switch (as10x_tps->code_rate_HP) {
386 case CODE_RATE_1_2:
387 fe_tps->code_rate_HP = FEC_1_2;
388 break;
389 case CODE_RATE_2_3:
390 fe_tps->code_rate_HP = FEC_2_3;
391 break;
392 case CODE_RATE_3_4:
393 fe_tps->code_rate_HP = FEC_3_4;
394 break;
395 case CODE_RATE_5_6:
396 fe_tps->code_rate_HP = FEC_5_6;
397 break;
398 case CODE_RATE_7_8:
399 fe_tps->code_rate_HP = FEC_7_8;
400 break;
401 }
402
403 /* extract code rate LP */
404 switch (as10x_tps->code_rate_LP) {
405 case CODE_RATE_1_2:
406 fe_tps->code_rate_LP = FEC_1_2;
407 break;
408 case CODE_RATE_2_3:
409 fe_tps->code_rate_LP = FEC_2_3;
410 break;
411 case CODE_RATE_3_4:
412 fe_tps->code_rate_LP = FEC_3_4;
413 break;
414 case CODE_RATE_5_6:
415 fe_tps->code_rate_LP = FEC_5_6;
416 break;
417 case CODE_RATE_7_8:
418 fe_tps->code_rate_LP = FEC_7_8;
419 break;
420 }
421
422 /* extract guard interval */
423 switch (as10x_tps->guard_interval) {
424 case GUARD_INT_1_32:
425 fe_tps->guard_interval = GUARD_INTERVAL_1_32;
426 break;
427 case GUARD_INT_1_16:
428 fe_tps->guard_interval = GUARD_INTERVAL_1_16;
429 break;
430 case GUARD_INT_1_8:
431 fe_tps->guard_interval = GUARD_INTERVAL_1_8;
432 break;
433 case GUARD_INT_1_4:
434 fe_tps->guard_interval = GUARD_INTERVAL_1_4;
435 break;
436 }
437
438 /* extract transmission mode */
439 switch (as10x_tps->transmission_mode) {
440 case TRANS_MODE_2K:
441 fe_tps->transmission_mode = TRANSMISSION_MODE_2K;
442 break;
443 case TRANS_MODE_8K:
444 fe_tps->transmission_mode = TRANSMISSION_MODE_8K;
445 break;
446 }
447}
448
449static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
450{
451 uint8_t c;
452
453 switch (arg) {
454 case FEC_1_2:
455 c = CODE_RATE_1_2;
456 break;
457 case FEC_2_3:
458 c = CODE_RATE_2_3;
459 break;
460 case FEC_3_4:
461 c = CODE_RATE_3_4;
462 break;
463 case FEC_5_6:
464 c = CODE_RATE_5_6;
465 break;
466 case FEC_7_8:
467 c = CODE_RATE_7_8;
468 break;
469 default:
470 c = CODE_RATE_UNKNOWN;
471 break;
472 }
473
474 return c;
475}
476
477static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
478 struct dvb_frontend_parameters *params)
479{
480
481 /* set frequency */
482 tune_args->freq = params->frequency / 1000;
483
484 /* fix interleaving_mode */
485 tune_args->interleaving_mode = INTLV_NATIVE;
486
487 switch (params->u.ofdm.bandwidth) {
488 case BANDWIDTH_8_MHZ:
489 tune_args->bandwidth = BW_8_MHZ;
490 break;
491 case BANDWIDTH_7_MHZ:
492 tune_args->bandwidth = BW_7_MHZ;
493 break;
494 case BANDWIDTH_6_MHZ:
495 tune_args->bandwidth = BW_6_MHZ;
496 break;
497 default:
498 tune_args->bandwidth = BW_8_MHZ;
499 }
500
501 switch (params->u.ofdm.guard_interval) {
502 case GUARD_INTERVAL_1_32:
503 tune_args->guard_interval = GUARD_INT_1_32;
504 break;
505 case GUARD_INTERVAL_1_16:
506 tune_args->guard_interval = GUARD_INT_1_16;
507 break;
508 case GUARD_INTERVAL_1_8:
509 tune_args->guard_interval = GUARD_INT_1_8;
510 break;
511 case GUARD_INTERVAL_1_4:
512 tune_args->guard_interval = GUARD_INT_1_4;
513 break;
514 case GUARD_INTERVAL_AUTO:
515 default:
516 tune_args->guard_interval = GUARD_UNKNOWN;
517 break;
518 }
519
520 switch (params->u.ofdm.constellation) {
521 case QPSK:
522 tune_args->constellation = CONST_QPSK;
523 break;
524 case QAM_16:
525 tune_args->constellation = CONST_QAM16;
526 break;
527 case QAM_64:
528 tune_args->constellation = CONST_QAM64;
529 break;
530 default:
531 tune_args->constellation = CONST_UNKNOWN;
532 break;
533 }
534
535 switch (params->u.ofdm.transmission_mode) {
536 case TRANSMISSION_MODE_2K:
537 tune_args->transmission_mode = TRANS_MODE_2K;
538 break;
539 case TRANSMISSION_MODE_8K:
540 tune_args->transmission_mode = TRANS_MODE_8K;
541 break;
542 default:
543 tune_args->transmission_mode = TRANS_MODE_UNKNOWN;
544 }
545
546 switch (params->u.ofdm.hierarchy_information) {
547 case HIERARCHY_NONE:
548 tune_args->hierarchy = HIER_NONE;
549 break;
550 case HIERARCHY_1:
551 tune_args->hierarchy = HIER_ALPHA_1;
552 break;
553 case HIERARCHY_2:
554 tune_args->hierarchy = HIER_ALPHA_2;
555 break;
556 case HIERARCHY_4:
557 tune_args->hierarchy = HIER_ALPHA_4;
558 break;
559 case HIERARCHY_AUTO:
560 tune_args->hierarchy = HIER_UNKNOWN;
561 break;
562 }
563
564 dprintk(debug, "tuner parameters: freq: %d bw: 0x%02x gi: 0x%02x\n",
565 params->frequency,
566 tune_args->bandwidth,
567 tune_args->guard_interval);
568
569 /*
570 * Detect a hierarchy selection
571 * if HP/LP are both set to FEC_NONE, HP will be selected.
572 */
573 if ((tune_args->hierarchy != HIER_NONE) &&
574 ((params->u.ofdm.code_rate_LP == FEC_NONE) ||
575 (params->u.ofdm.code_rate_HP == FEC_NONE))) {
576
577 if (params->u.ofdm.code_rate_LP == FEC_NONE) {
578 tune_args->hier_select = HIER_HIGH_PRIORITY;
579 tune_args->code_rate =
580 as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
581 }
582
583 if (params->u.ofdm.code_rate_HP == FEC_NONE) {
584 tune_args->hier_select = HIER_LOW_PRIORITY;
585 tune_args->code_rate =
586 as102_fe_get_code_rate(params->u.ofdm.code_rate_LP);
587 }
588
589 dprintk(debug, "\thierarchy: 0x%02x "
590 "selected: %s code_rate_%s: 0x%02x\n",
591 tune_args->hierarchy,
592 tune_args->hier_select == HIER_HIGH_PRIORITY ?
593 "HP" : "LP",
594 tune_args->hier_select == HIER_HIGH_PRIORITY ?
595 "HP" : "LP",
596 tune_args->code_rate);
597 } else {
598 tune_args->code_rate =
599 as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
600 }
601}
602
603/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
new file mode 100644
index 000000000000..c019df933cc9
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -0,0 +1,251 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/ctype.h>
23#include <linux/delay.h>
24#include <linux/firmware.h>
25
26#include "as102_drv.h"
27#include "as102_fw.h"
28
29#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
30char as102_st_fw1[] = "as102_data1_st.hex";
31char as102_st_fw2[] = "as102_data2_st.hex";
32char as102_dt_fw1[] = "as102_data1_dt.hex";
33char as102_dt_fw2[] = "as102_data2_dt.hex";
34
35static unsigned char atohx(unsigned char *dst, char *src)
36{
37 unsigned char value = 0;
38
39 char msb = tolower(*src) - '0';
40 char lsb = tolower(*(src + 1)) - '0';
41
42 if (msb > 9)
43 msb -= 7;
44 if (lsb > 9)
45 lsb -= 7;
46
47 *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
48 return value;
49}
50
51/*
52 * Parse INTEL HEX firmware file to extract address and data.
53 */
54static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
55 unsigned char *data, int *dataLength,
56 unsigned char *addr_has_changed) {
57
58 int count = 0;
59 unsigned char *src, dst;
60
61 if (*fw_data++ != ':') {
62 printk(KERN_ERR "invalid firmware file\n");
63 return -EFAULT;
64 }
65
66 /* locate end of line */
67 for (src = fw_data; *src != '\n'; src += 2) {
68 atohx(&dst, src);
69 /* parse line to split addr / data */
70 switch (count) {
71 case 0:
72 *dataLength = dst;
73 break;
74 case 1:
75 addr[2] = dst;
76 break;
77 case 2:
78 addr[3] = dst;
79 break;
80 case 3:
81 /* check if data is an address */
82 if (dst == 0x04)
83 *addr_has_changed = 1;
84 else
85 *addr_has_changed = 0;
86 break;
87 case 4:
88 case 5:
89 if (*addr_has_changed)
90 addr[(count - 4)] = dst;
91 else
92 data[(count - 4)] = dst;
93 break;
94 default:
95 data[(count - 4)] = dst;
96 break;
97 }
98 count++;
99 }
100
101 /* return read value + ':' + '\n' */
102 return (count * 2) + 2;
103}
104
105static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
106 unsigned char *cmd,
107 const struct firmware *firmware) {
108
109 struct as10x_fw_pkt_t fw_pkt;
110 int total_read_bytes = 0, errno = 0;
111 unsigned char addr_has_changed = 0;
112
113 ENTER();
114
115 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
116 int read_bytes = 0, data_len = 0;
117
118 /* parse intel hex line */
119 read_bytes = parse_hex_line(
120 (u8 *) (firmware->data + total_read_bytes),
121 fw_pkt.raw.address,
122 fw_pkt.raw.data,
123 &data_len,
124 &addr_has_changed);
125
126 if (read_bytes <= 0)
127 goto error;
128
129 /* detect the end of file */
130 total_read_bytes += read_bytes;
131 if (total_read_bytes == firmware->size) {
132 fw_pkt.u.request[0] = 0x00;
133 fw_pkt.u.request[1] = 0x03;
134
135 /* send EOF command */
136 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
137 (uint8_t *)
138 &fw_pkt, 2, 0);
139 if (errno < 0)
140 goto error;
141 } else {
142 if (!addr_has_changed) {
143 /* prepare command to send */
144 fw_pkt.u.request[0] = 0x00;
145 fw_pkt.u.request[1] = 0x01;
146
147 data_len += sizeof(fw_pkt.u.request);
148 data_len += sizeof(fw_pkt.raw.address);
149
150 /* send cmd to device */
151 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
152 (uint8_t *)
153 &fw_pkt,
154 data_len,
155 0);
156 if (errno < 0)
157 goto error;
158 }
159 }
160 }
161error:
162 LEAVE();
163 return (errno == 0) ? total_read_bytes : errno;
164}
165
166int as102_fw_upload(struct as102_bus_adapter_t *bus_adap)
167{
168 int errno = -EFAULT;
169 const struct firmware *firmware;
170 unsigned char *cmd_buf = NULL;
171 char *fw1, *fw2;
172
173#if defined(CONFIG_AS102_USB)
174 struct usb_device *dev = bus_adap->usb_dev;
175#endif
176#if defined(CONFIG_AS102_SPI)
177 struct spi_device *dev = bus_adap->spi_dev;
178#endif
179 ENTER();
180
181 /* select fw file to upload */
182 if (dual_tuner) {
183 fw1 = as102_dt_fw1;
184 fw2 = as102_dt_fw2;
185 } else {
186 fw1 = as102_st_fw1;
187 fw2 = as102_st_fw2;
188 }
189
190#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
191 /* allocate buffer to store firmware upload command and data */
192 cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
193 if (cmd_buf == NULL) {
194 errno = -ENOMEM;
195 goto error;
196 }
197
198 /* request kernel to locate firmware file: part1 */
199 errno = request_firmware(&firmware, fw1, &dev->dev);
200 if (errno < 0) {
201 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
202 DRIVER_NAME, fw1);
203 goto error;
204 }
205
206 /* initiate firmware upload */
207 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
208 if (errno < 0) {
209 printk(KERN_ERR "%s: error during firmware upload part1\n",
210 DRIVER_NAME);
211 goto error;
212 }
213
214 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
215 DRIVER_NAME, fw1);
216 release_firmware(firmware);
217
218 /* wait for boot to complete */
219 mdelay(100);
220
221 /* request kernel to locate firmware file: part2 */
222 errno = request_firmware(&firmware, fw2, &dev->dev);
223 if (errno < 0) {
224 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
225 DRIVER_NAME, fw2);
226 goto error;
227 }
228
229 /* initiate firmware upload */
230 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
231 if (errno < 0) {
232 printk(KERN_ERR "%s: error during firmware upload part2\n",
233 DRIVER_NAME);
234 goto error;
235 }
236
237 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
238 DRIVER_NAME, fw2);
239error:
240 /* free data buffer */
241 kfree(cmd_buf);
242 /* release firmware if needed */
243 if (firmware != NULL)
244 release_firmware(firmware);
245#endif
246 LEAVE();
247 return errno;
248}
249#endif
250
251/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h
new file mode 100644
index 000000000000..27e5347e2e19
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.h
@@ -0,0 +1,42 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#define MAX_FW_PKT_SIZE 64
20
21extern int dual_tuner;
22
23#pragma pack(1)
24struct as10x_raw_fw_pkt {
25 unsigned char address[4];
26 unsigned char data[MAX_FW_PKT_SIZE - 6];
27};
28
29struct as10x_fw_pkt_t {
30 union {
31 unsigned char request[2];
32 unsigned char length[2];
33 } u;
34 struct as10x_raw_fw_pkt raw;
35};
36#pragma pack()
37
38#ifdef __KERNEL__
39int as102_fw_upload(struct as102_bus_adapter_t *bus_adap);
40#endif
41
42/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
new file mode 100644
index 000000000000..264be2dbd2a4
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -0,0 +1,478 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/slab.h>
23#include <linux/mm.h>
24#include <linux/usb.h>
25
26#include "as102_drv.h"
27#include "as102_usb_drv.h"
28#include "as102_fw.h"
29
30static void as102_usb_disconnect(struct usb_interface *interface);
31static int as102_usb_probe(struct usb_interface *interface,
32 const struct usb_device_id *id);
33
34static int as102_usb_start_stream(struct as102_dev_t *dev);
35static void as102_usb_stop_stream(struct as102_dev_t *dev);
36
37static int as102_open(struct inode *inode, struct file *file);
38static int as102_release(struct inode *inode, struct file *file);
39
40static struct usb_device_id as102_usb_id_table[] = {
41 { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
42 { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
43 { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
44 { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
45 { } /* Terminating entry */
46};
47
48/* Note that this table must always have the same number of entries as the
49 as102_usb_id_table struct */
50static const char *as102_device_names[] = {
51 AS102_REFERENCE_DESIGN,
52 AS102_PCTV_74E,
53 AS102_ELGATO_EYETV_DTT_NAME,
54 AS102_NBOX_DVBT_DONGLE_NAME,
55 NULL /* Terminating entry */
56};
57
58struct usb_driver as102_usb_driver = {
59 .name = DRIVER_FULL_NAME,
60 .probe = as102_usb_probe,
61 .disconnect = as102_usb_disconnect,
62 .id_table = as102_usb_id_table
63};
64
65static const struct file_operations as102_dev_fops = {
66 .owner = THIS_MODULE,
67 .open = as102_open,
68 .release = as102_release,
69};
70
71static struct usb_class_driver as102_usb_class_driver = {
72 .name = "aton2-%d",
73 .fops = &as102_dev_fops,
74 .minor_base = AS102_DEVICE_MAJOR,
75};
76
77static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap,
78 unsigned char *send_buf, int send_buf_len,
79 unsigned char *recv_buf, int recv_buf_len)
80{
81 int ret = 0;
82 ENTER();
83
84 if (send_buf != NULL) {
85 ret = usb_control_msg(bus_adap->usb_dev,
86 usb_sndctrlpipe(bus_adap->usb_dev, 0),
87 AS102_USB_DEVICE_TX_CTRL_CMD,
88 USB_DIR_OUT | USB_TYPE_VENDOR |
89 USB_RECIP_DEVICE,
90 bus_adap->cmd_xid, /* value */
91 0, /* index */
92 send_buf, send_buf_len,
93 USB_CTRL_SET_TIMEOUT /* 200 */);
94 if (ret < 0) {
95 dprintk(debug, "usb_control_msg(send) failed, err %i\n",
96 ret);
97 return ret;
98 }
99
100 if (ret != send_buf_len) {
101 dprintk(debug, "only wrote %d of %d bytes\n",
102 ret, send_buf_len);
103 return -1;
104 }
105 }
106
107 if (recv_buf != NULL) {
108#ifdef TRACE
109 dprintk(debug, "want to read: %d bytes\n", recv_buf_len);
110#endif
111 ret = usb_control_msg(bus_adap->usb_dev,
112 usb_rcvctrlpipe(bus_adap->usb_dev, 0),
113 AS102_USB_DEVICE_RX_CTRL_CMD,
114 USB_DIR_IN | USB_TYPE_VENDOR |
115 USB_RECIP_DEVICE,
116 bus_adap->cmd_xid, /* value */
117 0, /* index */
118 recv_buf, recv_buf_len,
119 USB_CTRL_GET_TIMEOUT /* 200 */);
120 if (ret < 0) {
121 dprintk(debug, "usb_control_msg(recv) failed, err %i\n",
122 ret);
123 return ret;
124 }
125#ifdef TRACE
126 dprintk(debug, "read %d bytes\n", recv_buf_len);
127#endif
128 }
129
130 LEAVE();
131 return ret;
132}
133
134static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap,
135 unsigned char *send_buf,
136 int send_buf_len,
137 int swap32)
138{
139 int ret = 0, actual_len;
140
141 ret = usb_bulk_msg(bus_adap->usb_dev,
142 usb_sndbulkpipe(bus_adap->usb_dev, 1),
143 send_buf, send_buf_len, &actual_len, 200);
144 if (ret) {
145 dprintk(debug, "usb_bulk_msg(send) failed, err %i\n", ret);
146 return ret;
147 }
148
149 if (actual_len != send_buf_len) {
150 dprintk(debug, "only wrote %d of %d bytes\n",
151 actual_len, send_buf_len);
152 return -1;
153 }
154 return ret ? ret : actual_len;
155}
156
157static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap,
158 unsigned char *recv_buf, int recv_buf_len)
159{
160 int ret = 0, actual_len;
161
162 if (recv_buf == NULL)
163 return -EINVAL;
164
165 ret = usb_bulk_msg(bus_adap->usb_dev,
166 usb_rcvbulkpipe(bus_adap->usb_dev, 2),
167 recv_buf, recv_buf_len, &actual_len, 200);
168 if (ret) {
169 dprintk(debug, "usb_bulk_msg(recv) failed, err %i\n", ret);
170 return ret;
171 }
172
173 if (actual_len != recv_buf_len) {
174 dprintk(debug, "only read %d of %d bytes\n",
175 actual_len, recv_buf_len);
176 return -1;
177 }
178 return ret ? ret : actual_len;
179}
180
181struct as102_priv_ops_t as102_priv_ops = {
182 .upload_fw_pkt = as102_send_ep1,
183 .xfer_cmd = as102_usb_xfer_cmd,
184 .as102_read_ep2 = as102_read_ep2,
185 .start_stream = as102_usb_start_stream,
186 .stop_stream = as102_usb_stop_stream,
187};
188
189static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb)
190{
191 int err;
192
193 usb_fill_bulk_urb(urb,
194 dev->bus_adap.usb_dev,
195 usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2),
196 urb->transfer_buffer,
197 AS102_USB_BUF_SIZE,
198 as102_urb_stream_irq,
199 dev);
200
201 err = usb_submit_urb(urb, GFP_ATOMIC);
202 if (err)
203 dprintk(debug, "%s: usb_submit_urb failed\n", __func__);
204
205 return err;
206}
207
208void as102_urb_stream_irq(struct urb *urb)
209{
210 struct as102_dev_t *as102_dev = urb->context;
211
212 if (urb->actual_length > 0) {
213 dvb_dmx_swfilter(&as102_dev->dvb_dmx,
214 urb->transfer_buffer,
215 urb->actual_length);
216 } else {
217 if (urb->actual_length == 0)
218 memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE);
219 }
220
221 /* is not stopped, re-submit urb */
222 if (as102_dev->streaming)
223 as102_submit_urb_stream(as102_dev, urb);
224}
225
226static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
227{
228 int i;
229
230 ENTER();
231
232 for (i = 0; i < MAX_STREAM_URB; i++)
233 usb_free_urb(dev->stream_urb[i]);
234
235 usb_free_coherent(dev->bus_adap.usb_dev,
236 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
237 dev->stream,
238 dev->dma_addr);
239 LEAVE();
240}
241
242static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
243{
244 int i, ret = 0;
245
246 ENTER();
247
248 dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev,
249 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
250 GFP_KERNEL,
251 &dev->dma_addr);
252 if (!dev->stream) {
253 dprintk(debug, "%s: usb_buffer_alloc failed\n", __func__);
254 return -ENOMEM;
255 }
256
257 memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE);
258
259 /* init urb buffers */
260 for (i = 0; i < MAX_STREAM_URB; i++) {
261 struct urb *urb;
262
263 urb = usb_alloc_urb(0, GFP_ATOMIC);
264 if (urb == NULL) {
265 dprintk(debug, "%s: usb_alloc_urb failed\n", __func__);
266 as102_free_usb_stream_buffer(dev);
267 return -ENOMEM;
268 }
269
270 urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE);
271 urb->transfer_buffer_length = AS102_USB_BUF_SIZE;
272
273 dev->stream_urb[i] = urb;
274 }
275 LEAVE();
276 return ret;
277}
278
279static void as102_usb_stop_stream(struct as102_dev_t *dev)
280{
281 int i;
282
283 for (i = 0; i < MAX_STREAM_URB; i++)
284 usb_kill_urb(dev->stream_urb[i]);
285}
286
287static int as102_usb_start_stream(struct as102_dev_t *dev)
288{
289 int i, ret = 0;
290
291 for (i = 0; i < MAX_STREAM_URB; i++) {
292 ret = as102_submit_urb_stream(dev, dev->stream_urb[i]);
293 if (ret) {
294 as102_usb_stop_stream(dev);
295 return ret;
296 }
297 }
298
299 return 0;
300}
301
302static void as102_usb_release(struct kref *kref)
303{
304 struct as102_dev_t *as102_dev;
305
306 ENTER();
307
308 as102_dev = container_of(kref, struct as102_dev_t, kref);
309 if (as102_dev != NULL) {
310 usb_put_dev(as102_dev->bus_adap.usb_dev);
311 kfree(as102_dev);
312 }
313
314 LEAVE();
315}
316
317static void as102_usb_disconnect(struct usb_interface *intf)
318{
319 struct as102_dev_t *as102_dev;
320
321 ENTER();
322
323 /* extract as102_dev_t from usb_device private data */
324 as102_dev = usb_get_intfdata(intf);
325
326 /* unregister dvb layer */
327 as102_dvb_unregister(as102_dev);
328
329 /* free usb buffers */
330 as102_free_usb_stream_buffer(as102_dev);
331
332 usb_set_intfdata(intf, NULL);
333
334 /* usb unregister device */
335 usb_deregister_dev(intf, &as102_usb_class_driver);
336
337 /* decrement usage counter */
338 kref_put(&as102_dev->kref, as102_usb_release);
339
340 printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME);
341
342 LEAVE();
343}
344
345static int as102_usb_probe(struct usb_interface *intf,
346 const struct usb_device_id *id)
347{
348 int ret;
349 struct as102_dev_t *as102_dev;
350 int i;
351
352 ENTER();
353
354 as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
355 if (as102_dev == NULL) {
356 err("%s: kzalloc failed", __func__);
357 return -ENOMEM;
358 }
359
360 /* This should never actually happen */
361 if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) !=
362 (sizeof(as102_device_names) / sizeof(const char *))) {
363 printk(KERN_ERR "Device names table invalid size");
364 return -EINVAL;
365 }
366
367 /* Assign the user-friendly device name */
368 for (i = 0; i < (sizeof(as102_usb_id_table) /
369 sizeof(struct usb_device_id)); i++) {
370 if (id == &as102_usb_id_table[i])
371 as102_dev->name = as102_device_names[i];
372 }
373
374 if (as102_dev->name == NULL)
375 as102_dev->name = "Unknown AS102 device";
376
377 /* set private callback functions */
378 as102_dev->bus_adap.ops = &as102_priv_ops;
379
380 /* init cmd token for usb bus */
381 as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
382 as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;
383
384 /* init kernel device reference */
385 kref_init(&as102_dev->kref);
386
387 /* store as102 device to usb_device private data */
388 usb_set_intfdata(intf, (void *) as102_dev);
389
390 /* store in as102 device the usb_device pointer */
391 as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));
392
393 /* we can register the device now, as it is ready */
394 ret = usb_register_dev(intf, &as102_usb_class_driver);
395 if (ret < 0) {
396 /* something prevented us from registering this driver */
397 err("%s: usb_register_dev() failed (errno = %d)",
398 __func__, ret);
399 goto failed;
400 }
401
402 printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME);
403
404 /* request buffer allocation for streaming */
405 ret = as102_alloc_usb_stream_buffer(as102_dev);
406 if (ret != 0)
407 goto failed;
408
409 /* register dvb layer */
410 ret = as102_dvb_register(as102_dev);
411
412 LEAVE();
413 return ret;
414
415failed:
416 usb_set_intfdata(intf, NULL);
417 kfree(as102_dev);
418 return ret;
419}
420
421static int as102_open(struct inode *inode, struct file *file)
422{
423 int ret = 0, minor = 0;
424 struct usb_interface *intf = NULL;
425 struct as102_dev_t *dev = NULL;
426
427 ENTER();
428
429 /* read minor from inode */
430 minor = iminor(inode);
431
432 /* fetch device from usb interface */
433 intf = usb_find_interface(&as102_usb_driver, minor);
434 if (intf == NULL) {
435 printk(KERN_ERR "%s: can't find device for minor %d\n",
436 __func__, minor);
437 ret = -ENODEV;
438 goto exit;
439 }
440
441 /* get our device */
442 dev = usb_get_intfdata(intf);
443 if (dev == NULL) {
444 ret = -EFAULT;
445 goto exit;
446 }
447
448 /* save our device object in the file's private structure */
449 file->private_data = dev;
450
451 /* increment our usage count for the device */
452 kref_get(&dev->kref);
453
454exit:
455 LEAVE();
456 return ret;
457}
458
459static int as102_release(struct inode *inode, struct file *file)
460{
461 int ret = 0;
462 struct as102_dev_t *dev = NULL;
463
464 ENTER();
465
466 dev = file->private_data;
467 if (dev != NULL) {
468 /* decrement the count on our device */
469 kref_put(&dev->kref, as102_usb_release);
470 }
471
472 LEAVE();
473 return ret;
474}
475
476MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
477
478/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h
new file mode 100644
index 000000000000..fb1fc41dcd79
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.h
@@ -0,0 +1,59 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/version.h>
21
22#ifndef _AS102_USB_DRV_H_
23#define _AS102_USB_DRV_H_
24
25#define AS102_USB_DEVICE_TX_CTRL_CMD 0xF1
26#define AS102_USB_DEVICE_RX_CTRL_CMD 0xF2
27
28/* define these values to match the supported devices */
29
30/* Abilis system: "TITAN" */
31#define AS102_REFERENCE_DESIGN "Abilis Systems DVB-Titan"
32#define AS102_USB_DEVICE_VENDOR_ID 0x1BA6
33#define AS102_USB_DEVICE_PID_0001 0x0001
34
35/* PCTV Systems: PCTV picoStick (74e) */
36#define AS102_PCTV_74E "PCTV Systems picoStick (74e)"
37#define PCTV_74E_USB_VID 0x2013
38#define PCTV_74E_USB_PID 0x0246
39
40/* Elgato: EyeTV DTT Deluxe */
41#define AS102_ELGATO_EYETV_DTT_NAME "Elgato EyeTV DTT Deluxe"
42#define ELGATO_EYETV_DTT_USB_VID 0x0fd9
43#define ELGATO_EYETV_DTT_USB_PID 0x002c
44
45/* nBox: nBox DVB-T Dongle */
46#define AS102_NBOX_DVBT_DONGLE_NAME "nBox DVB-T Dongle"
47#define NBOX_DVBT_DONGLE_USB_VID 0x0b89
48#define NBOX_DVBT_DONGLE_USB_PID 0x0007
49
50void as102_urb_stream_irq(struct urb *urb);
51
52struct as10x_usb_token_cmd_t {
53 /* token cmd */
54 struct as10x_cmd_t c;
55 /* token response */
56 struct as10x_cmd_t r;
57};
58#endif
59/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
new file mode 100644
index 000000000000..0dcba8065780
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -0,0 +1,452 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/kernel.h>
22#include "as102_drv.h"
23#include "as10x_types.h"
24#include "as10x_cmd.h"
25
26/**
27 * as10x_cmd_turn_on - send turn on command to AS10x
28 * @phandle: pointer to AS10x handle
29 *
30 * Return 0 when no error, < 0 in case of error.
31 */
32int as10x_cmd_turn_on(as10x_handle_t *phandle)
33{
34 int error;
35 struct as10x_cmd_t *pcmd, *prsp;
36
37 ENTER();
38
39 pcmd = phandle->cmd;
40 prsp = phandle->rsp;
41
42 /* prepare command */
43 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
44 sizeof(pcmd->body.turn_on.req));
45
46 /* fill command */
47 pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
48
49 /* send command */
50 if (phandle->ops->xfer_cmd) {
51 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
52 sizeof(pcmd->body.turn_on.req) +
53 HEADER_SIZE,
54 (uint8_t *) prsp,
55 sizeof(prsp->body.turn_on.rsp) +
56 HEADER_SIZE);
57 } else {
58 error = AS10X_CMD_ERROR;
59 }
60
61 if (error < 0)
62 goto out;
63
64 /* parse response */
65 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
66
67out:
68 LEAVE();
69 return error;
70}
71
72/**
73 * as10x_cmd_turn_off - send turn off command to AS10x
74 * @phandle: pointer to AS10x handle
75 *
76 * Return 0 on success or negative value in case of error.
77 */
78int as10x_cmd_turn_off(as10x_handle_t *phandle)
79{
80 int error;
81 struct as10x_cmd_t *pcmd, *prsp;
82
83 ENTER();
84
85 pcmd = phandle->cmd;
86 prsp = phandle->rsp;
87
88 /* prepare command */
89 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
90 sizeof(pcmd->body.turn_off.req));
91
92 /* fill command */
93 pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
94
95 /* send command */
96 if (phandle->ops->xfer_cmd) {
97 error = phandle->ops->xfer_cmd(
98 phandle, (uint8_t *) pcmd,
99 sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
100 (uint8_t *) prsp,
101 sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
102 } else {
103 error = AS10X_CMD_ERROR;
104 }
105
106 if (error < 0)
107 goto out;
108
109 /* parse response */
110 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
111
112out:
113 LEAVE();
114 return error;
115}
116
117/**
118 * as10x_cmd_set_tune - send set tune command to AS10x
119 * @phandle: pointer to AS10x handle
120 * @ptune: tune parameters
121 *
122 * Return 0 on success or negative value in case of error.
123 */
124int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune)
125{
126 int error;
127 struct as10x_cmd_t *preq, *prsp;
128
129 ENTER();
130
131 preq = phandle->cmd;
132 prsp = phandle->rsp;
133
134 /* prepare command */
135 as10x_cmd_build(preq, (++phandle->cmd_xid),
136 sizeof(preq->body.set_tune.req));
137
138 /* fill command */
139 preq->body.set_tune.req.proc_id = cpu_to_le16(CONTROL_PROC_SETTUNE);
140 preq->body.set_tune.req.args.freq = cpu_to_le32(ptune->freq);
141 preq->body.set_tune.req.args.bandwidth = ptune->bandwidth;
142 preq->body.set_tune.req.args.hier_select = ptune->hier_select;
143 preq->body.set_tune.req.args.constellation = ptune->constellation;
144 preq->body.set_tune.req.args.hierarchy = ptune->hierarchy;
145 preq->body.set_tune.req.args.interleaving_mode =
146 ptune->interleaving_mode;
147 preq->body.set_tune.req.args.code_rate = ptune->code_rate;
148 preq->body.set_tune.req.args.guard_interval = ptune->guard_interval;
149 preq->body.set_tune.req.args.transmission_mode =
150 ptune->transmission_mode;
151
152 /* send command */
153 if (phandle->ops->xfer_cmd) {
154 error = phandle->ops->xfer_cmd(phandle,
155 (uint8_t *) preq,
156 sizeof(preq->body.set_tune.req)
157 + HEADER_SIZE,
158 (uint8_t *) prsp,
159 sizeof(prsp->body.set_tune.rsp)
160 + HEADER_SIZE);
161 } else {
162 error = AS10X_CMD_ERROR;
163 }
164
165 if (error < 0)
166 goto out;
167
168 /* parse response */
169 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
170
171out:
172 LEAVE();
173 return error;
174}
175
176/**
177 * as10x_cmd_get_tune_status - send get tune status command to AS10x
178 * @phandle: pointer to AS10x handle
179 * @pstatus: pointer to updated status structure of the current tune
180 *
181 * Return 0 on success or negative value in case of error.
182 */
183int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
184 struct as10x_tune_status *pstatus)
185{
186 int error;
187 struct as10x_cmd_t *preq, *prsp;
188
189 ENTER();
190
191 preq = phandle->cmd;
192 prsp = phandle->rsp;
193
194 /* prepare command */
195 as10x_cmd_build(preq, (++phandle->cmd_xid),
196 sizeof(preq->body.get_tune_status.req));
197
198 /* fill command */
199 preq->body.get_tune_status.req.proc_id =
200 cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
201
202 /* send command */
203 if (phandle->ops->xfer_cmd) {
204 error = phandle->ops->xfer_cmd(
205 phandle,
206 (uint8_t *) preq,
207 sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
208 (uint8_t *) prsp,
209 sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
210 } else {
211 error = AS10X_CMD_ERROR;
212 }
213
214 if (error < 0)
215 goto out;
216
217 /* parse response */
218 error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP);
219 if (error < 0)
220 goto out;
221
222 /* Response OK -> get response data */
223 pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state;
224 pstatus->signal_strength =
225 le16_to_cpu(prsp->body.get_tune_status.rsp.sts.signal_strength);
226 pstatus->PER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.PER);
227 pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
228
229out:
230 LEAVE();
231 return error;
232}
233
234/**
235 * send get TPS command to AS10x
236 * @phandle: pointer to AS10x handle
237 * @ptps: pointer to TPS parameters structure
238 *
239 * Return 0 on success or negative value in case of error.
240 */
241int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps)
242{
243 int error;
244 struct as10x_cmd_t *pcmd, *prsp;
245
246 ENTER();
247
248 pcmd = phandle->cmd;
249 prsp = phandle->rsp;
250
251 /* prepare command */
252 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
253 sizeof(pcmd->body.get_tps.req));
254
255 /* fill command */
256 pcmd->body.get_tune_status.req.proc_id =
257 cpu_to_le16(CONTROL_PROC_GETTPS);
258
259 /* send command */
260 if (phandle->ops->xfer_cmd) {
261 error = phandle->ops->xfer_cmd(phandle,
262 (uint8_t *) pcmd,
263 sizeof(pcmd->body.get_tps.req) +
264 HEADER_SIZE,
265 (uint8_t *) prsp,
266 sizeof(prsp->body.get_tps.rsp) +
267 HEADER_SIZE);
268 } else {
269 error = AS10X_CMD_ERROR;
270 }
271
272 if (error < 0)
273 goto out;
274
275 /* parse response */
276 error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP);
277 if (error < 0)
278 goto out;
279
280 /* Response OK -> get response data */
281 ptps->constellation = prsp->body.get_tps.rsp.tps.constellation;
282 ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy;
283 ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode;
284 ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP;
285 ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP;
286 ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval;
287 ptps->transmission_mode = prsp->body.get_tps.rsp.tps.transmission_mode;
288 ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
289 ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
290 ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
291
292out:
293 LEAVE();
294 return error;
295}
296
297/**
298 * as10x_cmd_get_demod_stats - send get demod stats command to AS10x
299 * @phandle: pointer to AS10x handle
300 * @pdemod_stats: pointer to demod stats parameters structure
301 *
302 * Return 0 on success or negative value in case of error.
303 */
304int as10x_cmd_get_demod_stats(as10x_handle_t *phandle,
305 struct as10x_demod_stats *pdemod_stats)
306{
307 int error;
308 struct as10x_cmd_t *pcmd, *prsp;
309
310 ENTER();
311
312 pcmd = phandle->cmd;
313 prsp = phandle->rsp;
314
315 /* prepare command */
316 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
317 sizeof(pcmd->body.get_demod_stats.req));
318
319 /* fill command */
320 pcmd->body.get_demod_stats.req.proc_id =
321 cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
322
323 /* send command */
324 if (phandle->ops->xfer_cmd) {
325 error = phandle->ops->xfer_cmd(phandle,
326 (uint8_t *) pcmd,
327 sizeof(pcmd->body.get_demod_stats.req)
328 + HEADER_SIZE,
329 (uint8_t *) prsp,
330 sizeof(prsp->body.get_demod_stats.rsp)
331 + HEADER_SIZE);
332 } else {
333 error = AS10X_CMD_ERROR;
334 }
335
336 if (error < 0)
337 goto out;
338
339 /* parse response */
340 error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_DEMOD_STATS_RSP);
341 if (error < 0)
342 goto out;
343
344 /* Response OK -> get response data */
345 pdemod_stats->frame_count =
346 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.frame_count);
347 pdemod_stats->bad_frame_count =
348 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
349 pdemod_stats->bytes_fixed_by_rs =
350 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
351 pdemod_stats->mer =
352 le16_to_cpu(prsp->body.get_demod_stats.rsp.stats.mer);
353 pdemod_stats->has_started =
354 prsp->body.get_demod_stats.rsp.stats.has_started;
355
356out:
357 LEAVE();
358 return error;
359}
360
361/**
362 * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x
363 * @phandle: pointer to AS10x handle
364 * @is_ready: pointer to value indicating when impulse
365 * response data is ready
366 *
367 * Return 0 on success or negative value in case of error.
368 */
369int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
370 uint8_t *is_ready)
371{
372 int error;
373 struct as10x_cmd_t *pcmd, *prsp;
374
375 ENTER();
376
377 pcmd = phandle->cmd;
378 prsp = phandle->rsp;
379
380 /* prepare command */
381 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
382 sizeof(pcmd->body.get_impulse_rsp.req));
383
384 /* fill command */
385 pcmd->body.get_impulse_rsp.req.proc_id =
386 cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
387
388 /* send command */
389 if (phandle->ops->xfer_cmd) {
390 error = phandle->ops->xfer_cmd(phandle,
391 (uint8_t *) pcmd,
392 sizeof(pcmd->body.get_impulse_rsp.req)
393 + HEADER_SIZE,
394 (uint8_t *) prsp,
395 sizeof(prsp->body.get_impulse_rsp.rsp)
396 + HEADER_SIZE);
397 } else {
398 error = AS10X_CMD_ERROR;
399 }
400
401 if (error < 0)
402 goto out;
403
404 /* parse response */
405 error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_IMPULSE_RESP_RSP);
406 if (error < 0)
407 goto out;
408
409 /* Response OK -> get response data */
410 *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
411
412out:
413 LEAVE();
414 return error;
415}
416
417/**
418 * as10x_cmd_build - build AS10x command header
419 * @pcmd: pointer to AS10x command buffer
420 * @xid: sequence id of the command
421 * @cmd_len: length of the command
422 */
423void as10x_cmd_build(struct as10x_cmd_t *pcmd,
424 uint16_t xid, uint16_t cmd_len)
425{
426 pcmd->header.req_id = cpu_to_le16(xid);
427 pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
428 pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
429 pcmd->header.data_len = cpu_to_le16(cmd_len);
430}
431
432/**
433 * as10x_rsp_parse - Parse command response
434 * @prsp: pointer to AS10x command buffer
435 * @proc_id: id of the command
436 *
437 * Return 0 on success or negative value in case of error.
438 */
439int as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
440{
441 int error;
442
443 /* extract command error code */
444 error = prsp->body.common.rsp.error;
445
446 if ((error == 0) &&
447 (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
448 return 0;
449 }
450
451 return AS10X_CMD_ERROR;
452}
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h
new file mode 100644
index 000000000000..01a716380e0a
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.h
@@ -0,0 +1,540 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifndef _AS10X_CMD_H_
20#define _AS10X_CMD_H_
21
22#ifdef __KERNEL__
23#include <linux/kernel.h>
24#endif
25
26#include "as10x_types.h"
27
28/*********************************/
29/* MACRO DEFINITIONS */
30/*********************************/
31#define AS10X_CMD_ERROR -1
32
33#define SERVICE_PROG_ID 0x0002
34#define SERVICE_PROG_VERSION 0x0001
35
36#define HIER_NONE 0x00
37#define HIER_LOW_PRIORITY 0x01
38
39#define HEADER_SIZE (sizeof(struct as10x_cmd_header_t))
40
41/* context request types */
42#define GET_CONTEXT_DATA 1
43#define SET_CONTEXT_DATA 2
44
45/* ODSP suspend modes */
46#define CFG_MODE_ODSP_RESUME 0
47#define CFG_MODE_ODSP_SUSPEND 1
48
49/* Dump memory size */
50#define DUMP_BLOCK_SIZE_MAX 0x20
51
52/*********************************/
53/* TYPE DEFINITION */
54/*********************************/
55typedef enum {
56 CONTROL_PROC_TURNON = 0x0001,
57 CONTROL_PROC_TURNON_RSP = 0x0100,
58 CONTROL_PROC_SET_REGISTER = 0x0002,
59 CONTROL_PROC_SET_REGISTER_RSP = 0x0200,
60 CONTROL_PROC_GET_REGISTER = 0x0003,
61 CONTROL_PROC_GET_REGISTER_RSP = 0x0300,
62 CONTROL_PROC_SETTUNE = 0x000A,
63 CONTROL_PROC_SETTUNE_RSP = 0x0A00,
64 CONTROL_PROC_GETTUNESTAT = 0x000B,
65 CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00,
66 CONTROL_PROC_GETTPS = 0x000D,
67 CONTROL_PROC_GETTPS_RSP = 0x0D00,
68 CONTROL_PROC_SETFILTER = 0x000E,
69 CONTROL_PROC_SETFILTER_RSP = 0x0E00,
70 CONTROL_PROC_REMOVEFILTER = 0x000F,
71 CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00,
72 CONTROL_PROC_GET_IMPULSE_RESP = 0x0012,
73 CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200,
74 CONTROL_PROC_START_STREAMING = 0x0013,
75 CONTROL_PROC_START_STREAMING_RSP = 0x1300,
76 CONTROL_PROC_STOP_STREAMING = 0x0014,
77 CONTROL_PROC_STOP_STREAMING_RSP = 0x1400,
78 CONTROL_PROC_GET_DEMOD_STATS = 0x0015,
79 CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500,
80 CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016,
81 CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600,
82 CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017,
83 CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700,
84 CONTROL_PROC_AGC_CHANGE_MODE = 0x0018,
85 CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800,
86
87 CONTROL_PROC_CONTEXT = 0x00FC,
88 CONTROL_PROC_CONTEXT_RSP = 0xFC00,
89 CONTROL_PROC_DUMP_MEMORY = 0x00FD,
90 CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00,
91 CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE,
92 CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00,
93 CONTROL_PROC_TURNOFF = 0x00FF,
94 CONTROL_PROC_TURNOFF_RSP = 0xFF00
95} control_proc;
96
97
98#pragma pack(1)
99typedef union {
100 /* request */
101 struct {
102 /* request identifier */
103 uint16_t proc_id;
104 } req;
105 /* response */
106 struct {
107 /* response identifier */
108 uint16_t proc_id;
109 /* error */
110 uint8_t error;
111 } rsp;
112} TURN_ON;
113
114typedef union {
115 /* request */
116 struct {
117 /* request identifier */
118 uint16_t proc_id;
119 } req;
120 /* response */
121 struct {
122 /* response identifier */
123 uint16_t proc_id;
124 /* error */
125 uint8_t err;
126 } rsp;
127} TURN_OFF;
128
129typedef union {
130 /* request */
131 struct {
132 /* request identifier */
133 uint16_t proc_id;
134 /* tune params */
135 struct as10x_tune_args args;
136 } req;
137 /* response */
138 struct {
139 /* response identifier */
140 uint16_t proc_id;
141 /* response error */
142 uint8_t error;
143 } rsp;
144} SET_TUNE;
145
146typedef union {
147 /* request */
148 struct {
149 /* request identifier */
150 uint16_t proc_id;
151 } req;
152 /* response */
153 struct {
154 /* response identifier */
155 uint16_t proc_id;
156 /* response error */
157 uint8_t error;
158 /* tune status */
159 struct as10x_tune_status sts;
160 } rsp;
161} GET_TUNE_STATUS;
162
163typedef union {
164 /* request */
165 struct {
166 /* request identifier */
167 uint16_t proc_id;
168 } req;
169 /* response */
170 struct {
171 /* response identifier */
172 uint16_t proc_id;
173 /* response error */
174 uint8_t error;
175 /* tps details */
176 struct as10x_tps tps;
177 } rsp;
178} GET_TPS;
179
180typedef union {
181 /* request */
182 struct {
183 /* request identifier */
184 uint16_t proc_id;
185 } req;
186 /* response */
187 struct {
188 /* response identifier */
189 uint16_t proc_id;
190 /* response error */
191 uint8_t error;
192 } rsp;
193} COMMON;
194
195typedef union {
196 /* request */
197 struct {
198 /* request identifier */
199 uint16_t proc_id;
200 /* PID to filter */
201 uint16_t pid;
202 /* stream type (MPE, PSI/SI or PES )*/
203 uint8_t stream_type;
204 /* PID index in filter table */
205 uint8_t idx;
206 } req;
207 /* response */
208 struct {
209 /* response identifier */
210 uint16_t proc_id;
211 /* response error */
212 uint8_t error;
213 /* Filter id */
214 uint8_t filter_id;
215 } rsp;
216} ADD_PID_FILTER;
217
218typedef union {
219 /* request */
220 struct {
221 /* request identifier */
222 uint16_t proc_id;
223 /* PID to remove */
224 uint16_t pid;
225 } req;
226 /* response */
227 struct {
228 /* response identifier */
229 uint16_t proc_id;
230 /* response error */
231 uint8_t error;
232 } rsp;
233} DEL_PID_FILTER;
234
235typedef union {
236 /* request */
237 struct {
238 /* request identifier */
239 uint16_t proc_id;
240 } req;
241 /* response */
242 struct {
243 /* response identifier */
244 uint16_t proc_id;
245 /* error */
246 uint8_t error;
247 } rsp;
248} START_STREAMING;
249
250typedef union {
251 /* request */
252 struct {
253 /* request identifier */
254 uint16_t proc_id;
255 } req;
256 /* response */
257 struct {
258 /* response identifier */
259 uint16_t proc_id;
260 /* error */
261 uint8_t error;
262 } rsp;
263} STOP_STREAMING;
264
265typedef union {
266 /* request */
267 struct {
268 /* request identifier */
269 uint16_t proc_id;
270 } req;
271 /* response */
272 struct {
273 /* response identifier */
274 uint16_t proc_id;
275 /* error */
276 uint8_t error;
277 /* demod stats */
278 struct as10x_demod_stats stats;
279 } rsp;
280} GET_DEMOD_STATS;
281
282typedef union {
283 /* request */
284 struct {
285 /* request identifier */
286 uint16_t proc_id;
287 } req;
288 /* response */
289 struct {
290 /* response identifier */
291 uint16_t proc_id;
292 /* error */
293 uint8_t error;
294 /* impulse response ready */
295 uint8_t is_ready;
296 } rsp;
297} GET_IMPULSE_RESP;
298
299typedef union {
300 /* request */
301 struct {
302 /* request identifier */
303 uint16_t proc_id;
304 /* value to write (for set context)*/
305 struct as10x_register_value reg_val;
306 /* context tag */
307 uint16_t tag;
308 /* context request type */
309 uint16_t type;
310 } req;
311 /* response */
312 struct {
313 /* response identifier */
314 uint16_t proc_id;
315 /* value read (for get context) */
316 struct as10x_register_value reg_val;
317 /* context request type */
318 uint16_t type;
319 /* error */
320 uint8_t error;
321 } rsp;
322} FW_CONTEXT;
323
324typedef union {
325 /* request */
326 struct {
327 /* response identifier */
328 uint16_t proc_id;
329 /* register description */
330 struct as10x_register_addr reg_addr;
331 /* register content */
332 struct as10x_register_value reg_val;
333 } req;
334 /* response */
335 struct {
336 /* response identifier */
337 uint16_t proc_id;
338 /* error */
339 uint8_t error;
340 } rsp;
341} SET_REGISTER;
342
343typedef union {
344 /* request */
345 struct {
346 /* response identifier */
347 uint16_t proc_id;
348 /* register description */
349 struct as10x_register_addr reg_addr;
350 } req;
351 /* response */
352 struct {
353 /* response identifier */
354 uint16_t proc_id;
355 /* error */
356 uint8_t error;
357 /* register content */
358 struct as10x_register_value reg_val;
359 } rsp;
360} GET_REGISTER;
361
362typedef union {
363 /* request */
364 struct {
365 /* request identifier */
366 uint16_t proc_id;
367 /* mode */
368 uint8_t mode;
369 } req;
370 /* response */
371 struct {
372 /* response identifier */
373 uint16_t proc_id;
374 /* error */
375 uint8_t error;
376 } rsp;
377} CFG_CHANGE_MODE;
378
379struct as10x_cmd_header_t {
380 uint16_t req_id;
381 uint16_t prog;
382 uint16_t version;
383 uint16_t data_len;
384};
385
386#define DUMP_BLOCK_SIZE 16
387typedef union {
388 /* request */
389 struct {
390 /* request identifier */
391 uint16_t proc_id;
392 /* dump memory type request */
393 uint8_t dump_req;
394 /* register description */
395 struct as10x_register_addr reg_addr;
396 /* nb blocks to read */
397 uint16_t num_blocks;
398 } req;
399 /* response */
400 struct {
401 /* response identifier */
402 uint16_t proc_id;
403 /* error */
404 uint8_t error;
405 /* dump response */
406 uint8_t dump_rsp;
407 /* data */
408 union {
409 uint8_t data8[DUMP_BLOCK_SIZE];
410 uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
411 uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
412 } u;
413 } rsp;
414} DUMP_MEMORY;
415
416typedef union {
417 struct {
418 /* request identifier */
419 uint16_t proc_id;
420 /* dump memory type request */
421 uint8_t dump_req;
422 } req;
423 struct {
424 /* request identifier */
425 uint16_t proc_id;
426 /* error */
427 uint8_t error;
428 /* dump response */
429 uint8_t dump_rsp;
430 /* dump data */
431 uint8_t data[DUMP_BLOCK_SIZE];
432 } rsp;
433} DUMPLOG_MEMORY;
434
435typedef union {
436 /* request */
437 struct {
438 uint16_t proc_id;
439 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */];
440 } req;
441 /* response */
442 struct {
443 uint16_t proc_id;
444 uint8_t error;
445 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */
446 - 2 /* proc_id */ - 1 /* rc */];
447 } rsp;
448} RAW_DATA;
449
450struct as10x_cmd_t {
451 /* header */
452 struct as10x_cmd_header_t header;
453 /* body */
454 union {
455 TURN_ON turn_on;
456 TURN_OFF turn_off;
457 SET_TUNE set_tune;
458 GET_TUNE_STATUS get_tune_status;
459 GET_TPS get_tps;
460 COMMON common;
461 ADD_PID_FILTER add_pid_filter;
462 DEL_PID_FILTER del_pid_filter;
463 START_STREAMING start_streaming;
464 STOP_STREAMING stop_streaming;
465 GET_DEMOD_STATS get_demod_stats;
466 GET_IMPULSE_RESP get_impulse_rsp;
467 FW_CONTEXT context;
468 SET_REGISTER set_register;
469 GET_REGISTER get_register;
470 CFG_CHANGE_MODE cfg_change_mode;
471 DUMP_MEMORY dump_memory;
472 DUMPLOG_MEMORY dumplog_memory;
473 RAW_DATA raw_data;
474 } body;
475};
476
477struct as10x_token_cmd_t {
478 /* token cmd */
479 struct as10x_cmd_t c;
480 /* token response */
481 struct as10x_cmd_t r;
482};
483#pragma pack()
484
485
486/**************************/
487/* FUNCTION DECLARATION */
488/**************************/
489
490void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id,
491 uint16_t cmd_len);
492int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id);
493
494#ifdef __cplusplus
495extern "C" {
496#endif
497
498/* as10x cmd */
499int as10x_cmd_turn_on(as10x_handle_t *phandle);
500int as10x_cmd_turn_off(as10x_handle_t *phandle);
501
502int as10x_cmd_set_tune(as10x_handle_t *phandle,
503 struct as10x_tune_args *ptune);
504
505int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
506 struct as10x_tune_status *pstatus);
507
508int as10x_cmd_get_tps(as10x_handle_t *phandle,
509 struct as10x_tps *ptps);
510
511int as10x_cmd_get_demod_stats(as10x_handle_t *phandle,
512 struct as10x_demod_stats *pdemod_stats);
513
514int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
515 uint8_t *is_ready);
516
517/* as10x cmd stream */
518int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
519 struct as10x_ts_filter *filter);
520int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
521 uint16_t pid_value);
522
523int as10x_cmd_start_streaming(as10x_handle_t *phandle);
524int as10x_cmd_stop_streaming(as10x_handle_t *phandle);
525
526/* as10x cmd cfg */
527int as10x_cmd_set_context(as10x_handle_t *phandle,
528 uint16_t tag,
529 uint32_t value);
530int as10x_cmd_get_context(as10x_handle_t *phandle,
531 uint16_t tag,
532 uint32_t *pvalue);
533
534int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode);
535int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id);
536#ifdef __cplusplus
537}
538#endif
539#endif
540/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
new file mode 100644
index 000000000000..ec6f69fcf399
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_cfg.c
@@ -0,0 +1,215 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/kernel.h>
21#include "as102_drv.h"
22#include "as10x_types.h"
23#include "as10x_cmd.h"
24
25/***************************/
26/* FUNCTION DEFINITION */
27/***************************/
28
29/**
30 * as10x_cmd_get_context - Send get context command to AS10x
31 * @phandle: pointer to AS10x handle
32 * @tag: context tag
33 * @pvalue: pointer where to store context value read
34 *
35 * Return 0 on success or negative value in case of error.
36 */
37int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag,
38 uint32_t *pvalue)
39{
40 int error;
41 struct as10x_cmd_t *pcmd, *prsp;
42
43 ENTER();
44
45 pcmd = phandle->cmd;
46 prsp = phandle->rsp;
47
48 /* prepare command */
49 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
50 sizeof(pcmd->body.context.req));
51
52 /* fill command */
53 pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
54 pcmd->body.context.req.tag = cpu_to_le16(tag);
55 pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA);
56
57 /* send command */
58 if (phandle->ops->xfer_cmd) {
59 error = phandle->ops->xfer_cmd(phandle,
60 (uint8_t *) pcmd,
61 sizeof(pcmd->body.context.req)
62 + HEADER_SIZE,
63 (uint8_t *) prsp,
64 sizeof(prsp->body.context.rsp)
65 + HEADER_SIZE);
66 } else {
67 error = AS10X_CMD_ERROR;
68 }
69
70 if (error < 0)
71 goto out;
72
73 /* parse response: context command do not follow the common response */
74 /* structure -> specific handling response parse required */
75 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
76
77 if (error == 0) {
78 /* Response OK -> get response data */
79 *pvalue = le32_to_cpu(prsp->body.context.rsp.reg_val.u.value32);
80 /* value returned is always a 32-bit value */
81 }
82
83out:
84 LEAVE();
85 return error;
86}
87
88/**
89 * as10x_cmd_set_context - send set context command to AS10x
90 * @phandle: pointer to AS10x handle
91 * @tag: context tag
92 * @value: value to set in context
93 *
94 * Return 0 on success or negative value in case of error.
95 */
96int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag,
97 uint32_t value)
98{
99 int error;
100 struct as10x_cmd_t *pcmd, *prsp;
101
102 ENTER();
103
104 pcmd = phandle->cmd;
105 prsp = phandle->rsp;
106
107 /* prepare command */
108 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
109 sizeof(pcmd->body.context.req));
110
111 /* fill command */
112 pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
113 /* pcmd->body.context.req.reg_val.mode initialization is not required */
114 pcmd->body.context.req.reg_val.u.value32 = cpu_to_le32(value);
115 pcmd->body.context.req.tag = cpu_to_le16(tag);
116 pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA);
117
118 /* send command */
119 if (phandle->ops->xfer_cmd) {
120 error = phandle->ops->xfer_cmd(phandle,
121 (uint8_t *) pcmd,
122 sizeof(pcmd->body.context.req)
123 + HEADER_SIZE,
124 (uint8_t *) prsp,
125 sizeof(prsp->body.context.rsp)
126 + HEADER_SIZE);
127 } else {
128 error = AS10X_CMD_ERROR;
129 }
130
131 if (error < 0)
132 goto out;
133
134 /* parse response: context command do not follow the common response */
135 /* structure -> specific handling response parse required */
136 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
137
138out:
139 LEAVE();
140 return error;
141}
142
143/**
144 * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
145 * @phandle: pointer to AS10x handle
146 * @mode: mode selected:
147 * - ON : 0x0 => eLNA always ON
148 * - OFF : 0x1 => eLNA always OFF
149 * - AUTO : 0x2 => eLNA follow hysteresis parameters
150 * to be ON or OFF
151 *
152 * Return 0 on success or negative value in case of error.
153 */
154int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode)
155{
156 int error;
157 struct as10x_cmd_t *pcmd, *prsp;
158
159 ENTER();
160
161 pcmd = phandle->cmd;
162 prsp = phandle->rsp;
163
164 /* prepare command */
165 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
166 sizeof(pcmd->body.cfg_change_mode.req));
167
168 /* fill command */
169 pcmd->body.cfg_change_mode.req.proc_id =
170 cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE);
171 pcmd->body.cfg_change_mode.req.mode = mode;
172
173 /* send command */
174 if (phandle->ops->xfer_cmd) {
175 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
176 sizeof(pcmd->body.cfg_change_mode.req)
177 + HEADER_SIZE, (uint8_t *) prsp,
178 sizeof(prsp->body.cfg_change_mode.rsp)
179 + HEADER_SIZE);
180 } else {
181 error = AS10X_CMD_ERROR;
182 }
183
184 if (error < 0)
185 goto out;
186
187 /* parse response */
188 error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
189
190out:
191 LEAVE();
192 return error;
193}
194
195/**
196 * as10x_context_rsp_parse - Parse context command response
197 * @prsp: pointer to AS10x command response buffer
198 * @proc_id: id of the command
199 *
200 * Since the contex command reponse does not follow the common
201 * response, a specific parse function is required.
202 * Return 0 on success or negative value in case of error.
203 */
204int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
205{
206 int err;
207
208 err = prsp->body.context.rsp.error;
209
210 if ((err == 0) &&
211 (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) {
212 return 0;
213 }
214 return AS10X_CMD_ERROR;
215}
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
new file mode 100644
index 000000000000..045c70683193
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_stream.c
@@ -0,0 +1,223 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/kernel.h>
21#include "as102_drv.h"
22#include "as10x_cmd.h"
23
24/**
25 * as10x_cmd_add_PID_filter - send add filter command to AS10x
26 * @phandle: pointer to AS10x handle
27 * @filter: TSFilter filter for DVB-T
28 *
29 * Return 0 on success or negative value in case of error.
30 */
31int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
32 struct as10x_ts_filter *filter)
33{
34 int error;
35 struct as10x_cmd_t *pcmd, *prsp;
36
37 ENTER();
38
39 pcmd = phandle->cmd;
40 prsp = phandle->rsp;
41
42 /* prepare command */
43 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
44 sizeof(pcmd->body.add_pid_filter.req));
45
46 /* fill command */
47 pcmd->body.add_pid_filter.req.proc_id =
48 cpu_to_le16(CONTROL_PROC_SETFILTER);
49 pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
50 pcmd->body.add_pid_filter.req.stream_type = filter->type;
51
52 if (filter->idx < 16)
53 pcmd->body.add_pid_filter.req.idx = filter->idx;
54 else
55 pcmd->body.add_pid_filter.req.idx = 0xFF;
56
57 /* send command */
58 if (phandle->ops->xfer_cmd) {
59 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
60 sizeof(pcmd->body.add_pid_filter.req)
61 + HEADER_SIZE, (uint8_t *) prsp,
62 sizeof(prsp->body.add_pid_filter.rsp)
63 + HEADER_SIZE);
64 } else {
65 error = AS10X_CMD_ERROR;
66 }
67
68 if (error < 0)
69 goto out;
70
71 /* parse response */
72 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
73
74 if (error == 0) {
75 /* Response OK -> get response data */
76 filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
77 }
78
79out:
80 LEAVE();
81 return error;
82}
83
84/**
85 * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
86 * @phandle: pointer to AS10x handle
87 * @pid_value: PID to delete
88 *
89 * Return 0 on success or negative value in case of error.
90 */
91int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
92 uint16_t pid_value)
93{
94 int error;
95 struct as10x_cmd_t *pcmd, *prsp;
96
97 ENTER();
98
99 pcmd = phandle->cmd;
100 prsp = phandle->rsp;
101
102 /* prepare command */
103 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
104 sizeof(pcmd->body.del_pid_filter.req));
105
106 /* fill command */
107 pcmd->body.del_pid_filter.req.proc_id =
108 cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
109 pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
110
111 /* send command */
112 if (phandle->ops->xfer_cmd) {
113 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
114 sizeof(pcmd->body.del_pid_filter.req)
115 + HEADER_SIZE, (uint8_t *) prsp,
116 sizeof(prsp->body.del_pid_filter.rsp)
117 + HEADER_SIZE);
118 } else {
119 error = AS10X_CMD_ERROR;
120 }
121
122 if (error < 0)
123 goto out;
124
125 /* parse response */
126 error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
127
128out:
129 LEAVE();
130 return error;
131}
132
133/**
134 * as10x_cmd_start_streaming - Send start streaming command to AS10x
135 * @phandle: pointer to AS10x handle
136 *
137 * Return 0 on success or negative value in case of error.
138 */
139int as10x_cmd_start_streaming(as10x_handle_t *phandle)
140{
141 int error;
142 struct as10x_cmd_t *pcmd, *prsp;
143
144 ENTER();
145
146 pcmd = phandle->cmd;
147 prsp = phandle->rsp;
148
149 /* prepare command */
150 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
151 sizeof(pcmd->body.start_streaming.req));
152
153 /* fill command */
154 pcmd->body.start_streaming.req.proc_id =
155 cpu_to_le16(CONTROL_PROC_START_STREAMING);
156
157 /* send command */
158 if (phandle->ops->xfer_cmd) {
159 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
160 sizeof(pcmd->body.start_streaming.req)
161 + HEADER_SIZE, (uint8_t *) prsp,
162 sizeof(prsp->body.start_streaming.rsp)
163 + HEADER_SIZE);
164 } else {
165 error = AS10X_CMD_ERROR;
166 }
167
168 if (error < 0)
169 goto out;
170
171 /* parse response */
172 error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
173
174out:
175 LEAVE();
176 return error;
177}
178
179/**
180 * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
181 * @phandle: pointer to AS10x handle
182 *
183 * Return 0 on success or negative value in case of error.
184 */
185int as10x_cmd_stop_streaming(as10x_handle_t *phandle)
186{
187 int8_t error;
188 struct as10x_cmd_t *pcmd, *prsp;
189
190 ENTER();
191
192 pcmd = phandle->cmd;
193 prsp = phandle->rsp;
194
195 /* prepare command */
196 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
197 sizeof(pcmd->body.stop_streaming.req));
198
199 /* fill command */
200 pcmd->body.stop_streaming.req.proc_id =
201 cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
202
203 /* send command */
204 if (phandle->ops->xfer_cmd) {
205 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
206 sizeof(pcmd->body.stop_streaming.req)
207 + HEADER_SIZE, (uint8_t *) prsp,
208 sizeof(prsp->body.stop_streaming.rsp)
209 + HEADER_SIZE);
210 } else {
211 error = AS10X_CMD_ERROR;
212 }
213
214 if (error < 0)
215 goto out;
216
217 /* parse response */
218 error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
219
220out:
221 LEAVE();
222 return error;
223}
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h
new file mode 100644
index 000000000000..4f01a76e9829
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_handle.h
@@ -0,0 +1,58 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifdef __KERNEL__
20struct as102_bus_adapter_t;
21struct as102_dev_t;
22
23#define as10x_handle_t struct as102_bus_adapter_t
24#include "as10x_cmd.h"
25
26/* values for "mode" field */
27#define REGMODE8 8
28#define REGMODE16 16
29#define REGMODE32 32
30
31struct as102_priv_ops_t {
32 int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap,
33 unsigned char *buf, int buflen, int swap32);
34
35 int (*send_cmd) (struct as102_bus_adapter_t *bus_adap,
36 unsigned char *buf, int buflen);
37
38 int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap,
39 unsigned char *send_buf, int send_buf_len,
40 unsigned char *recv_buf, int recv_buf_len);
41/*
42 int (*pid_filter) (struct as102_bus_adapter_t *bus_adap,
43 int index, u16 pid, int onoff);
44*/
45 int (*start_stream) (struct as102_dev_t *dev);
46 void (*stop_stream) (struct as102_dev_t *dev);
47
48 int (*reset_target) (struct as102_bus_adapter_t *bus_adap);
49
50 int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode,
51 uint32_t rd_addr, uint16_t rd_len,
52 uint32_t wr_addr, uint16_t wr_len);
53
54 int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap,
55 unsigned char *recv_buf,
56 int recv_buf_len);
57};
58#endif
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h
new file mode 100644
index 000000000000..3dedb3c1420a
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_types.h
@@ -0,0 +1,198 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifndef _AS10X_TYPES_H_
20#define _AS10X_TYPES_H_
21
22#include "as10x_handle.h"
23
24/*********************************/
25/* MACRO DEFINITIONS */
26/*********************************/
27
28/* bandwidth constant values */
29#define BW_5_MHZ 0x00
30#define BW_6_MHZ 0x01
31#define BW_7_MHZ 0x02
32#define BW_8_MHZ 0x03
33
34/* hierarchy priority selection values */
35#define HIER_NO_PRIORITY 0x00
36#define HIER_LOW_PRIORITY 0x01
37#define HIER_HIGH_PRIORITY 0x02
38
39/* constellation available values */
40#define CONST_QPSK 0x00
41#define CONST_QAM16 0x01
42#define CONST_QAM64 0x02
43#define CONST_UNKNOWN 0xFF
44
45/* hierarchy available values */
46#define HIER_NONE 0x00
47#define HIER_ALPHA_1 0x01
48#define HIER_ALPHA_2 0x02
49#define HIER_ALPHA_4 0x03
50#define HIER_UNKNOWN 0xFF
51
52/* interleaving available values */
53#define INTLV_NATIVE 0x00
54#define INTLV_IN_DEPTH 0x01
55#define INTLV_UNKNOWN 0xFF
56
57/* code rate available values */
58#define CODE_RATE_1_2 0x00
59#define CODE_RATE_2_3 0x01
60#define CODE_RATE_3_4 0x02
61#define CODE_RATE_5_6 0x03
62#define CODE_RATE_7_8 0x04
63#define CODE_RATE_UNKNOWN 0xFF
64
65/* guard interval available values */
66#define GUARD_INT_1_32 0x00
67#define GUARD_INT_1_16 0x01
68#define GUARD_INT_1_8 0x02
69#define GUARD_INT_1_4 0x03
70#define GUARD_UNKNOWN 0xFF
71
72/* transmission mode available values */
73#define TRANS_MODE_2K 0x00
74#define TRANS_MODE_8K 0x01
75#define TRANS_MODE_4K 0x02
76#define TRANS_MODE_UNKNOWN 0xFF
77
78/* DVBH signalling available values */
79#define TIMESLICING_PRESENT 0x01
80#define MPE_FEC_PRESENT 0x02
81
82/* tune state available */
83#define TUNE_STATUS_NOT_TUNED 0x00
84#define TUNE_STATUS_IDLE 0x01
85#define TUNE_STATUS_LOCKING 0x02
86#define TUNE_STATUS_SIGNAL_DVB_OK 0x03
87#define TUNE_STATUS_STREAM_DETECTED 0x04
88#define TUNE_STATUS_STREAM_TUNED 0x05
89#define TUNE_STATUS_ERROR 0xFF
90
91/* available TS FID filter types */
92#define TS_PID_TYPE_TS 0
93#define TS_PID_TYPE_PSI_SI 1
94#define TS_PID_TYPE_MPE 2
95
96/* number of echos available */
97#define MAX_ECHOS 15
98
99/* Context types */
100#define CONTEXT_LNA 1010
101#define CONTEXT_ELNA_HYSTERESIS 4003
102#define CONTEXT_ELNA_GAIN 4004
103#define CONTEXT_MER_THRESHOLD 5005
104#define CONTEXT_MER_OFFSET 5006
105#define CONTEXT_IR_STATE 7000
106#define CONTEXT_TSOUT_MSB_FIRST 7004
107#define CONTEXT_TSOUT_FALLING_EDGE 7005
108
109/* Configuration modes */
110#define CFG_MODE_ON 0
111#define CFG_MODE_OFF 1
112#define CFG_MODE_AUTO 2
113
114#pragma pack(1)
115struct as10x_tps {
116 uint8_t constellation;
117 uint8_t hierarchy;
118 uint8_t interleaving_mode;
119 uint8_t code_rate_HP;
120 uint8_t code_rate_LP;
121 uint8_t guard_interval;
122 uint8_t transmission_mode;
123 uint8_t DVBH_mask_HP;
124 uint8_t DVBH_mask_LP;
125 uint16_t cell_ID;
126};
127
128struct as10x_tune_args {
129 /* frequency */
130 uint32_t freq;
131 /* bandwidth */
132 uint8_t bandwidth;
133 /* hierarchy selection */
134 uint8_t hier_select;
135 /* constellation */
136 uint8_t constellation;
137 /* hierarchy */
138 uint8_t hierarchy;
139 /* interleaving mode */
140 uint8_t interleaving_mode;
141 /* code rate */
142 uint8_t code_rate;
143 /* guard interval */
144 uint8_t guard_interval;
145 /* transmission mode */
146 uint8_t transmission_mode;
147};
148
149struct as10x_tune_status {
150 /* tune status */
151 uint8_t tune_state;
152 /* signal strength */
153 int16_t signal_strength;
154 /* packet error rate 10^-4 */
155 uint16_t PER;
156 /* bit error rate 10^-4 */
157 uint16_t BER;
158};
159
160struct as10x_demod_stats {
161 /* frame counter */
162 uint32_t frame_count;
163 /* Bad frame counter */
164 uint32_t bad_frame_count;
165 /* Number of wrong bytes fixed by Reed-Solomon */
166 uint32_t bytes_fixed_by_rs;
167 /* Averaged MER */
168 uint16_t mer;
169 /* statistics calculation state indicator (started or not) */
170 uint8_t has_started;
171};
172
173struct as10x_ts_filter {
174 uint16_t pid; /** valid PID value 0x00 : 0x2000 */
175 uint8_t type; /** Red TS_PID_TYPE_<N> values */
176 uint8_t idx; /** index in filtering table */
177};
178
179struct as10x_register_value {
180 uint8_t mode;
181 union {
182 uint8_t value8; /* 8 bit value */
183 uint16_t value16; /* 16 bit value */
184 uint32_t value32; /* 32 bit value */
185 }u;
186};
187
188#pragma pack()
189
190struct as10x_register_addr {
191 /* register addr */
192 uint32_t addr;
193 /* register mode access */
194 uint8_t mode;
195};
196
197
198#endif
diff --git a/drivers/staging/cxd2099/Kconfig b/drivers/staging/media/cxd2099/Kconfig
index b48aefddc84c..b48aefddc84c 100644
--- a/drivers/staging/cxd2099/Kconfig
+++ b/drivers/staging/media/cxd2099/Kconfig
diff --git a/drivers/staging/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index 64cfc77be357..64cfc77be357 100644
--- a/drivers/staging/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
diff --git a/drivers/staging/cxd2099/TODO b/drivers/staging/media/cxd2099/TODO
index 375bb6f8ee2c..375bb6f8ee2c 100644
--- a/drivers/staging/cxd2099/TODO
+++ b/drivers/staging/media/cxd2099/TODO
diff --git a/drivers/staging/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 1c04185bcfd7..1c04185bcfd7 100644
--- a/drivers/staging/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
diff --git a/drivers/staging/cxd2099/cxd2099.h b/drivers/staging/media/cxd2099/cxd2099.h
index 19c588a59588..19c588a59588 100644
--- a/drivers/staging/cxd2099/cxd2099.h
+++ b/drivers/staging/media/cxd2099/cxd2099.h
diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/media/dt3155v4l/Kconfig
index 226a1ca90b3c..226a1ca90b3c 100644
--- a/drivers/staging/dt3155v4l/Kconfig
+++ b/drivers/staging/media/dt3155v4l/Kconfig
diff --git a/drivers/staging/dt3155v4l/Makefile b/drivers/staging/media/dt3155v4l/Makefile
index ce7a3ec2faf3..ce7a3ec2faf3 100644
--- a/drivers/staging/dt3155v4l/Makefile
+++ b/drivers/staging/media/dt3155v4l/Makefile
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index 04e93c49f03a..04e93c49f03a 100644
--- a/drivers/staging/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/media/dt3155v4l/dt3155v4l.h
index 2e4f89d402e4..2e4f89d402e4 100644
--- a/drivers/staging/dt3155v4l/dt3155v4l.h
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.h
diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/media/easycap/Kconfig
index a425a6f9cdca..a425a6f9cdca 100644
--- a/drivers/staging/easycap/Kconfig
+++ b/drivers/staging/media/easycap/Kconfig
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/media/easycap/Makefile
index a34e75f59c18..a34e75f59c18 100644
--- a/drivers/staging/easycap/Makefile
+++ b/drivers/staging/media/easycap/Makefile
diff --git a/drivers/staging/easycap/README b/drivers/staging/media/easycap/README
index 796b032384bd..796b032384bd 100644
--- a/drivers/staging/easycap/README
+++ b/drivers/staging/media/easycap/README
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h
index 7b256a948c27..7b256a948c27 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/media/easycap/easycap.h
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c
index c99addfb6242..c99addfb6242 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/media/easycap/easycap_ioctl.c
diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c
index 0385735ac6df..0385735ac6df 100644
--- a/drivers/staging/easycap/easycap_low.c
+++ b/drivers/staging/media/easycap/easycap_low.c
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index a45c0b507067..a45c0b507067 100644
--- a/drivers/staging/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c
index 70f59b13c34d..70f59b13c34d 100644
--- a/drivers/staging/easycap/easycap_settings.c
+++ b/drivers/staging/media/easycap/easycap_settings.c
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c
index b22bb39b5f69..b22bb39b5f69 100644
--- a/drivers/staging/easycap/easycap_sound.c
+++ b/drivers/staging/media/easycap/easycap_sound.c
diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/media/easycap/easycap_testcard.c
index 0f71470ace39..0f71470ace39 100644
--- a/drivers/staging/easycap/easycap_testcard.c
+++ b/drivers/staging/media/easycap/easycap_testcard.c
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
index 7dfb2815b9ec..7dfb2815b9ec 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/media/go7007/Kconfig
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 6ee837c56706..6ee837c56706 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
diff --git a/drivers/staging/go7007/README b/drivers/staging/media/go7007/README
index 48f447637817..48f447637817 100644
--- a/drivers/staging/go7007/README
+++ b/drivers/staging/media/go7007/README
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 6c9279a6d606..6c9279a6d606 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c
index c9a6409edfe3..c9a6409edfe3 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/media/go7007/go7007-fw.c
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
index b8cfa1a6eaeb..b8cfa1a6eaeb 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/media/go7007/go7007-i2c.c
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b58c394c6555..b58c394c6555 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 3db3b0a91cc1..3db3b0a91cc1 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 2b27d8da70a2..2b27d8da70a2 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
diff --git a/drivers/staging/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
index 7399c915a934..7399c915a934 100644
--- a/drivers/staging/go7007/go7007.h
+++ b/drivers/staging/media/go7007/go7007.h
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
index 9db1f3952fd2..9db1f3952fd2 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/media/go7007/go7007.txt
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index e7736a915530..e7736a915530 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c
index 4e132519e253..4e132519e253 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/media/go7007/s2250-loader.c
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/media/go7007/s2250-loader.h
index b7c301af16cc..b7c301af16cc 100644
--- a/drivers/staging/go7007/s2250-loader.h
+++ b/drivers/staging/media/go7007/s2250-loader.h
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index cf7c34a99459..cf7c34a99459 100644
--- a/drivers/staging/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
index deac938d8505..deac938d8505 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/media/go7007/snd-go7007.c
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/media/go7007/wis-i2c.h
index 3c2b9be455df..3c2b9be455df 100644
--- a/drivers/staging/go7007/wis-i2c.h
+++ b/drivers/staging/media/go7007/wis-i2c.h
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/media/go7007/wis-ov7640.c
index 6bc9470fecb6..6bc9470fecb6 100644
--- a/drivers/staging/go7007/wis-ov7640.c
+++ b/drivers/staging/media/go7007/wis-ov7640.c
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/media/go7007/wis-saa7113.c
index 05e0e1083864..05e0e1083864 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/media/go7007/wis-saa7113.c
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/media/go7007/wis-saa7115.c
index 46cff59e28b7..46cff59e28b7 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/media/go7007/wis-saa7115.c
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/media/go7007/wis-sony-tuner.c
index 8f1b7d4f6a2e..8f1b7d4f6a2e 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/media/go7007/wis-sony-tuner.c
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/media/go7007/wis-tw2804.c
index 9134f03e3cf0..9134f03e3cf0 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/media/go7007/wis-tw2804.c
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/media/go7007/wis-tw9903.c
index 9230f4a80529..9230f4a80529 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/media/go7007/wis-tw9903.c
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/media/go7007/wis-uda1342.c
index 0127be2f3be0..0127be2f3be0 100644
--- a/drivers/staging/go7007/wis-uda1342.c
+++ b/drivers/staging/media/go7007/wis-uda1342.c
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index 526ec0fc2f04..526ec0fc2f04 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index d76b0fa2af53..d76b0fa2af53 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
diff --git a/drivers/staging/lirc/TODO b/drivers/staging/media/lirc/TODO
index b6cb593f55c6..b6cb593f55c6 100644
--- a/drivers/staging/lirc/TODO
+++ b/drivers/staging/media/lirc/TODO
diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/media/lirc/TODO.lirc_zilog
index a97800a8e127..a97800a8e127 100644
--- a/drivers/staging/lirc/TODO.lirc_zilog
+++ b/drivers/staging/media/lirc/TODO.lirc_zilog
diff --git a/drivers/staging/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c
index c5a0d27a02dc..c5a0d27a02dc 100644
--- a/drivers/staging/lirc/lirc_bt829.c
+++ b/drivers/staging/media/lirc/lirc_bt829.c
diff --git a/drivers/staging/lirc/lirc_ene0100.h b/drivers/staging/media/lirc/lirc_ene0100.h
index 06bebd6acc46..06bebd6acc46 100644
--- a/drivers/staging/lirc/lirc_ene0100.h
+++ b/drivers/staging/media/lirc/lirc_ene0100.h
diff --git a/drivers/staging/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 0dc2c2b22c2b..0dc2c2b22c2b 100644
--- a/drivers/staging/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index f5308d5929c6..f5308d5929c6 100644
--- a/drivers/staging/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 792aac0a8e7b..792aac0a8e7b 100644
--- a/drivers/staging/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
diff --git a/drivers/staging/lirc/lirc_parallel.h b/drivers/staging/media/lirc/lirc_parallel.h
index 4bed6afe0632..4bed6afe0632 100644
--- a/drivers/staging/lirc/lirc_parallel.h
+++ b/drivers/staging/media/lirc/lirc_parallel.h
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index a2d18b0aa048..a2d18b0aa048 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 8a060a8a7224..8a060a8a7224 100644
--- a/drivers/staging/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 6903d3992eca..6903d3992eca 100644
--- a/drivers/staging/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
diff --git a/drivers/staging/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c
index e4b329b8cafd..e4b329b8cafd 100644
--- a/drivers/staging/lirc/lirc_ttusbir.c
+++ b/drivers/staging/media/lirc/lirc_ttusbir.c
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
index 0302d82a12f7..0302d82a12f7 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig
index 03dcac4ea4d0..03dcac4ea4d0 100644
--- a/drivers/staging/solo6x10/Kconfig
+++ b/drivers/staging/media/solo6x10/Kconfig
diff --git a/drivers/staging/solo6x10/Makefile b/drivers/staging/media/solo6x10/Makefile
index 72816cf16704..72816cf16704 100644
--- a/drivers/staging/solo6x10/Makefile
+++ b/drivers/staging/media/solo6x10/Makefile
diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/media/solo6x10/TODO
index 7e6c4fa130df..7e6c4fa130df 100644
--- a/drivers/staging/solo6x10/TODO
+++ b/drivers/staging/media/solo6x10/TODO
diff --git a/drivers/staging/solo6x10/core.c b/drivers/staging/media/solo6x10/core.c
index f974f6412ad7..f974f6412ad7 100644
--- a/drivers/staging/solo6x10/core.c
+++ b/drivers/staging/media/solo6x10/core.c
diff --git a/drivers/staging/solo6x10/disp.c b/drivers/staging/media/solo6x10/disp.c
index 884c0eb757c4..884c0eb757c4 100644
--- a/drivers/staging/solo6x10/disp.c
+++ b/drivers/staging/media/solo6x10/disp.c
diff --git a/drivers/staging/solo6x10/enc.c b/drivers/staging/media/solo6x10/enc.c
index de502599bb19..de502599bb19 100644
--- a/drivers/staging/solo6x10/enc.c
+++ b/drivers/staging/media/solo6x10/enc.c
diff --git a/drivers/staging/solo6x10/g723.c b/drivers/staging/media/solo6x10/g723.c
index 59274bfca95b..59274bfca95b 100644
--- a/drivers/staging/solo6x10/g723.c
+++ b/drivers/staging/media/solo6x10/g723.c
diff --git a/drivers/staging/solo6x10/gpio.c b/drivers/staging/media/solo6x10/gpio.c
index 0925e6f33a99..0925e6f33a99 100644
--- a/drivers/staging/solo6x10/gpio.c
+++ b/drivers/staging/media/solo6x10/gpio.c
diff --git a/drivers/staging/solo6x10/i2c.c b/drivers/staging/media/solo6x10/i2c.c
index ef95a500b4da..ef95a500b4da 100644
--- a/drivers/staging/solo6x10/i2c.c
+++ b/drivers/staging/media/solo6x10/i2c.c
diff --git a/drivers/staging/solo6x10/jpeg.h b/drivers/staging/media/solo6x10/jpeg.h
index 50defec318cc..50defec318cc 100644
--- a/drivers/staging/solo6x10/jpeg.h
+++ b/drivers/staging/media/solo6x10/jpeg.h
diff --git a/drivers/staging/solo6x10/offsets.h b/drivers/staging/media/solo6x10/offsets.h
index 3d7e569f1cf8..3d7e569f1cf8 100644
--- a/drivers/staging/solo6x10/offsets.h
+++ b/drivers/staging/media/solo6x10/offsets.h
diff --git a/drivers/staging/solo6x10/osd-font.h b/drivers/staging/media/solo6x10/osd-font.h
index 591e0e82e0e8..591e0e82e0e8 100644
--- a/drivers/staging/solo6x10/osd-font.h
+++ b/drivers/staging/media/solo6x10/osd-font.h
diff --git a/drivers/staging/solo6x10/p2m.c b/drivers/staging/media/solo6x10/p2m.c
index 56210f0fc5ec..56210f0fc5ec 100644
--- a/drivers/staging/solo6x10/p2m.c
+++ b/drivers/staging/media/solo6x10/p2m.c
diff --git a/drivers/staging/solo6x10/registers.h b/drivers/staging/media/solo6x10/registers.h
index aca544472c93..aca544472c93 100644
--- a/drivers/staging/solo6x10/registers.h
+++ b/drivers/staging/media/solo6x10/registers.h
diff --git a/drivers/staging/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h
index abee7213202f..abee7213202f 100644
--- a/drivers/staging/solo6x10/solo6x10.h
+++ b/drivers/staging/media/solo6x10/solo6x10.h
diff --git a/drivers/staging/solo6x10/tw28.c b/drivers/staging/media/solo6x10/tw28.c
index db56b42c56c6..db56b42c56c6 100644
--- a/drivers/staging/solo6x10/tw28.c
+++ b/drivers/staging/media/solo6x10/tw28.c
diff --git a/drivers/staging/solo6x10/tw28.h b/drivers/staging/media/solo6x10/tw28.h
index a44a03afbd30..a44a03afbd30 100644
--- a/drivers/staging/solo6x10/tw28.h
+++ b/drivers/staging/media/solo6x10/tw28.h
diff --git a/drivers/staging/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index bee7280bbed9..bee7280bbed9 100644
--- a/drivers/staging/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
diff --git a/drivers/staging/solo6x10/v4l2.c b/drivers/staging/media/solo6x10/v4l2.c
index 571c3a348d30..571c3a348d30 100644
--- a/drivers/staging/solo6x10/v4l2.c
+++ b/drivers/staging/media/solo6x10/v4l2.c
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index b9926ee0052c..09de99fbb7e0 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -556,7 +556,7 @@ static inline int valid_io_request(struct zram *zram, struct bio *bio)
556/* 556/*
557 * Handler function for all zram I/O requests. 557 * Handler function for all zram I/O requests.
558 */ 558 */
559static int zram_make_request(struct request_queue *queue, struct bio *bio) 559static void zram_make_request(struct request_queue *queue, struct bio *bio)
560{ 560{
561 struct zram *zram = queue->queuedata; 561 struct zram *zram = queue->queuedata;
562 562
@@ -575,13 +575,12 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
575 __zram_make_request(zram, bio, bio_data_dir(bio)); 575 __zram_make_request(zram, bio, bio_data_dir(bio));
576 up_read(&zram->init_lock); 576 up_read(&zram->init_lock);
577 577
578 return 0; 578 return;
579 579
580error_unlock: 580error_unlock:
581 up_read(&zram->init_lock); 581 up_read(&zram->init_lock);
582error: 582error:
583 bio_io_error(bio); 583 bio_io_error(bio);
584 return 0;
585} 584}
586 585
587void __zram_reset_device(struct zram *zram) 586void __zram_reset_device(struct zram *zram)
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index e371753ba921..4222035acfb7 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -34,6 +34,15 @@ config HVC_ISERIES
34 help 34 help
35 iSeries machines support a hypervisor virtual console. 35 iSeries machines support a hypervisor virtual console.
36 36
37config HVC_OPAL
38 bool "OPAL Console support"
39 depends on PPC_POWERNV
40 select HVC_DRIVER
41 select HVC_IRQ
42 default y
43 help
44 PowerNV machines running under OPAL need that driver to get a console
45
37config HVC_RTAS 46config HVC_RTAS
38 bool "IBM RTAS Console support" 47 bool "IBM RTAS Console support"
39 depends on PPC_RTAS 48 depends on PPC_RTAS
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile
index e29205316376..89abf40bc73d 100644
--- a/drivers/tty/hvc/Makefile
+++ b/drivers/tty/hvc/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o 1obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o
2obj-$(CONFIG_HVC_OPAL) += hvc_opal.o hvsi_lib.o
2obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o 3obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o
3obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o 4obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
4obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 5obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
new file mode 100644
index 000000000000..7b38512d6c41
--- /dev/null
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -0,0 +1,424 @@
1/*
2 * opal driver interface to hvc_console.c
3 *
4 * Copyright 2011 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#undef DEBUG
23
24#include <linux/types.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/console.h>
29#include <linux/of.h>
30#include <linux/of_platform.h>
31
32#include <asm/hvconsole.h>
33#include <asm/prom.h>
34#include <asm/firmware.h>
35#include <asm/hvsi.h>
36#include <asm/udbg.h>
37#include <asm/opal.h>
38
39#include "hvc_console.h"
40
41static const char hvc_opal_name[] = "hvc_opal";
42
43static struct of_device_id hvc_opal_match[] __devinitdata = {
44 { .name = "serial", .compatible = "ibm,opal-console-raw" },
45 { .name = "serial", .compatible = "ibm,opal-console-hvsi" },
46 { },
47};
48
49typedef enum hv_protocol {
50 HV_PROTOCOL_RAW,
51 HV_PROTOCOL_HVSI
52} hv_protocol_t;
53
54struct hvc_opal_priv {
55 hv_protocol_t proto; /* Raw data or HVSI packets */
56 struct hvsi_priv hvsi; /* HVSI specific data */
57};
58static struct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES];
59
60/* For early boot console */
61static struct hvc_opal_priv hvc_opal_boot_priv;
62static u32 hvc_opal_boot_termno;
63
64static const struct hv_ops hvc_opal_raw_ops = {
65 .get_chars = opal_get_chars,
66 .put_chars = opal_put_chars,
67 .notifier_add = notifier_add_irq,
68 .notifier_del = notifier_del_irq,
69 .notifier_hangup = notifier_hangup_irq,
70};
71
72static int hvc_opal_hvsi_get_chars(uint32_t vtermno, char *buf, int count)
73{
74 struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
75
76 if (WARN_ON(!pv))
77 return -ENODEV;
78
79 return hvsilib_get_chars(&pv->hvsi, buf, count);
80}
81
82static int hvc_opal_hvsi_put_chars(uint32_t vtermno, const char *buf, int count)
83{
84 struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
85
86 if (WARN_ON(!pv))
87 return -ENODEV;
88
89 return hvsilib_put_chars(&pv->hvsi, buf, count);
90}
91
92static int hvc_opal_hvsi_open(struct hvc_struct *hp, int data)
93{
94 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
95 int rc;
96
97 pr_devel("HVSI@%x: do open !\n", hp->vtermno);
98
99 rc = notifier_add_irq(hp, data);
100 if (rc)
101 return rc;
102
103 return hvsilib_open(&pv->hvsi, hp);
104}
105
106static void hvc_opal_hvsi_close(struct hvc_struct *hp, int data)
107{
108 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
109
110 pr_devel("HVSI@%x: do close !\n", hp->vtermno);
111
112 hvsilib_close(&pv->hvsi, hp);
113
114 notifier_del_irq(hp, data);
115}
116
117void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data)
118{
119 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
120
121 pr_devel("HVSI@%x: do hangup !\n", hp->vtermno);
122
123 hvsilib_close(&pv->hvsi, hp);
124
125 notifier_hangup_irq(hp, data);
126}
127
128static int hvc_opal_hvsi_tiocmget(struct hvc_struct *hp)
129{
130 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
131
132 if (!pv)
133 return -EINVAL;
134 return pv->hvsi.mctrl;
135}
136
137static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
138 unsigned int clear)
139{
140 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
141
142 pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n",
143 hp->vtermno, set, clear);
144
145 if (set & TIOCM_DTR)
146 hvsilib_write_mctrl(&pv->hvsi, 1);
147 else if (clear & TIOCM_DTR)
148 hvsilib_write_mctrl(&pv->hvsi, 0);
149
150 return 0;
151}
152
153static const struct hv_ops hvc_opal_hvsi_ops = {
154 .get_chars = hvc_opal_hvsi_get_chars,
155 .put_chars = hvc_opal_hvsi_put_chars,
156 .notifier_add = hvc_opal_hvsi_open,
157 .notifier_del = hvc_opal_hvsi_close,
158 .notifier_hangup = hvc_opal_hvsi_hangup,
159 .tiocmget = hvc_opal_hvsi_tiocmget,
160 .tiocmset = hvc_opal_hvsi_tiocmset,
161};
162
163static int __devinit hvc_opal_probe(struct platform_device *dev)
164{
165 const struct hv_ops *ops;
166 struct hvc_struct *hp;
167 struct hvc_opal_priv *pv;
168 hv_protocol_t proto;
169 unsigned int termno, boot = 0;
170 const __be32 *reg;
171
172 if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
173 proto = HV_PROTOCOL_RAW;
174 ops = &hvc_opal_raw_ops;
175 } else if (of_device_is_compatible(dev->dev.of_node,
176 "ibm,opal-console-hvsi")) {
177 proto = HV_PROTOCOL_HVSI;
178 ops = &hvc_opal_hvsi_ops;
179 } else {
180 pr_err("hvc_opal: Unkown protocol for %s\n",
181 dev->dev.of_node->full_name);
182 return -ENXIO;
183 }
184
185 reg = of_get_property(dev->dev.of_node, "reg", NULL);
186 termno = reg ? be32_to_cpup(reg) : 0;
187
188 /* Is it our boot one ? */
189 if (hvc_opal_privs[termno] == &hvc_opal_boot_priv) {
190 pv = hvc_opal_privs[termno];
191 boot = 1;
192 } else if (hvc_opal_privs[termno] == NULL) {
193 pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL);
194 if (!pv)
195 return -ENOMEM;
196 pv->proto = proto;
197 hvc_opal_privs[termno] = pv;
198 if (proto == HV_PROTOCOL_HVSI)
199 hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars,
200 termno, 0);
201
202 /* Instanciate now to establish a mapping index==vtermno */
203 hvc_instantiate(termno, termno, ops);
204 } else {
205 pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n",
206 dev->dev.of_node->full_name, termno);
207 return -ENXIO;
208 }
209
210 pr_info("hvc%d: %s protocol on %s%s\n", termno,
211 proto == HV_PROTOCOL_RAW ? "raw" : "hvsi",
212 dev->dev.of_node->full_name,
213 boot ? " (boot console)" : "");
214
215 /* We don't do IRQ yet */
216 hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS);
217 if (IS_ERR(hp))
218 return PTR_ERR(hp);
219 dev_set_drvdata(&dev->dev, hp);
220
221 return 0;
222}
223
224static int __devexit hvc_opal_remove(struct platform_device *dev)
225{
226 struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
227 int rc, termno;
228
229 termno = hp->vtermno;
230 rc = hvc_remove(hp);
231 if (rc == 0) {
232 if (hvc_opal_privs[termno] != &hvc_opal_boot_priv)
233 kfree(hvc_opal_privs[termno]);
234 hvc_opal_privs[termno] = NULL;
235 }
236 return rc;
237}
238
239static struct platform_driver hvc_opal_driver = {
240 .probe = hvc_opal_probe,
241 .remove = __devexit_p(hvc_opal_remove),
242 .driver = {
243 .name = hvc_opal_name,
244 .owner = THIS_MODULE,
245 .of_match_table = hvc_opal_match,
246 }
247};
248
249static int __init hvc_opal_init(void)
250{
251 if (!firmware_has_feature(FW_FEATURE_OPAL))
252 return -ENODEV;
253
254 /* Register as a vio device to receive callbacks */
255 return platform_driver_register(&hvc_opal_driver);
256}
257module_init(hvc_opal_init);
258
259static void __exit hvc_opal_exit(void)
260{
261 platform_driver_unregister(&hvc_opal_driver);
262}
263module_exit(hvc_opal_exit);
264
265static void udbg_opal_putc(char c)
266{
267 unsigned int termno = hvc_opal_boot_termno;
268 int count = -1;
269
270 if (c == '\n')
271 udbg_opal_putc('\r');
272
273 do {
274 switch(hvc_opal_boot_priv.proto) {
275 case HV_PROTOCOL_RAW:
276 count = opal_put_chars(termno, &c, 1);
277 break;
278 case HV_PROTOCOL_HVSI:
279 count = hvc_opal_hvsi_put_chars(termno, &c, 1);
280 break;
281 }
282 } while(count == 0 || count == -EAGAIN);
283}
284
285static int udbg_opal_getc_poll(void)
286{
287 unsigned int termno = hvc_opal_boot_termno;
288 int rc = 0;
289 char c;
290
291 switch(hvc_opal_boot_priv.proto) {
292 case HV_PROTOCOL_RAW:
293 rc = opal_get_chars(termno, &c, 1);
294 break;
295 case HV_PROTOCOL_HVSI:
296 rc = hvc_opal_hvsi_get_chars(termno, &c, 1);
297 break;
298 }
299 if (!rc)
300 return -1;
301 return c;
302}
303
304static int udbg_opal_getc(void)
305{
306 int ch;
307 for (;;) {
308 ch = udbg_opal_getc_poll();
309 if (ch == -1) {
310 /* This shouldn't be needed...but... */
311 volatile unsigned long delay;
312 for (delay=0; delay < 2000000; delay++)
313 ;
314 } else {
315 return ch;
316 }
317 }
318}
319
320static void udbg_init_opal_common(void)
321{
322 udbg_putc = udbg_opal_putc;
323 udbg_getc = udbg_opal_getc;
324 udbg_getc_poll = udbg_opal_getc_poll;
325 tb_ticks_per_usec = 0x200; /* Make udelay not suck */
326}
327
328void __init hvc_opal_init_early(void)
329{
330 struct device_node *stdout_node = NULL;
331 const u32 *termno;
332 const char *name = NULL;
333 const struct hv_ops *ops;
334 u32 index;
335
336 /* find the boot console from /chosen/stdout */
337 if (of_chosen)
338 name = of_get_property(of_chosen, "linux,stdout-path", NULL);
339 if (name) {
340 stdout_node = of_find_node_by_path(name);
341 if (!stdout_node) {
342 pr_err("hvc_opal: Failed to locate default console!\n");
343 return;
344 }
345 } else {
346 struct device_node *opal, *np;
347
348 /* Current OPAL takeover doesn't provide the stdout
349 * path, so we hard wire it
350 */
351 opal = of_find_node_by_path("/ibm,opal/consoles");
352 if (opal)
353 pr_devel("hvc_opal: Found consoles in new location\n");
354 if (!opal) {
355 opal = of_find_node_by_path("/ibm,opal");
356 if (opal)
357 pr_devel("hvc_opal: "
358 "Found consoles in old location\n");
359 }
360 if (!opal)
361 return;
362 for_each_child_of_node(opal, np) {
363 if (!strcmp(np->name, "serial")) {
364 stdout_node = np;
365 break;
366 }
367 }
368 of_node_put(opal);
369 }
370 if (!stdout_node)
371 return;
372 termno = of_get_property(stdout_node, "reg", NULL);
373 index = termno ? *termno : 0;
374 if (index >= MAX_NR_HVC_CONSOLES)
375 return;
376 hvc_opal_privs[index] = &hvc_opal_boot_priv;
377
378 /* Check the protocol */
379 if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) {
380 hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
381 ops = &hvc_opal_raw_ops;
382 pr_devel("hvc_opal: Found RAW console\n");
383 }
384 else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
385 hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
386 ops = &hvc_opal_hvsi_ops;
387 hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars,
388 opal_put_chars, index, 1);
389 /* HVSI, perform the handshake now */
390 hvsilib_establish(&hvc_opal_boot_priv.hvsi);
391 pr_devel("hvc_opal: Found HVSI console\n");
392 } else
393 goto out;
394 hvc_opal_boot_termno = index;
395 udbg_init_opal_common();
396 add_preferred_console("hvc", index, NULL);
397 hvc_instantiate(index, index, ops);
398out:
399 of_node_put(stdout_node);
400}
401
402#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW
403void __init udbg_init_debug_opal(void)
404{
405 u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
406 hvc_opal_privs[index] = &hvc_opal_boot_priv;
407 hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
408 hvc_opal_boot_termno = index;
409 udbg_init_opal_common();
410}
411#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_RAW */
412
413#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI
414void __init udbg_init_debug_opal_hvsi(void)
415{
416 u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
417 hvc_opal_privs[index] = &hvc_opal_boot_priv;
418 hvc_opal_boot_termno = index;
419 udbg_init_opal_common();
420 hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars,
421 index, 1);
422 hvsilib_establish(&hvc_opal_boot_priv.hvsi);
423}
424#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI */
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 55882b5930a6..b9040bec36bd 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1532,7 +1532,7 @@ static int __devinit hvcs_initialize(void)
1532 goto register_fail; 1532 goto register_fail;
1533 } 1533 }
1534 1534
1535 hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); 1535 hvcs_pi_buff = (unsigned long *) __get_free_page(GFP_KERNEL);
1536 if (!hvcs_pi_buff) { 1536 if (!hvcs_pi_buff) {
1537 rc = -ENOMEM; 1537 rc = -ENOMEM;
1538 goto buff_alloc_fail; 1538 goto buff_alloc_fail;
@@ -1548,7 +1548,7 @@ static int __devinit hvcs_initialize(void)
1548 return 0; 1548 return 0;
1549 1549
1550kthread_fail: 1550kthread_fail:
1551 kfree(hvcs_pi_buff); 1551 free_page((unsigned long)hvcs_pi_buff);
1552buff_alloc_fail: 1552buff_alloc_fail:
1553 tty_unregister_driver(hvcs_tty_driver); 1553 tty_unregister_driver(hvcs_tty_driver);
1554register_fail: 1554register_fail:
@@ -1597,7 +1597,7 @@ static void __exit hvcs_module_exit(void)
1597 kthread_stop(hvcs_task); 1597 kthread_stop(hvcs_task);
1598 1598
1599 spin_lock(&hvcs_pi_lock); 1599 spin_lock(&hvcs_pi_lock);
1600 kfree(hvcs_pi_buff); 1600 free_page((unsigned long)hvcs_pi_buff);
1601 hvcs_pi_buff = NULL; 1601 hvcs_pi_buff = NULL;
1602 spin_unlock(&hvcs_pi_lock); 1602 spin_unlock(&hvcs_pi_lock);
1603 1603
diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c
index bd9b09827b24..6f4dd83d8695 100644
--- a/drivers/tty/hvc/hvsi_lib.c
+++ b/drivers/tty/hvc/hvsi_lib.c
@@ -183,7 +183,7 @@ int hvsilib_get_chars(struct hvsi_priv *pv, char *buf, int count)
183 unsigned int tries, read = 0; 183 unsigned int tries, read = 0;
184 184
185 if (WARN_ON(!pv)) 185 if (WARN_ON(!pv))
186 return 0; 186 return -ENXIO;
187 187
188 /* If we aren't open, don't do anything in order to avoid races 188 /* If we aren't open, don't do anything in order to avoid races
189 * with connection establishment. The hvc core will call this 189 * with connection establishment. The hvc core will call this
@@ -234,7 +234,7 @@ int hvsilib_put_chars(struct hvsi_priv *pv, const char *buf, int count)
234 int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA); 234 int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA);
235 235
236 if (WARN_ON(!pv)) 236 if (WARN_ON(!pv))
237 return 0; 237 return -ENODEV;
238 238
239 dp.hdr.type = VS_DATA_PACKET_HEADER; 239 dp.hdr.type = VS_DATA_PACKET_HEADER;
240 dp.hdr.len = adjcount + sizeof(struct hvsi_header); 240 dp.hdr.len = adjcount + sizeof(struct hvsi_header);
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index a87a56cb5417..eeadf1b8e093 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -450,24 +450,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value)
450 __raw_writel(value, p->membase + offset); 450 __raw_writel(value, p->membase + offset);
451} 451}
452 452
453static unsigned int tsi_serial_in(struct uart_port *p, int offset)
454{
455 unsigned int tmp;
456 offset = map_8250_in_reg(p, offset) << p->regshift;
457 if (offset == UART_IIR) {
458 tmp = readl(p->membase + (UART_IIR & ~3));
459 return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
460 } else
461 return readb(p->membase + offset);
462}
463
464static void tsi_serial_out(struct uart_port *p, int offset, int value)
465{
466 offset = map_8250_out_reg(p, offset) << p->regshift;
467 if (!((offset == UART_IER) && (value & UART_IER_UUE)))
468 writeb(value, p->membase + offset);
469}
470
471static unsigned int io_serial_in(struct uart_port *p, int offset) 453static unsigned int io_serial_in(struct uart_port *p, int offset)
472{ 454{
473 offset = map_8250_in_reg(p, offset) << p->regshift; 455 offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -508,11 +490,6 @@ static void set_io_from_upio(struct uart_port *p)
508 p->serial_out = au_serial_out; 490 p->serial_out = au_serial_out;
509 break; 491 break;
510 492
511 case UPIO_TSI:
512 p->serial_in = tsi_serial_in;
513 p->serial_out = tsi_serial_out;
514 break;
515
516 default: 493 default:
517 p->serial_in = io_serial_in; 494 p->serial_in = io_serial_in;
518 p->serial_out = io_serial_out; 495 p->serial_out = io_serial_out;
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9871c57b348e..1945c70539c2 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1446,12 +1446,8 @@ static bool filter(struct dma_chan *chan, void *slave)
1446 dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, 1446 dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
1447 param->slave_id); 1447 param->slave_id);
1448 1448
1449 if (param->dma_dev == chan->device->dev) { 1449 chan->private = param;
1450 chan->private = param; 1450 return true;
1451 return true;
1452 } else {
1453 return false;
1454 }
1455} 1451}
1456 1452
1457static void rx_timer_fn(unsigned long arg) 1453static void rx_timer_fn(unsigned long arg)
@@ -1477,10 +1473,10 @@ static void sci_request_dma(struct uart_port *port)
1477 dma_cap_mask_t mask; 1473 dma_cap_mask_t mask;
1478 int nent; 1474 int nent;
1479 1475
1480 dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, 1476 dev_dbg(port->dev, "%s: port %d\n", __func__,
1481 port->line, s->cfg->dma_dev); 1477 port->line);
1482 1478
1483 if (!s->cfg->dma_dev) 1479 if (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0)
1484 return; 1480 return;
1485 1481
1486 dma_cap_zero(mask); 1482 dma_cap_zero(mask);
@@ -1490,7 +1486,6 @@ static void sci_request_dma(struct uart_port *port)
1490 1486
1491 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ 1487 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
1492 param->slave_id = s->cfg->dma_slave_tx; 1488 param->slave_id = s->cfg->dma_slave_tx;
1493 param->dma_dev = s->cfg->dma_dev;
1494 1489
1495 s->cookie_tx = -EINVAL; 1490 s->cookie_tx = -EINVAL;
1496 chan = dma_request_channel(mask, filter, param); 1491 chan = dma_request_channel(mask, filter, param);
@@ -1519,7 +1514,6 @@ static void sci_request_dma(struct uart_port *port)
1519 1514
1520 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ 1515 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
1521 param->slave_id = s->cfg->dma_slave_rx; 1516 param->slave_id = s->cfg->dma_slave_rx;
1522 param->dma_dev = s->cfg->dma_dev;
1523 1517
1524 chan = dma_request_channel(mask, filter, param); 1518 chan = dma_request_channel(mask, filter, param);
1525 dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); 1519 dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
@@ -1564,9 +1558,6 @@ static void sci_free_dma(struct uart_port *port)
1564{ 1558{
1565 struct sci_port *s = to_sci_port(port); 1559 struct sci_port *s = to_sci_port(port);
1566 1560
1567 if (!s->cfg->dma_dev)
1568 return;
1569
1570 if (s->chan_tx) 1561 if (s->chan_tx)
1571 sci_tx_dma_release(s, false); 1562 sci_tx_dma_release(s, false);
1572 if (s->chan_rx) 1563 if (s->chan_rx)
@@ -1981,9 +1972,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
1981 port->serial_in = sci_serial_in; 1972 port->serial_in = sci_serial_in;
1982 port->serial_out = sci_serial_out; 1973 port->serial_out = sci_serial_out;
1983 1974
1984 if (p->dma_dev) 1975 if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0)
1985 dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", 1976 dev_dbg(port->dev, "DMA tx %d, rx %d\n",
1986 p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); 1977 p->dma_slave_tx, p->dma_slave_rx);
1987 1978
1988 return 0; 1979 return 0;
1989} 1980}
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 3b029a0a4787..c2c0ae57e7ff 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1667,6 +1667,11 @@ int usb_runtime_suspend(struct device *dev)
1667 return -EAGAIN; 1667 return -EAGAIN;
1668 1668
1669 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); 1669 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1670
1671 /* Allow a retry if autosuspend failed temporarily */
1672 if (status == -EAGAIN || status == -EBUSY)
1673 usb_mark_last_busy(udev);
1674
1670 /* The PM core reacts badly unless the return code is 0, 1675 /* The PM core reacts badly unless the return code is 0,
1671 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error. 1676 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
1672 */ 1677 */
diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c
index 3d9162151fd2..4939e0ccc4e5 100644
--- a/drivers/virt/fsl_hypervisor.c
+++ b/drivers/virt/fsl_hypervisor.c
@@ -706,6 +706,7 @@ static const struct file_operations fsl_hv_fops = {
706 .poll = fsl_hv_poll, 706 .poll = fsl_hv_poll,
707 .read = fsl_hv_read, 707 .read = fsl_hv_read,
708 .unlocked_ioctl = fsl_hv_ioctl, 708 .unlocked_ioctl = fsl_hv_ioctl,
709 .compat_ioctl = fsl_hv_ioctl,
709}; 710};
710 711
711static struct miscdevice fsl_hv_misc_dev = { 712static struct miscdevice fsl_hv_misc_dev = {
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 64c6752ea2c6..6285867a9356 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -66,6 +66,7 @@ config SOFT_WATCHDOG
66config WM831X_WATCHDOG 66config WM831X_WATCHDOG
67 tristate "WM831x watchdog" 67 tristate "WM831x watchdog"
68 depends on MFD_WM831X 68 depends on MFD_WM831X
69 select WATCHDOG_CORE
69 help 70 help
70 Support for the watchdog in the WM831x AudioPlus PMICs. When 71 Support for the watchdog in the WM831x AudioPlus PMICs. When
71 the watchdog triggers the system will be reset. 72 the watchdog triggers the system will be reset.
@@ -170,6 +171,7 @@ config HAVE_S3C2410_WATCHDOG
170config S3C2410_WATCHDOG 171config S3C2410_WATCHDOG
171 tristate "S3C2410 Watchdog" 172 tristate "S3C2410 Watchdog"
172 depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG 173 depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG
174 select WATCHDOG_CORE
173 help 175 help
174 Watchdog timer block in the Samsung SoCs. This will reboot 176 Watchdog timer block in the Samsung SoCs. This will reboot
175 the system when the timer expires with the watchdog enabled. 177 the system when the timer expires with the watchdog enabled.
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 9291506b8b23..03f449a430d2 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -429,7 +429,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
429 writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); 429 writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR);
430 430
431 irq = platform_get_irq(pdev, 0); 431 irq = platform_get_irq(pdev, 0);
432 if (request_irq(irq, coh901327_interrupt, IRQF_DISABLED, 432 if (request_irq(irq, coh901327_interrupt, 0,
433 DRV_NAME " Bark", pdev)) { 433 DRV_NAME " Bark", pdev)) {
434 ret = -EIO; 434 ret = -EIO;
435 goto out_no_irq; 435 goto out_no_irq;
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index f1d1da662fbe..41018d429abb 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -427,7 +427,7 @@ static int __init eurwdt_init(void)
427{ 427{
428 int ret; 428 int ret;
429 429
430 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); 430 ret = request_irq(irq, eurwdt_interrupt, 0, "eurwdt", NULL);
431 if (ret) { 431 if (ret) {
432 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); 432 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
433 goto out; 433 goto out;
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 751a591684da..ba6ad662635a 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * intel TCO Watchdog Driver 2 * intel TCO Watchdog Driver
3 * 3 *
4 * (c) Copyright 2006-2010 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2006-2011 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -44,7 +44,7 @@
44 44
45/* Module and version information */ 45/* Module and version information */
46#define DRV_NAME "iTCO_wdt" 46#define DRV_NAME "iTCO_wdt"
47#define DRV_VERSION "1.06" 47#define DRV_VERSION "1.07"
48#define PFX DRV_NAME ": " 48#define PFX DRV_NAME ": "
49 49
50/* Includes */ 50/* Includes */
@@ -384,6 +384,11 @@ MODULE_PARM_DESC(nowayout,
384 "Watchdog cannot be stopped once started (default=" 384 "Watchdog cannot be stopped once started (default="
385 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 385 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
386 386
387static int turn_SMI_watchdog_clear_off = 0;
388module_param(turn_SMI_watchdog_clear_off, int, 0);
389MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
390 "Turn off SMI clearing watchdog (default=0)");
391
387/* 392/*
388 * Some TCO specific functions 393 * Some TCO specific functions
389 */ 394 */
@@ -808,10 +813,12 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
808 ret = -EIO; 813 ret = -EIO;
809 goto out_unmap; 814 goto out_unmap;
810 } 815 }
811 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ 816 if (turn_SMI_watchdog_clear_off) {
812 val32 = inl(SMI_EN); 817 /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
813 val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ 818 val32 = inl(SMI_EN);
814 outl(val32, SMI_EN); 819 val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
820 outl(val32, SMI_EN);
821 }
815 822
816 /* The TCO I/O registers reside in a 32-byte range pointed to 823 /* The TCO I/O registers reside in a 32-byte range pointed to
817 by the TCOBASE value */ 824 by the TCOBASE value */
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 4dc31024d26c..82ccd36e2c90 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -367,8 +367,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
367 goto err_misc; 367 goto err_misc;
368 } 368 }
369 369
370 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, 370 ret = request_irq(wdt->irq, mpcore_wdt_fire, 0, "mpcore_wdt", wdt);
371 "mpcore_wdt", wdt);
372 if (ret) { 371 if (ret) {
373 dev_printk(KERN_ERR, wdt->dev, 372 dev_printk(KERN_ERR, wdt->dev,
374 "cannot register IRQ%d for watchdog\n", wdt->irq); 373 "cannot register IRQ%d for watchdog\n", wdt->irq);
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
index 945ee8300306..7c0d8630e641 100644
--- a/drivers/watchdog/octeon-wdt-main.c
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -402,7 +402,7 @@ static void octeon_wdt_setup_interrupt(int cpu)
402 irq = OCTEON_IRQ_WDOG0 + core; 402 irq = OCTEON_IRQ_WDOG0 + core;
403 403
404 if (request_irq(irq, octeon_wdt_poke_irq, 404 if (request_irq(irq, octeon_wdt_poke_irq,
405 IRQF_DISABLED, "octeon_wdt", octeon_wdt_poke_irq)) 405 IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq))
406 panic("octeon_wdt: Couldn't obtain irq %d", irq); 406 panic("octeon_wdt: Couldn't obtain irq %d", irq);
407 407
408 cpumask_set_cpu(cpu, &irq_enabled_cpus); 408 cpumask_set_cpu(cpu, &irq_enabled_cpus);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 30da88f47cd3..5de7e4fa5b8a 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -27,9 +27,8 @@
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/timer.h> 29#include <linux/timer.h>
30#include <linux/miscdevice.h> 30#include <linux/miscdevice.h> /* for MODULE_ALIAS_MISCDEV */
31#include <linux/watchdog.h> 31#include <linux/watchdog.h>
32#include <linux/fs.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/platform_device.h> 33#include <linux/platform_device.h>
35#include <linux/interrupt.h> 34#include <linux/interrupt.h>
@@ -38,6 +37,7 @@
38#include <linux/io.h> 37#include <linux/io.h>
39#include <linux/cpufreq.h> 38#include <linux/cpufreq.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/err.h>
41 41
42#include <mach/map.h> 42#include <mach/map.h>
43 43
@@ -74,14 +74,12 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
74 "0 to reboot (default 0)"); 74 "0 to reboot (default 0)");
75MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); 75MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)");
76 76
77static unsigned long open_lock;
78static struct device *wdt_dev; /* platform device attached to */ 77static struct device *wdt_dev; /* platform device attached to */
79static struct resource *wdt_mem; 78static struct resource *wdt_mem;
80static struct resource *wdt_irq; 79static struct resource *wdt_irq;
81static struct clk *wdt_clock; 80static struct clk *wdt_clock;
82static void __iomem *wdt_base; 81static void __iomem *wdt_base;
83static unsigned int wdt_count; 82static unsigned int wdt_count;
84static char expect_close;
85static DEFINE_SPINLOCK(wdt_lock); 83static DEFINE_SPINLOCK(wdt_lock);
86 84
87/* watchdog control routines */ 85/* watchdog control routines */
@@ -93,11 +91,13 @@ static DEFINE_SPINLOCK(wdt_lock);
93 91
94/* functions */ 92/* functions */
95 93
96static void s3c2410wdt_keepalive(void) 94static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
97{ 95{
98 spin_lock(&wdt_lock); 96 spin_lock(&wdt_lock);
99 writel(wdt_count, wdt_base + S3C2410_WTCNT); 97 writel(wdt_count, wdt_base + S3C2410_WTCNT);
100 spin_unlock(&wdt_lock); 98 spin_unlock(&wdt_lock);
99
100 return 0;
101} 101}
102 102
103static void __s3c2410wdt_stop(void) 103static void __s3c2410wdt_stop(void)
@@ -109,14 +109,16 @@ static void __s3c2410wdt_stop(void)
109 writel(wtcon, wdt_base + S3C2410_WTCON); 109 writel(wtcon, wdt_base + S3C2410_WTCON);
110} 110}
111 111
112static void s3c2410wdt_stop(void) 112static int s3c2410wdt_stop(struct watchdog_device *wdd)
113{ 113{
114 spin_lock(&wdt_lock); 114 spin_lock(&wdt_lock);
115 __s3c2410wdt_stop(); 115 __s3c2410wdt_stop();
116 spin_unlock(&wdt_lock); 116 spin_unlock(&wdt_lock);
117
118 return 0;
117} 119}
118 120
119static void s3c2410wdt_start(void) 121static int s3c2410wdt_start(struct watchdog_device *wdd)
120{ 122{
121 unsigned long wtcon; 123 unsigned long wtcon;
122 124
@@ -142,6 +144,8 @@ static void s3c2410wdt_start(void)
142 writel(wdt_count, wdt_base + S3C2410_WTCNT); 144 writel(wdt_count, wdt_base + S3C2410_WTCNT);
143 writel(wtcon, wdt_base + S3C2410_WTCON); 145 writel(wtcon, wdt_base + S3C2410_WTCON);
144 spin_unlock(&wdt_lock); 146 spin_unlock(&wdt_lock);
147
148 return 0;
145} 149}
146 150
147static inline int s3c2410wdt_is_running(void) 151static inline int s3c2410wdt_is_running(void)
@@ -149,7 +153,7 @@ static inline int s3c2410wdt_is_running(void)
149 return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE; 153 return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE;
150} 154}
151 155
152static int s3c2410wdt_set_heartbeat(int timeout) 156static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeout)
153{ 157{
154 unsigned long freq = clk_get_rate(wdt_clock); 158 unsigned long freq = clk_get_rate(wdt_clock);
155 unsigned int count; 159 unsigned int count;
@@ -182,8 +186,6 @@ static int s3c2410wdt_set_heartbeat(int timeout)
182 } 186 }
183 } 187 }
184 188
185 tmr_margin = timeout;
186
187 DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", 189 DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n",
188 __func__, timeout, divisor, count, count/divisor); 190 __func__, timeout, divisor, count, count/divisor);
189 191
@@ -201,70 +203,6 @@ static int s3c2410wdt_set_heartbeat(int timeout)
201 return 0; 203 return 0;
202} 204}
203 205
204/*
205 * /dev/watchdog handling
206 */
207
208static int s3c2410wdt_open(struct inode *inode, struct file *file)
209{
210 if (test_and_set_bit(0, &open_lock))
211 return -EBUSY;
212
213 if (nowayout)
214 __module_get(THIS_MODULE);
215
216 expect_close = 0;
217
218 /* start the timer */
219 s3c2410wdt_start();
220 return nonseekable_open(inode, file);
221}
222
223static int s3c2410wdt_release(struct inode *inode, struct file *file)
224{
225 /*
226 * Shut off the timer.
227 * Lock it in if it's a module and we set nowayout
228 */
229
230 if (expect_close == 42)
231 s3c2410wdt_stop();
232 else {
233 dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
234 s3c2410wdt_keepalive();
235 }
236 expect_close = 0;
237 clear_bit(0, &open_lock);
238 return 0;
239}
240
241static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
242 size_t len, loff_t *ppos)
243{
244 /*
245 * Refresh the timer.
246 */
247 if (len) {
248 if (!nowayout) {
249 size_t i;
250
251 /* In case it was set long ago */
252 expect_close = 0;
253
254 for (i = 0; i != len; i++) {
255 char c;
256
257 if (get_user(c, data + i))
258 return -EFAULT;
259 if (c == 'V')
260 expect_close = 42;
261 }
262 }
263 s3c2410wdt_keepalive();
264 }
265 return len;
266}
267
268#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) 206#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
269 207
270static const struct watchdog_info s3c2410_wdt_ident = { 208static const struct watchdog_info s3c2410_wdt_ident = {
@@ -273,53 +211,17 @@ static const struct watchdog_info s3c2410_wdt_ident = {
273 .identity = "S3C2410 Watchdog", 211 .identity = "S3C2410 Watchdog",
274}; 212};
275 213
276 214static struct watchdog_ops s3c2410wdt_ops = {
277static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd, 215 .owner = THIS_MODULE,
278 unsigned long arg) 216 .start = s3c2410wdt_start,
279{ 217 .stop = s3c2410wdt_stop,
280 void __user *argp = (void __user *)arg; 218 .ping = s3c2410wdt_keepalive,
281 int __user *p = argp; 219 .set_timeout = s3c2410wdt_set_heartbeat,
282 int new_margin;
283
284 switch (cmd) {
285 case WDIOC_GETSUPPORT:
286 return copy_to_user(argp, &s3c2410_wdt_ident,
287 sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;
288 case WDIOC_GETSTATUS:
289 case WDIOC_GETBOOTSTATUS:
290 return put_user(0, p);
291 case WDIOC_KEEPALIVE:
292 s3c2410wdt_keepalive();
293 return 0;
294 case WDIOC_SETTIMEOUT:
295 if (get_user(new_margin, p))
296 return -EFAULT;
297 if (s3c2410wdt_set_heartbeat(new_margin))
298 return -EINVAL;
299 s3c2410wdt_keepalive();
300 return put_user(tmr_margin, p);
301 case WDIOC_GETTIMEOUT:
302 return put_user(tmr_margin, p);
303 default:
304 return -ENOTTY;
305 }
306}
307
308/* kernel interface */
309
310static const struct file_operations s3c2410wdt_fops = {
311 .owner = THIS_MODULE,
312 .llseek = no_llseek,
313 .write = s3c2410wdt_write,
314 .unlocked_ioctl = s3c2410wdt_ioctl,
315 .open = s3c2410wdt_open,
316 .release = s3c2410wdt_release,
317}; 220};
318 221
319static struct miscdevice s3c2410wdt_miscdev = { 222static struct watchdog_device s3c2410_wdd = {
320 .minor = WATCHDOG_MINOR, 223 .info = &s3c2410_wdt_ident,
321 .name = "watchdog", 224 .ops = &s3c2410wdt_ops,
322 .fops = &s3c2410wdt_fops,
323}; 225};
324 226
325/* interrupt handler code */ 227/* interrupt handler code */
@@ -328,7 +230,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
328{ 230{
329 dev_info(wdt_dev, "watchdog timer expired (irq)\n"); 231 dev_info(wdt_dev, "watchdog timer expired (irq)\n");
330 232
331 s3c2410wdt_keepalive(); 233 s3c2410wdt_keepalive(&s3c2410_wdd);
332 return IRQ_HANDLED; 234 return IRQ_HANDLED;
333} 235}
334 236
@@ -349,14 +251,14 @@ static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
349 * the watchdog is running. 251 * the watchdog is running.
350 */ 252 */
351 253
352 s3c2410wdt_keepalive(); 254 s3c2410wdt_keepalive(&s3c2410_wdd);
353 } else if (val == CPUFREQ_POSTCHANGE) { 255 } else if (val == CPUFREQ_POSTCHANGE) {
354 s3c2410wdt_stop(); 256 s3c2410wdt_stop(&s3c2410_wdd);
355 257
356 ret = s3c2410wdt_set_heartbeat(tmr_margin); 258 ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout);
357 259
358 if (ret >= 0) 260 if (ret >= 0)
359 s3c2410wdt_start(); 261 s3c2410wdt_start(&s3c2410_wdd);
360 else 262 else
361 goto err; 263 goto err;
362 } 264 }
@@ -365,7 +267,8 @@ done:
365 return 0; 267 return 0;
366 268
367 err: 269 err:
368 dev_err(wdt_dev, "cannot set new value for timeout %d\n", tmr_margin); 270 dev_err(wdt_dev, "cannot set new value for timeout %d\n",
271 s3c2410_wdd.timeout);
369 return ret; 272 return ret;
370} 273}
371 274
@@ -396,10 +299,6 @@ static inline void s3c2410wdt_cpufreq_deregister(void)
396} 299}
397#endif 300#endif
398 301
399
400
401/* device interface */
402
403static int __devinit s3c2410wdt_probe(struct platform_device *pdev) 302static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
404{ 303{
405 struct device *dev; 304 struct device *dev;
@@ -466,8 +365,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
466 /* see if we can actually set the requested timer margin, and if 365 /* see if we can actually set the requested timer margin, and if
467 * not, try the default value */ 366 * not, try the default value */
468 367
469 if (s3c2410wdt_set_heartbeat(tmr_margin)) { 368 if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, tmr_margin)) {
470 started = s3c2410wdt_set_heartbeat( 369 started = s3c2410wdt_set_heartbeat(&s3c2410_wdd,
471 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); 370 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
472 371
473 if (started == 0) 372 if (started == 0)
@@ -479,22 +378,21 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
479 "cannot start\n"); 378 "cannot start\n");
480 } 379 }
481 380
482 ret = misc_register(&s3c2410wdt_miscdev); 381 ret = watchdog_register_device(&s3c2410_wdd);
483 if (ret) { 382 if (ret) {
484 dev_err(dev, "cannot register miscdev on minor=%d (%d)\n", 383 dev_err(dev, "cannot register watchdog (%d)\n", ret);
485 WATCHDOG_MINOR, ret);
486 goto err_cpufreq; 384 goto err_cpufreq;
487 } 385 }
488 386
489 if (tmr_atboot && started == 0) { 387 if (tmr_atboot && started == 0) {
490 dev_info(dev, "starting watchdog timer\n"); 388 dev_info(dev, "starting watchdog timer\n");
491 s3c2410wdt_start(); 389 s3c2410wdt_start(&s3c2410_wdd);
492 } else if (!tmr_atboot) { 390 } else if (!tmr_atboot) {
493 /* if we're not enabling the watchdog, then ensure it is 391 /* if we're not enabling the watchdog, then ensure it is
494 * disabled if it has been left running from the bootloader 392 * disabled if it has been left running from the bootloader
495 * or other source */ 393 * or other source */
496 394
497 s3c2410wdt_stop(); 395 s3c2410wdt_stop(&s3c2410_wdd);
498 } 396 }
499 397
500 /* print out a statement of readiness */ 398 /* print out a statement of readiness */
@@ -530,7 +428,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
530 428
531static int __devexit s3c2410wdt_remove(struct platform_device *dev) 429static int __devexit s3c2410wdt_remove(struct platform_device *dev)
532{ 430{
533 misc_deregister(&s3c2410wdt_miscdev); 431 watchdog_unregister_device(&s3c2410_wdd);
534 432
535 s3c2410wdt_cpufreq_deregister(); 433 s3c2410wdt_cpufreq_deregister();
536 434
@@ -550,7 +448,7 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
550 448
551static void s3c2410wdt_shutdown(struct platform_device *dev) 449static void s3c2410wdt_shutdown(struct platform_device *dev)
552{ 450{
553 s3c2410wdt_stop(); 451 s3c2410wdt_stop(&s3c2410_wdd);
554} 452}
555 453
556#ifdef CONFIG_PM 454#ifdef CONFIG_PM
@@ -565,7 +463,7 @@ static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state)
565 wtdat_save = readl(wdt_base + S3C2410_WTDAT); 463 wtdat_save = readl(wdt_base + S3C2410_WTDAT);
566 464
567 /* Note that WTCNT doesn't need to be saved. */ 465 /* Note that WTCNT doesn't need to be saved. */
568 s3c2410wdt_stop(); 466 s3c2410wdt_stop(&s3c2410_wdd);
569 467
570 return 0; 468 return 0;
571} 469}
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index f31493e65b38..b01a30e5a663 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -300,7 +300,7 @@ static int __init sbwdog_init(void)
300 * get the resources 300 * get the resources
301 */ 301 */
302 302
303 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 303 ret = request_irq(1, sbwdog_interrupt, IRQF_SHARED,
304 ident.identity, (void *)user_dog); 304 ident.identity, (void *)user_dog);
305 if (ret) { 305 if (ret) {
306 printk(KERN_ERR "%s: failed to request irq 1 - %d\n", 306 printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
@@ -350,7 +350,7 @@ void platform_wd_setup(void)
350{ 350{
351 int ret; 351 int ret;
352 352
353 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 353 ret = request_irq(1, sbwdog_interrupt, IRQF_SHARED,
354 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); 354 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
355 if (ret) { 355 if (ret) {
356 printk(KERN_CRIT 356 printk(KERN_CRIT
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index 52b63f2f0dac..b2840409ebc7 100644
--- a/drivers/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
@@ -398,7 +398,7 @@ static int __init sc520_wdt_init(void)
398 WATCHDOG_TIMEOUT); 398 WATCHDOG_TIMEOUT);
399 } 399 }
400 400
401 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); 401 wdtmrctl = ioremap(MMCR_BASE + OFFS_WDTMRCTL, 2);
402 if (!wdtmrctl) { 402 if (!wdtmrctl) {
403 printk(KERN_ERR PFX "Unable to remap memory\n"); 403 printk(KERN_ERR PFX "Unable to remap memory\n");
404 rc = -ENOMEM; 404 rc = -ENOMEM;
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index e5c91d4404ed..dd5d67548758 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -142,7 +142,7 @@ static void w83627hf_init(void)
142 w83627hf_unselect_wd_register(); 142 w83627hf_unselect_wd_register();
143} 143}
144 144
145static void wdt_ctrl(int timeout) 145static void wdt_set_time(int timeout)
146{ 146{
147 spin_lock(&io_lock); 147 spin_lock(&io_lock);
148 148
@@ -158,13 +158,13 @@ static void wdt_ctrl(int timeout)
158 158
159static int wdt_ping(void) 159static int wdt_ping(void)
160{ 160{
161 wdt_ctrl(timeout); 161 wdt_set_time(timeout);
162 return 0; 162 return 0;
163} 163}
164 164
165static int wdt_disable(void) 165static int wdt_disable(void)
166{ 166{
167 wdt_ctrl(0); 167 wdt_set_time(0);
168 return 0; 168 return 0;
169} 169}
170 170
@@ -176,6 +176,24 @@ static int wdt_set_heartbeat(int t)
176 return 0; 176 return 0;
177} 177}
178 178
179static int wdt_get_time(void)
180{
181 int timeleft;
182
183 spin_lock(&io_lock);
184
185 w83627hf_select_wd_register();
186
187 outb_p(0xF6, WDT_EFER); /* Select CRF6 */
188 timeleft = inb_p(WDT_EFDR); /* Read Timeout counter to CRF6 */
189
190 w83627hf_unselect_wd_register();
191
192 spin_unlock(&io_lock);
193
194 return timeleft;
195}
196
179static ssize_t wdt_write(struct file *file, const char __user *buf, 197static ssize_t wdt_write(struct file *file, const char __user *buf,
180 size_t count, loff_t *ppos) 198 size_t count, loff_t *ppos)
181{ 199{
@@ -202,7 +220,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
202{ 220{
203 void __user *argp = (void __user *)arg; 221 void __user *argp = (void __user *)arg;
204 int __user *p = argp; 222 int __user *p = argp;
205 int new_timeout; 223 int timeval;
206 static const struct watchdog_info ident = { 224 static const struct watchdog_info ident = {
207 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 225 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
208 WDIOF_MAGICCLOSE, 226 WDIOF_MAGICCLOSE,
@@ -238,14 +256,17 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
238 wdt_ping(); 256 wdt_ping();
239 break; 257 break;
240 case WDIOC_SETTIMEOUT: 258 case WDIOC_SETTIMEOUT:
241 if (get_user(new_timeout, p)) 259 if (get_user(timeval, p))
242 return -EFAULT; 260 return -EFAULT;
243 if (wdt_set_heartbeat(new_timeout)) 261 if (wdt_set_heartbeat(timeval))
244 return -EINVAL; 262 return -EINVAL;
245 wdt_ping(); 263 wdt_ping();
246 /* Fall */ 264 /* Fall */
247 case WDIOC_GETTIMEOUT: 265 case WDIOC_GETTIMEOUT:
248 return put_user(timeout, p); 266 return put_user(timeout, p);
267 case WDIOC_GETTIMELEFT:
268 timeval = wdt_get_time();
269 return put_user(timeval, p);
249 default: 270 default:
250 return -ENOTTY; 271 return -ENOTTY;
251 } 272 }
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index bb03e151a1d0..d2ef002be96b 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -612,7 +612,7 @@ static int __init wdt_init(void)
612 goto out; 612 goto out;
613 } 613 }
614 614
615 ret = request_irq(irq, wdt_interrupt, IRQF_DISABLED, "wdt501p", NULL); 615 ret = request_irq(irq, wdt_interrupt, 0, "wdt501p", NULL);
616 if (ret) { 616 if (ret) {
617 printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq); 617 printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq);
618 goto outreg; 618 goto outreg;
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 172dad6c7693..e0fc3baa9197 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -643,7 +643,7 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
643 irq = dev->irq; 643 irq = dev->irq;
644 io = pci_resource_start(dev, 2); 644 io = pci_resource_start(dev, 2);
645 645
646 if (request_irq(irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED, 646 if (request_irq(irq, wdtpci_interrupt, IRQF_SHARED,
647 "wdt_pci", &wdtpci_miscdev)) { 647 "wdt_pci", &wdtpci_miscdev)) {
648 printk(KERN_ERR PFX "IRQ %d is not free\n", irq); 648 printk(KERN_ERR PFX "IRQ %d is not free\n", irq);
649 goto out_reg; 649 goto out_reg;
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 871caea4e1c6..7be38556aed0 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -12,8 +12,7 @@
12#include <linux/moduleparam.h> 12#include <linux/moduleparam.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/fs.h> 15#include <linux/slab.h>
16#include <linux/miscdevice.h>
17#include <linux/platform_device.h> 16#include <linux/platform_device.h>
18#include <linux/watchdog.h> 17#include <linux/watchdog.h>
19#include <linux/uaccess.h> 18#include <linux/uaccess.h>
@@ -29,19 +28,19 @@ MODULE_PARM_DESC(nowayout,
29 "Watchdog cannot be stopped once started (default=" 28 "Watchdog cannot be stopped once started (default="
30 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 29 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
31 30
32static unsigned long wm831x_wdt_users; 31struct wm831x_wdt_drvdata {
33static struct miscdevice wm831x_wdt_miscdev; 32 struct watchdog_device wdt;
34static int wm831x_wdt_expect_close; 33 struct wm831x *wm831x;
35static DEFINE_MUTEX(wdt_mutex); 34 struct mutex lock;
36static struct wm831x *wm831x; 35 int update_gpio;
37static unsigned int update_gpio; 36 int update_state;
38static unsigned int update_state; 37};
39 38
40/* We can't use the sub-second values here but they're included 39/* We can't use the sub-second values here but they're included
41 * for completeness. */ 40 * for completeness. */
42static struct { 41static struct {
43 int time; /* Seconds */ 42 unsigned int time; /* Seconds */
44 u16 val; /* WDOG_TO value */ 43 u16 val; /* WDOG_TO value */
45} wm831x_wdt_cfgs[] = { 44} wm831x_wdt_cfgs[] = {
46 { 1, 2 }, 45 { 1, 2 },
47 { 2, 3 }, 46 { 2, 3 },
@@ -52,32 +51,13 @@ static struct {
52 { 33, 7 }, /* Actually 32.768s so include both, others round down */ 51 { 33, 7 }, /* Actually 32.768s so include both, others round down */
53}; 52};
54 53
55static int wm831x_wdt_set_timeout(struct wm831x *wm831x, u16 value) 54static int wm831x_wdt_start(struct watchdog_device *wdt_dev)
56{
57 int ret;
58
59 mutex_lock(&wdt_mutex);
60
61 ret = wm831x_reg_unlock(wm831x);
62 if (ret == 0) {
63 ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
64 WM831X_WDOG_TO_MASK, value);
65 wm831x_reg_lock(wm831x);
66 } else {
67 dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
68 ret);
69 }
70
71 mutex_unlock(&wdt_mutex);
72
73 return ret;
74}
75
76static int wm831x_wdt_start(struct wm831x *wm831x)
77{ 55{
56 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
57 struct wm831x *wm831x = driver_data->wm831x;
78 int ret; 58 int ret;
79 59
80 mutex_lock(&wdt_mutex); 60 mutex_lock(&driver_data->lock);
81 61
82 ret = wm831x_reg_unlock(wm831x); 62 ret = wm831x_reg_unlock(wm831x);
83 if (ret == 0) { 63 if (ret == 0) {
@@ -89,16 +69,18 @@ static int wm831x_wdt_start(struct wm831x *wm831x)
89 ret); 69 ret);
90 } 70 }
91 71
92 mutex_unlock(&wdt_mutex); 72 mutex_unlock(&driver_data->lock);
93 73
94 return ret; 74 return ret;
95} 75}
96 76
97static int wm831x_wdt_stop(struct wm831x *wm831x) 77static int wm831x_wdt_stop(struct watchdog_device *wdt_dev)
98{ 78{
79 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
80 struct wm831x *wm831x = driver_data->wm831x;
99 int ret; 81 int ret;
100 82
101 mutex_lock(&wdt_mutex); 83 mutex_lock(&driver_data->lock);
102 84
103 ret = wm831x_reg_unlock(wm831x); 85 ret = wm831x_reg_unlock(wm831x);
104 if (ret == 0) { 86 if (ret == 0) {
@@ -110,26 +92,28 @@ static int wm831x_wdt_stop(struct wm831x *wm831x)
110 ret); 92 ret);
111 } 93 }
112 94
113 mutex_unlock(&wdt_mutex); 95 mutex_unlock(&driver_data->lock);
114 96
115 return ret; 97 return ret;
116} 98}
117 99
118static int wm831x_wdt_kick(struct wm831x *wm831x) 100static int wm831x_wdt_ping(struct watchdog_device *wdt_dev)
119{ 101{
102 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
103 struct wm831x *wm831x = driver_data->wm831x;
120 int ret; 104 int ret;
121 u16 reg; 105 u16 reg;
122 106
123 mutex_lock(&wdt_mutex); 107 mutex_lock(&driver_data->lock);
124 108
125 if (update_gpio) { 109 if (driver_data->update_gpio) {
126 gpio_set_value_cansleep(update_gpio, update_state); 110 gpio_set_value_cansleep(driver_data->update_gpio,
127 update_state = !update_state; 111 driver_data->update_state);
112 driver_data->update_state = !driver_data->update_state;
128 ret = 0; 113 ret = 0;
129 goto out; 114 goto out;
130 } 115 }
131 116
132
133 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 117 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
134 118
135 if (!(reg & WM831X_WDOG_RST_SRC)) { 119 if (!(reg & WM831X_WDOG_RST_SRC)) {
@@ -150,182 +134,59 @@ static int wm831x_wdt_kick(struct wm831x *wm831x)
150 } 134 }
151 135
152out: 136out:
153 mutex_unlock(&wdt_mutex); 137 mutex_unlock(&driver_data->lock);
154 138
155 return ret; 139 return ret;
156} 140}
157 141
158static int wm831x_wdt_open(struct inode *inode, struct file *file) 142static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev,
143 unsigned int timeout)
159{ 144{
160 int ret; 145 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
161 146 struct wm831x *wm831x = driver_data->wm831x;
162 if (!wm831x) 147 int ret, i;
163 return -ENODEV;
164
165 if (test_and_set_bit(0, &wm831x_wdt_users))
166 return -EBUSY;
167 148
168 ret = wm831x_wdt_start(wm831x); 149 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
169 if (ret != 0) 150 if (wm831x_wdt_cfgs[i].time == timeout)
170 return ret; 151 break;
171 152 if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
172 return nonseekable_open(inode, file); 153 ret = -EINVAL;
173}
174 154
175static int wm831x_wdt_release(struct inode *inode, struct file *file) 155 ret = wm831x_reg_unlock(wm831x);
176{ 156 if (ret == 0) {
177 if (wm831x_wdt_expect_close) 157 ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
178 wm831x_wdt_stop(wm831x); 158 WM831X_WDOG_TO_MASK,
179 else { 159 wm831x_wdt_cfgs[i].val);
180 dev_warn(wm831x->dev, "Watchdog device closed uncleanly\n"); 160 wm831x_reg_lock(wm831x);
181 wm831x_wdt_kick(wm831x); 161 } else {
162 dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
163 ret);
182 } 164 }
183 165
184 clear_bit(0, &wm831x_wdt_users); 166 return ret;
185
186 return 0;
187}
188
189static ssize_t wm831x_wdt_write(struct file *file,
190 const char __user *data, size_t count,
191 loff_t *ppos)
192{
193 size_t i;
194
195 if (count) {
196 wm831x_wdt_kick(wm831x);
197
198 if (!nowayout) {
199 /* In case it was set long ago */
200 wm831x_wdt_expect_close = 0;
201
202 /* scan to see whether or not we got the magic
203 character */
204 for (i = 0; i != count; i++) {
205 char c;
206 if (get_user(c, data + i))
207 return -EFAULT;
208 if (c == 'V')
209 wm831x_wdt_expect_close = 42;
210 }
211 }
212 }
213 return count;
214} 167}
215 168
216static const struct watchdog_info ident = { 169static const struct watchdog_info wm831x_wdt_info = {
217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 170 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
218 .identity = "WM831x Watchdog", 171 .identity = "WM831x Watchdog",
219}; 172};
220 173
221static long wm831x_wdt_ioctl(struct file *file, unsigned int cmd, 174static const struct watchdog_ops wm831x_wdt_ops = {
222 unsigned long arg)
223{
224 int ret = -ENOTTY, time, i;
225 void __user *argp = (void __user *)arg;
226 int __user *p = argp;
227 u16 reg;
228
229 switch (cmd) {
230 case WDIOC_GETSUPPORT:
231 ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
232 break;
233
234 case WDIOC_GETSTATUS:
235 case WDIOC_GETBOOTSTATUS:
236 ret = put_user(0, p);
237 break;
238
239 case WDIOC_SETOPTIONS:
240 {
241 int options;
242
243 if (get_user(options, p))
244 return -EFAULT;
245
246 ret = -EINVAL;
247
248 /* Setting both simultaneously means at least one must fail */
249 if (options == WDIOS_DISABLECARD)
250 ret = wm831x_wdt_start(wm831x);
251
252 if (options == WDIOS_ENABLECARD)
253 ret = wm831x_wdt_stop(wm831x);
254 break;
255 }
256
257 case WDIOC_KEEPALIVE:
258 ret = wm831x_wdt_kick(wm831x);
259 break;
260
261 case WDIOC_SETTIMEOUT:
262 ret = get_user(time, p);
263 if (ret)
264 break;
265
266 if (time == 0) {
267 if (nowayout)
268 ret = -EINVAL;
269 else
270 wm831x_wdt_stop(wm831x);
271 break;
272 }
273
274 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
275 if (wm831x_wdt_cfgs[i].time == time)
276 break;
277 if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
278 ret = -EINVAL;
279 else
280 ret = wm831x_wdt_set_timeout(wm831x,
281 wm831x_wdt_cfgs[i].val);
282 break;
283
284 case WDIOC_GETTIMEOUT:
285 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
286 reg &= WM831X_WDOG_TO_MASK;
287 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
288 if (wm831x_wdt_cfgs[i].val == reg)
289 break;
290 if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) {
291 dev_warn(wm831x->dev,
292 "Unknown watchdog configuration: %x\n", reg);
293 ret = -EINVAL;
294 } else
295 ret = put_user(wm831x_wdt_cfgs[i].time, p);
296
297 }
298
299 return ret;
300}
301
302static const struct file_operations wm831x_wdt_fops = {
303 .owner = THIS_MODULE, 175 .owner = THIS_MODULE,
304 .llseek = no_llseek, 176 .start = wm831x_wdt_start,
305 .write = wm831x_wdt_write, 177 .stop = wm831x_wdt_stop,
306 .unlocked_ioctl = wm831x_wdt_ioctl, 178 .ping = wm831x_wdt_ping,
307 .open = wm831x_wdt_open, 179 .set_timeout = wm831x_wdt_set_timeout,
308 .release = wm831x_wdt_release,
309};
310
311static struct miscdevice wm831x_wdt_miscdev = {
312 .minor = WATCHDOG_MINOR,
313 .name = "watchdog",
314 .fops = &wm831x_wdt_fops,
315}; 180};
316 181
317static int __devinit wm831x_wdt_probe(struct platform_device *pdev) 182static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
318{ 183{
184 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
319 struct wm831x_pdata *chip_pdata; 185 struct wm831x_pdata *chip_pdata;
320 struct wm831x_watchdog_pdata *pdata; 186 struct wm831x_watchdog_pdata *pdata;
321 int reg, ret; 187 struct wm831x_wdt_drvdata *driver_data;
322 188 struct watchdog_device *wm831x_wdt;
323 if (wm831x) { 189 int reg, ret, i;
324 dev_err(&pdev->dev, "wm831x watchdog already registered\n");
325 return -EBUSY;
326 }
327
328 wm831x = dev_get_drvdata(pdev->dev.parent);
329 190
330 ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 191 ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
331 if (ret < 0) { 192 if (ret < 0) {
@@ -338,6 +199,36 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
338 if (reg & WM831X_WDOG_DEBUG) 199 if (reg & WM831X_WDOG_DEBUG)
339 dev_warn(wm831x->dev, "Watchdog is paused\n"); 200 dev_warn(wm831x->dev, "Watchdog is paused\n");
340 201
202 driver_data = kzalloc(sizeof(*driver_data), GFP_KERNEL);
203 if (!driver_data) {
204 dev_err(wm831x->dev, "Unable to alloacate watchdog device\n");
205 ret = -ENOMEM;
206 goto err;
207 }
208
209 mutex_init(&driver_data->lock);
210 driver_data->wm831x = wm831x;
211
212 wm831x_wdt = &driver_data->wdt;
213
214 wm831x_wdt->info = &wm831x_wdt_info;
215 wm831x_wdt->ops = &wm831x_wdt_ops;
216 watchdog_set_drvdata(wm831x_wdt, driver_data);
217
218 if (nowayout)
219 wm831x_wdt->status |= WDOG_NO_WAY_OUT;
220
221 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
222 reg &= WM831X_WDOG_TO_MASK;
223 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
224 if (wm831x_wdt_cfgs[i].val == reg)
225 break;
226 if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
227 dev_warn(wm831x->dev,
228 "Unknown watchdog timeout: %x\n", reg);
229 else
230 wm831x_wdt->timeout = wm831x_wdt_cfgs[i].time;
231
341 /* Apply any configuration */ 232 /* Apply any configuration */
342 if (pdev->dev.parent->platform_data) { 233 if (pdev->dev.parent->platform_data) {
343 chip_pdata = pdev->dev.parent->platform_data; 234 chip_pdata = pdev->dev.parent->platform_data;
@@ -361,7 +252,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
361 dev_err(wm831x->dev, 252 dev_err(wm831x->dev,
362 "Failed to request update GPIO: %d\n", 253 "Failed to request update GPIO: %d\n",
363 ret); 254 ret);
364 goto err; 255 goto err_alloc;
365 } 256 }
366 257
367 ret = gpio_direction_output(pdata->update_gpio, 0); 258 ret = gpio_direction_output(pdata->update_gpio, 0);
@@ -372,7 +263,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
372 goto err_gpio; 263 goto err_gpio;
373 } 264 }
374 265
375 update_gpio = pdata->update_gpio; 266 driver_data->update_gpio = pdata->update_gpio;
376 267
377 /* Make sure the watchdog takes hardware updates */ 268 /* Make sure the watchdog takes hardware updates */
378 reg |= WM831X_WDOG_RST_SRC; 269 reg |= WM831X_WDOG_RST_SRC;
@@ -389,33 +280,34 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
389 } 280 }
390 } 281 }
391 282
392 wm831x_wdt_miscdev.parent = &pdev->dev; 283 ret = watchdog_register_device(&driver_data->wdt);
393
394 ret = misc_register(&wm831x_wdt_miscdev);
395 if (ret != 0) { 284 if (ret != 0) {
396 dev_err(wm831x->dev, "Failed to register miscdev: %d\n", ret); 285 dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
286 ret);
397 goto err_gpio; 287 goto err_gpio;
398 } 288 }
399 289
290 dev_set_drvdata(&pdev->dev, driver_data);
291
400 return 0; 292 return 0;
401 293
402err_gpio: 294err_gpio:
403 if (update_gpio) { 295 if (driver_data->update_gpio)
404 gpio_free(update_gpio); 296 gpio_free(driver_data->update_gpio);
405 update_gpio = 0; 297err_alloc:
406 } 298 kfree(driver_data);
407err: 299err:
408 return ret; 300 return ret;
409} 301}
410 302
411static int __devexit wm831x_wdt_remove(struct platform_device *pdev) 303static int __devexit wm831x_wdt_remove(struct platform_device *pdev)
412{ 304{
413 if (update_gpio) { 305 struct wm831x_wdt_drvdata *driver_data = dev_get_drvdata(&pdev->dev);
414 gpio_free(update_gpio); 306
415 update_gpio = 0; 307 watchdog_unregister_device(&driver_data->wdt);
416 }
417 308
418 misc_deregister(&wm831x_wdt_miscdev); 309 if (driver_data->update_gpio)
310 gpio_free(driver_data->update_gpio);
419 311
420 return 0; 312 return 0;
421} 313}
diff --git a/fs/bio.c b/fs/bio.c
index 9bfade8a609b..41c93c722244 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -255,7 +255,6 @@ void bio_init(struct bio *bio)
255{ 255{
256 memset(bio, 0, sizeof(*bio)); 256 memset(bio, 0, sizeof(*bio));
257 bio->bi_flags = 1 << BIO_UPTODATE; 257 bio->bi_flags = 1 << BIO_UPTODATE;
258 bio->bi_comp_cpu = -1;
259 atomic_set(&bio->bi_cnt, 1); 258 atomic_set(&bio->bi_cnt, 1);
260} 259}
261EXPORT_SYMBOL(bio_init); 260EXPORT_SYMBOL(bio_init);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 95f786ec7f08..b07f1da1de4e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -971,7 +971,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty)
971 971
972 if (!bdev->bd_disk) 972 if (!bdev->bd_disk)
973 return; 973 return;
974 if (disk_partitionable(bdev->bd_disk)) 974 if (disk_part_scan_enabled(bdev->bd_disk))
975 bdev->bd_invalidated = 1; 975 bdev->bd_invalidated = 1;
976} 976}
977 977
@@ -1085,6 +1085,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
1085static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) 1085static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1086{ 1086{
1087 struct gendisk *disk; 1087 struct gendisk *disk;
1088 struct module *owner;
1088 int ret; 1089 int ret;
1089 int partno; 1090 int partno;
1090 int perm = 0; 1091 int perm = 0;
@@ -1110,6 +1111,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1110 disk = get_gendisk(bdev->bd_dev, &partno); 1111 disk = get_gendisk(bdev->bd_dev, &partno);
1111 if (!disk) 1112 if (!disk)
1112 goto out; 1113 goto out;
1114 owner = disk->fops->owner;
1113 1115
1114 disk_block_events(disk); 1116 disk_block_events(disk);
1115 mutex_lock_nested(&bdev->bd_mutex, for_part); 1117 mutex_lock_nested(&bdev->bd_mutex, for_part);
@@ -1137,8 +1139,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1137 bdev->bd_disk = NULL; 1139 bdev->bd_disk = NULL;
1138 mutex_unlock(&bdev->bd_mutex); 1140 mutex_unlock(&bdev->bd_mutex);
1139 disk_unblock_events(disk); 1141 disk_unblock_events(disk);
1140 module_put(disk->fops->owner);
1141 put_disk(disk); 1142 put_disk(disk);
1143 module_put(owner);
1142 goto restart; 1144 goto restart;
1143 } 1145 }
1144 } 1146 }
@@ -1194,8 +1196,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1194 goto out_unlock_bdev; 1196 goto out_unlock_bdev;
1195 } 1197 }
1196 /* only one opener holds refs to the module and disk */ 1198 /* only one opener holds refs to the module and disk */
1197 module_put(disk->fops->owner);
1198 put_disk(disk); 1199 put_disk(disk);
1200 module_put(owner);
1199 } 1201 }
1200 bdev->bd_openers++; 1202 bdev->bd_openers++;
1201 if (for_part) 1203 if (for_part)
@@ -1215,8 +1217,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1215 out_unlock_bdev: 1217 out_unlock_bdev:
1216 mutex_unlock(&bdev->bd_mutex); 1218 mutex_unlock(&bdev->bd_mutex);
1217 disk_unblock_events(disk); 1219 disk_unblock_events(disk);
1218 module_put(disk->fops->owner);
1219 put_disk(disk); 1220 put_disk(disk);
1221 module_put(owner);
1220 out: 1222 out:
1221 bdput(bdev); 1223 bdput(bdev);
1222 1224
@@ -1442,14 +1444,15 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
1442 if (!bdev->bd_openers) { 1444 if (!bdev->bd_openers) {
1443 struct module *owner = disk->fops->owner; 1445 struct module *owner = disk->fops->owner;
1444 1446
1445 put_disk(disk);
1446 module_put(owner);
1447 disk_put_part(bdev->bd_part); 1447 disk_put_part(bdev->bd_part);
1448 bdev->bd_part = NULL; 1448 bdev->bd_part = NULL;
1449 bdev->bd_disk = NULL; 1449 bdev->bd_disk = NULL;
1450 if (bdev != bdev->bd_contains) 1450 if (bdev != bdev->bd_contains)
1451 victim = bdev->bd_contains; 1451 victim = bdev->bd_contains;
1452 bdev->bd_contains = NULL; 1452 bdev->bd_contains = NULL;
1453
1454 put_disk(disk);
1455 module_put(owner);
1453 } 1456 }
1454 mutex_unlock(&bdev->bd_mutex); 1457 mutex_unlock(&bdev->bd_mutex);
1455 bdput(bdev); 1458 bdput(bdev);
diff --git a/fs/exofs/Kconfig b/fs/exofs/Kconfig
index fa9a286c8771..da42f32c49be 100644
--- a/fs/exofs/Kconfig
+++ b/fs/exofs/Kconfig
@@ -5,7 +5,7 @@
5# selected by any of the users. 5# selected by any of the users.
6config ORE 6config ORE
7 tristate 7 tristate
8 depends on EXOFS_FS 8 depends on EXOFS_FS || PNFS_OBJLAYOUT
9 select ASYNC_XOR 9 select ASYNC_XOR
10 default SCSI_OSD_ULD 10 default SCSI_OSD_ULD
11 11
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 918ad647afea..726e59a9e50f 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -488,17 +488,18 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp,
488 struct xdr_stream *xdr, 488 struct xdr_stream *xdr,
489 struct cb_recallanyargs *args) 489 struct cb_recallanyargs *args)
490{ 490{
491 __be32 *p; 491 uint32_t bitmap[2];
492 __be32 *p, status;
492 493
493 args->craa_addr = svc_addr(rqstp); 494 args->craa_addr = svc_addr(rqstp);
494 p = read_buf(xdr, 4); 495 p = read_buf(xdr, 4);
495 if (unlikely(p == NULL)) 496 if (unlikely(p == NULL))
496 return htonl(NFS4ERR_BADXDR); 497 return htonl(NFS4ERR_BADXDR);
497 args->craa_objs_to_keep = ntohl(*p++); 498 args->craa_objs_to_keep = ntohl(*p++);
498 p = read_buf(xdr, 4); 499 status = decode_bitmap(xdr, bitmap);
499 if (unlikely(p == NULL)) 500 if (unlikely(status))
500 return htonl(NFS4ERR_BADXDR); 501 return status;
501 args->craa_type_mask = ntohl(*p); 502 args->craa_type_mask = bitmap[0];
502 503
503 return 0; 504 return 0;
504} 505}
@@ -986,4 +987,5 @@ struct svc_version nfs4_callback_version4 = {
986 .vs_proc = nfs4_callback_procedures1, 987 .vs_proc = nfs4_callback_procedures1,
987 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 988 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
988 .vs_dispatch = NULL, 989 .vs_dispatch = NULL,
990 .vs_hidden = 1,
989}; 991};
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 91c01f0a4c3b..0a1f8312b4dc 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -137,11 +137,9 @@ nfs_file_open(struct inode *inode, struct file *filp)
137static int 137static int
138nfs_file_release(struct inode *inode, struct file *filp) 138nfs_file_release(struct inode *inode, struct file *filp)
139{ 139{
140 struct dentry *dentry = filp->f_path.dentry;
141
142 dprintk("NFS: release(%s/%s)\n", 140 dprintk("NFS: release(%s/%s)\n",
143 dentry->d_parent->d_name.name, 141 filp->f_path.dentry->d_parent->d_name.name,
144 dentry->d_name.name); 142 filp->f_path.dentry->d_name.name);
145 143
146 nfs_inc_stats(inode, NFSIOS_VFSRELEASE); 144 nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
147 return nfs_release(inode, filp); 145 return nfs_release(inode, filp);
@@ -228,14 +226,13 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
228 struct dentry * dentry = iocb->ki_filp->f_path.dentry; 226 struct dentry * dentry = iocb->ki_filp->f_path.dentry;
229 struct inode * inode = dentry->d_inode; 227 struct inode * inode = dentry->d_inode;
230 ssize_t result; 228 ssize_t result;
231 size_t count = iov_length(iov, nr_segs);
232 229
233 if (iocb->ki_filp->f_flags & O_DIRECT) 230 if (iocb->ki_filp->f_flags & O_DIRECT)
234 return nfs_file_direct_read(iocb, iov, nr_segs, pos); 231 return nfs_file_direct_read(iocb, iov, nr_segs, pos);
235 232
236 dprintk("NFS: read(%s/%s, %lu@%lu)\n", 233 dprintk("NFS: read(%s/%s, %lu@%lu)\n",
237 dentry->d_parent->d_name.name, dentry->d_name.name, 234 dentry->d_parent->d_name.name, dentry->d_name.name,
238 (unsigned long) count, (unsigned long) pos); 235 (unsigned long) iov_length(iov, nr_segs), (unsigned long) pos);
239 236
240 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); 237 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
241 if (!result) { 238 if (!result) {
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 09119418402f..12185aadb349 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -449,9 +449,8 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
449 449
450 fl->dsaddr = dsaddr; 450 fl->dsaddr = dsaddr;
451 451
452 if (fl->first_stripe_index < 0 || 452 if (fl->first_stripe_index >= dsaddr->stripe_count) {
453 fl->first_stripe_index >= dsaddr->stripe_count) { 453 dprintk("%s Bad first_stripe_index %u\n",
454 dprintk("%s Bad first_stripe_index %d\n",
455 __func__, fl->first_stripe_index); 454 __func__, fl->first_stripe_index);
456 goto out_put; 455 goto out_put;
457 } 456 }
@@ -552,7 +551,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
552 551
553 /* Note that a zero value for num_fh is legal for STRIPE_SPARSE. 552 /* Note that a zero value for num_fh is legal for STRIPE_SPARSE.
554 * Futher checking is done in filelayout_check_layout */ 553 * Futher checking is done in filelayout_check_layout */
555 if (fl->num_fh < 0 || fl->num_fh > 554 if (fl->num_fh >
556 max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT)) 555 max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT))
557 goto out_err; 556 goto out_err;
558 557
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d2ae413c986a..b60fddf606f7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5950,6 +5950,7 @@ static void nfs4_layoutcommit_release(void *calldata)
5950{ 5950{
5951 struct nfs4_layoutcommit_data *data = calldata; 5951 struct nfs4_layoutcommit_data *data = calldata;
5952 struct pnfs_layout_segment *lseg, *tmp; 5952 struct pnfs_layout_segment *lseg, *tmp;
5953 unsigned long *bitlock = &NFS_I(data->args.inode)->flags;
5953 5954
5954 pnfs_cleanup_layoutcommit(data); 5955 pnfs_cleanup_layoutcommit(data);
5955 /* Matched by references in pnfs_set_layoutcommit */ 5956 /* Matched by references in pnfs_set_layoutcommit */
@@ -5959,6 +5960,11 @@ static void nfs4_layoutcommit_release(void *calldata)
5959 &lseg->pls_flags)) 5960 &lseg->pls_flags))
5960 put_lseg(lseg); 5961 put_lseg(lseg);
5961 } 5962 }
5963
5964 clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
5965 smp_mb__after_clear_bit();
5966 wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
5967
5962 put_rpccred(data->cred); 5968 put_rpccred(data->cred);
5963 kfree(data); 5969 kfree(data);
5964} 5970}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1dce12f41a4f..e6161b213ed1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -6602,8 +6602,6 @@ static int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp,
6602 if (status) 6602 if (status)
6603 goto out; 6603 goto out;
6604 status = decode_secinfo(xdr, res); 6604 status = decode_secinfo(xdr, res);
6605 if (status)
6606 goto out;
6607out: 6605out:
6608 return status; 6606 return status;
6609} 6607}
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index d0cda12fddc3..c807ab93140e 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -38,21 +38,15 @@
38 */ 38 */
39 39
40#include <linux/module.h> 40#include <linux/module.h>
41#include <scsi/osd_initiator.h> 41#include <scsi/osd_ore.h>
42 42
43#include "objlayout.h" 43#include "objlayout.h"
44 44
45#define NFSDBG_FACILITY NFSDBG_PNFS_LD 45#define NFSDBG_FACILITY NFSDBG_PNFS_LD
46 46
47#define _LLU(x) ((unsigned long long)x)
48
49enum { BIO_MAX_PAGES_KMALLOC =
50 (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),
51};
52
53struct objio_dev_ent { 47struct objio_dev_ent {
54 struct nfs4_deviceid_node id_node; 48 struct nfs4_deviceid_node id_node;
55 struct osd_dev *od; 49 struct ore_dev od;
56}; 50};
57 51
58static void 52static void
@@ -60,8 +54,8 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d)
60{ 54{
61 struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node); 55 struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node);
62 56
63 dprintk("%s: free od=%p\n", __func__, de->od); 57 dprintk("%s: free od=%p\n", __func__, de->od.od);
64 osduld_put_device(de->od); 58 osduld_put_device(de->od.od);
65 kfree(de); 59 kfree(de);
66} 60}
67 61
@@ -98,12 +92,12 @@ _dev_list_add(const struct nfs_server *nfss,
98 nfss->pnfs_curr_ld, 92 nfss->pnfs_curr_ld,
99 nfss->nfs_client, 93 nfss->nfs_client,
100 d_id); 94 d_id);
101 de->od = od; 95 de->od.od = od;
102 96
103 d = nfs4_insert_deviceid_node(&de->id_node); 97 d = nfs4_insert_deviceid_node(&de->id_node);
104 n = container_of(d, struct objio_dev_ent, id_node); 98 n = container_of(d, struct objio_dev_ent, id_node);
105 if (n != de) { 99 if (n != de) {
106 dprintk("%s: Race with other n->od=%p\n", __func__, n->od); 100 dprintk("%s: Race with other n->od=%p\n", __func__, n->od.od);
107 objio_free_deviceid_node(&de->id_node); 101 objio_free_deviceid_node(&de->id_node);
108 de = n; 102 de = n;
109 } 103 }
@@ -111,28 +105,11 @@ _dev_list_add(const struct nfs_server *nfss,
111 return de; 105 return de;
112} 106}
113 107
114struct caps_buffers {
115 u8 caps_key[OSD_CRYPTO_KEYID_SIZE];
116 u8 creds[OSD_CAP_LEN];
117};
118
119struct objio_segment { 108struct objio_segment {
120 struct pnfs_layout_segment lseg; 109 struct pnfs_layout_segment lseg;
121 110
122 struct pnfs_osd_object_cred *comps; 111 struct ore_layout layout;
123 112 struct ore_components oc;
124 unsigned mirrors_p1;
125 unsigned stripe_unit;
126 unsigned group_width; /* Data stripe_units without integrity comps */
127 u64 group_depth;
128 unsigned group_count;
129
130 unsigned max_io_size;
131
132 unsigned comps_index;
133 unsigned num_comps;
134 /* variable length */
135 struct objio_dev_ent *ods[];
136}; 113};
137 114
138static inline struct objio_segment * 115static inline struct objio_segment *
@@ -141,59 +118,44 @@ OBJIO_LSEG(struct pnfs_layout_segment *lseg)
141 return container_of(lseg, struct objio_segment, lseg); 118 return container_of(lseg, struct objio_segment, lseg);
142} 119}
143 120
144struct objio_state;
145typedef ssize_t (*objio_done_fn)(struct objio_state *ios);
146
147struct objio_state { 121struct objio_state {
148 /* Generic layer */ 122 /* Generic layer */
149 struct objlayout_io_state ol_state; 123 struct objlayout_io_res oir;
150 124
151 struct objio_segment *layout; 125 bool sync;
152 126 /*FIXME: Support for extra_bytes at ore_get_rw_state() */
153 struct kref kref; 127 struct ore_io_state *ios;
154 objio_done_fn done;
155 void *private;
156
157 unsigned long length;
158 unsigned numdevs; /* Actually used devs in this IO */
159 /* A per-device variable array of size numdevs */
160 struct _objio_per_comp {
161 struct bio *bio;
162 struct osd_request *or;
163 unsigned long length;
164 u64 offset;
165 unsigned dev;
166 } per_dev[];
167}; 128};
168 129
169/* Send and wait for a get_device_info of devices in the layout, 130/* Send and wait for a get_device_info of devices in the layout,
170 then look them up with the osd_initiator library */ 131 then look them up with the osd_initiator library */
171static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay, 132static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay,
172 struct objio_segment *objio_seg, unsigned comp, 133 struct objio_segment *objio_seg, unsigned c, struct nfs4_deviceid *d_id,
173 gfp_t gfp_flags) 134 gfp_t gfp_flags)
174{ 135{
175 struct pnfs_osd_deviceaddr *deviceaddr; 136 struct pnfs_osd_deviceaddr *deviceaddr;
176 struct nfs4_deviceid *d_id;
177 struct objio_dev_ent *ode; 137 struct objio_dev_ent *ode;
178 struct osd_dev *od; 138 struct osd_dev *od;
179 struct osd_dev_info odi; 139 struct osd_dev_info odi;
180 int err; 140 int err;
181 141
182 d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id;
183
184 ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id); 142 ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id);
185 if (ode) 143 if (ode) {
186 return ode; 144 objio_seg->oc.ods[c] = &ode->od; /* must use container_of */
145 return 0;
146 }
187 147
188 err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags); 148 err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags);
189 if (unlikely(err)) { 149 if (unlikely(err)) {
190 dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n", 150 dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n",
191 __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err); 151 __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err);
192 return ERR_PTR(err); 152 return err;
193 } 153 }
194 154
195 odi.systemid_len = deviceaddr->oda_systemid.len; 155 odi.systemid_len = deviceaddr->oda_systemid.len;
196 if (odi.systemid_len > sizeof(odi.systemid)) { 156 if (odi.systemid_len > sizeof(odi.systemid)) {
157 dprintk("%s: odi.systemid_len > sizeof(systemid=%zd)\n",
158 __func__, sizeof(odi.systemid));
197 err = -EINVAL; 159 err = -EINVAL;
198 goto out; 160 goto out;
199 } else if (odi.systemid_len) 161 } else if (odi.systemid_len)
@@ -218,96 +180,53 @@ static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay,
218 180
219 ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od, 181 ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od,
220 gfp_flags); 182 gfp_flags);
221 183 objio_seg->oc.ods[c] = &ode->od; /* must use container_of */
184 dprintk("Adding new dev_id(%llx:%llx)\n",
185 _DEVID_LO(d_id), _DEVID_HI(d_id));
222out: 186out:
223 dprintk("%s: return=%d\n", __func__, err);
224 objlayout_put_deviceinfo(deviceaddr); 187 objlayout_put_deviceinfo(deviceaddr);
225 return err ? ERR_PTR(err) : ode; 188 return err;
226} 189}
227 190
228static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay, 191static void copy_single_comp(struct ore_components *oc, unsigned c,
229 struct objio_segment *objio_seg, 192 struct pnfs_osd_object_cred *src_comp)
230 gfp_t gfp_flags)
231{ 193{
232 unsigned i; 194 struct ore_comp *ocomp = &oc->comps[c];
233 int err;
234 195
235 /* lookup all devices */ 196 WARN_ON(src_comp->oc_cap_key.cred_len > 0); /* libosd is NO_SEC only */
236 for (i = 0; i < objio_seg->num_comps; i++) { 197 WARN_ON(src_comp->oc_cap.cred_len > sizeof(ocomp->cred));
237 struct objio_dev_ent *ode;
238 198
239 ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags); 199 ocomp->obj.partition = src_comp->oc_object_id.oid_partition_id;
240 if (unlikely(IS_ERR(ode))) { 200 ocomp->obj.id = src_comp->oc_object_id.oid_object_id;
241 err = PTR_ERR(ode);
242 goto out;
243 }
244 objio_seg->ods[i] = ode;
245 }
246 err = 0;
247 201
248out: 202 memcpy(ocomp->cred, src_comp->oc_cap.cred, sizeof(ocomp->cred));
249 dprintk("%s: return=%d\n", __func__, err);
250 return err;
251} 203}
252 204
253static int _verify_data_map(struct pnfs_osd_layout *layout) 205int __alloc_objio_seg(unsigned numdevs, gfp_t gfp_flags,
206 struct objio_segment **pseg)
254{ 207{
255 struct pnfs_osd_data_map *data_map = &layout->olo_map; 208 struct __alloc_objio_segment {
256 u64 stripe_length; 209 struct objio_segment olseg;
257 u32 group_width; 210 struct ore_dev *ods[numdevs];
258 211 struct ore_comp comps[numdevs];
259/* FIXME: Only raid0 for now. if not go through MDS */ 212 } *aolseg;
260 if (data_map->odm_raid_algorithm != PNFS_OSD_RAID_0) {
261 printk(KERN_ERR "Only RAID_0 for now\n");
262 return -ENOTSUPP;
263 }
264 if (0 != (data_map->odm_num_comps % (data_map->odm_mirror_cnt + 1))) {
265 printk(KERN_ERR "Data Map wrong, num_comps=%u mirrors=%u\n",
266 data_map->odm_num_comps, data_map->odm_mirror_cnt);
267 return -EINVAL;
268 }
269 213
270 if (data_map->odm_group_width) 214 aolseg = kzalloc(sizeof(*aolseg), gfp_flags);
271 group_width = data_map->odm_group_width; 215 if (unlikely(!aolseg)) {
272 else 216 dprintk("%s: Faild allocation numdevs=%d size=%zd\n", __func__,
273 group_width = data_map->odm_num_comps / 217 numdevs, sizeof(*aolseg));
274 (data_map->odm_mirror_cnt + 1); 218 return -ENOMEM;
275
276 stripe_length = (u64)data_map->odm_stripe_unit * group_width;
277 if (stripe_length >= (1ULL << 32)) {
278 printk(KERN_ERR "Total Stripe length(0x%llx)"
279 " >= 32bit is not supported\n", _LLU(stripe_length));
280 return -ENOTSUPP;
281 } 219 }
282 220
283 if (0 != (data_map->odm_stripe_unit & ~PAGE_MASK)) { 221 aolseg->olseg.oc.numdevs = numdevs;
284 printk(KERN_ERR "Stripe Unit(0x%llx)" 222 aolseg->olseg.oc.single_comp = EC_MULTPLE_COMPS;
285 " must be Multples of PAGE_SIZE(0x%lx)\n", 223 aolseg->olseg.oc.comps = aolseg->comps;
286 _LLU(data_map->odm_stripe_unit), PAGE_SIZE); 224 aolseg->olseg.oc.ods = aolseg->ods;
287 return -ENOTSUPP;
288 }
289 225
226 *pseg = &aolseg->olseg;
290 return 0; 227 return 0;
291} 228}
292 229
293static void copy_single_comp(struct pnfs_osd_object_cred *cur_comp,
294 struct pnfs_osd_object_cred *src_comp,
295 struct caps_buffers *caps_p)
296{
297 WARN_ON(src_comp->oc_cap_key.cred_len > sizeof(caps_p->caps_key));
298 WARN_ON(src_comp->oc_cap.cred_len > sizeof(caps_p->creds));
299
300 *cur_comp = *src_comp;
301
302 memcpy(caps_p->caps_key, src_comp->oc_cap_key.cred,
303 sizeof(caps_p->caps_key));
304 cur_comp->oc_cap_key.cred = caps_p->caps_key;
305
306 memcpy(caps_p->creds, src_comp->oc_cap.cred,
307 sizeof(caps_p->creds));
308 cur_comp->oc_cap.cred = caps_p->creds;
309}
310
311int objio_alloc_lseg(struct pnfs_layout_segment **outp, 230int objio_alloc_lseg(struct pnfs_layout_segment **outp,
312 struct pnfs_layout_hdr *pnfslay, 231 struct pnfs_layout_hdr *pnfslay,
313 struct pnfs_layout_range *range, 232 struct pnfs_layout_range *range,
@@ -317,59 +236,43 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp,
317 struct objio_segment *objio_seg; 236 struct objio_segment *objio_seg;
318 struct pnfs_osd_xdr_decode_layout_iter iter; 237 struct pnfs_osd_xdr_decode_layout_iter iter;
319 struct pnfs_osd_layout layout; 238 struct pnfs_osd_layout layout;
320 struct pnfs_osd_object_cred *cur_comp, src_comp; 239 struct pnfs_osd_object_cred src_comp;
321 struct caps_buffers *caps_p; 240 unsigned cur_comp;
322 int err; 241 int err;
323 242
324 err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); 243 err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr);
325 if (unlikely(err)) 244 if (unlikely(err))
326 return err; 245 return err;
327 246
328 err = _verify_data_map(&layout); 247 err = __alloc_objio_seg(layout.olo_num_comps, gfp_flags, &objio_seg);
329 if (unlikely(err)) 248 if (unlikely(err))
330 return err; 249 return err;
331 250
332 objio_seg = kzalloc(sizeof(*objio_seg) + 251 objio_seg->layout.stripe_unit = layout.olo_map.odm_stripe_unit;
333 sizeof(objio_seg->ods[0]) * layout.olo_num_comps + 252 objio_seg->layout.group_width = layout.olo_map.odm_group_width;
334 sizeof(*objio_seg->comps) * layout.olo_num_comps + 253 objio_seg->layout.group_depth = layout.olo_map.odm_group_depth;
335 sizeof(struct caps_buffers) * layout.olo_num_comps, 254 objio_seg->layout.mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
336 gfp_flags); 255 objio_seg->layout.raid_algorithm = layout.olo_map.odm_raid_algorithm;
337 if (!objio_seg)
338 return -ENOMEM;
339 256
340 objio_seg->comps = (void *)(objio_seg->ods + layout.olo_num_comps); 257 err = ore_verify_layout(layout.olo_map.odm_num_comps,
341 cur_comp = objio_seg->comps; 258 &objio_seg->layout);
342 caps_p = (void *)(cur_comp + layout.olo_num_comps);
343 while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err))
344 copy_single_comp(cur_comp++, &src_comp, caps_p++);
345 if (unlikely(err)) 259 if (unlikely(err))
346 goto err; 260 goto err;
347 261
348 objio_seg->num_comps = layout.olo_num_comps; 262 objio_seg->oc.first_dev = layout.olo_comps_index;
349 objio_seg->comps_index = layout.olo_comps_index; 263 cur_comp = 0;
350 err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags); 264 while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) {
351 if (err) 265 copy_single_comp(&objio_seg->oc, cur_comp, &src_comp);
352 goto err; 266 err = objio_devices_lookup(pnfslay, objio_seg, cur_comp,
353 267 &src_comp.oc_object_id.oid_device_id,
354 objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1; 268 gfp_flags);
355 objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit; 269 if (err)
356 if (layout.olo_map.odm_group_width) { 270 goto err;
357 objio_seg->group_width = layout.olo_map.odm_group_width; 271 ++cur_comp;
358 objio_seg->group_depth = layout.olo_map.odm_group_depth;
359 objio_seg->group_count = layout.olo_map.odm_num_comps /
360 objio_seg->mirrors_p1 /
361 objio_seg->group_width;
362 } else {
363 objio_seg->group_width = layout.olo_map.odm_num_comps /
364 objio_seg->mirrors_p1;
365 objio_seg->group_depth = -1;
366 objio_seg->group_count = 1;
367 } 272 }
368 273 /* pnfs_osd_xdr_decode_layout_comp returns false on error */
369 /* Cache this calculation it will hit for every page */ 274 if (unlikely(err))
370 objio_seg->max_io_size = (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - 275 goto err;
371 objio_seg->stripe_unit) *
372 objio_seg->group_width;
373 276
374 *outp = &objio_seg->lseg; 277 *outp = &objio_seg->lseg;
375 return 0; 278 return 0;
@@ -386,43 +289,63 @@ void objio_free_lseg(struct pnfs_layout_segment *lseg)
386 int i; 289 int i;
387 struct objio_segment *objio_seg = OBJIO_LSEG(lseg); 290 struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
388 291
389 for (i = 0; i < objio_seg->num_comps; i++) { 292 for (i = 0; i < objio_seg->oc.numdevs; i++) {
390 if (!objio_seg->ods[i]) 293 struct ore_dev *od = objio_seg->oc.ods[i];
294 struct objio_dev_ent *ode;
295
296 if (!od)
391 break; 297 break;
392 nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node); 298 ode = container_of(od, typeof(*ode), od);
299 nfs4_put_deviceid_node(&ode->id_node);
393 } 300 }
394 kfree(objio_seg); 301 kfree(objio_seg);
395} 302}
396 303
397int objio_alloc_io_state(struct pnfs_layout_segment *lseg, 304static int
398 struct objlayout_io_state **outp, 305objio_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, bool is_reading,
399 gfp_t gfp_flags) 306 struct pnfs_layout_segment *lseg, struct page **pages, unsigned pgbase,
307 loff_t offset, size_t count, void *rpcdata, gfp_t gfp_flags,
308 struct objio_state **outp)
400{ 309{
401 struct objio_segment *objio_seg = OBJIO_LSEG(lseg); 310 struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
402 struct objio_state *ios; 311 struct ore_io_state *ios;
403 const unsigned first_size = sizeof(*ios) + 312 int ret;
404 objio_seg->num_comps * sizeof(ios->per_dev[0]); 313 struct __alloc_objio_state {
405 const unsigned sec_size = objio_seg->num_comps * 314 struct objio_state objios;
406 sizeof(ios->ol_state.ioerrs[0]); 315 struct pnfs_osd_ioerr ioerrs[objio_seg->oc.numdevs];
407 316 } *aos;
408 ios = kzalloc(first_size + sec_size, gfp_flags); 317
409 if (unlikely(!ios)) 318 aos = kzalloc(sizeof(*aos), gfp_flags);
319 if (unlikely(!aos))
410 return -ENOMEM; 320 return -ENOMEM;
411 321
412 ios->layout = objio_seg; 322 objlayout_init_ioerrs(&aos->objios.oir, objio_seg->oc.numdevs,
413 ios->ol_state.ioerrs = ((void *)ios) + first_size; 323 aos->ioerrs, rpcdata, pnfs_layout_type);
414 ios->ol_state.num_comps = objio_seg->num_comps;
415 324
416 *outp = &ios->ol_state; 325 ret = ore_get_rw_state(&objio_seg->layout, &objio_seg->oc, is_reading,
326 offset, count, &ios);
327 if (unlikely(ret)) {
328 kfree(aos);
329 return ret;
330 }
331
332 ios->pages = pages;
333 ios->pgbase = pgbase;
334 ios->private = aos;
335 BUG_ON(ios->nr_pages > (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT);
336
337 aos->objios.sync = 0;
338 aos->objios.ios = ios;
339 *outp = &aos->objios;
417 return 0; 340 return 0;
418} 341}
419 342
420void objio_free_io_state(struct objlayout_io_state *ol_state) 343void objio_free_result(struct objlayout_io_res *oir)
421{ 344{
422 struct objio_state *ios = container_of(ol_state, struct objio_state, 345 struct objio_state *objios = container_of(oir, struct objio_state, oir);
423 ol_state);
424 346
425 kfree(ios); 347 ore_put_io_state(objios->ios);
348 kfree(objios);
426} 349}
427 350
428enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) 351enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
@@ -455,539 +378,152 @@ enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
455 } 378 }
456} 379}
457 380
458static void _clear_bio(struct bio *bio) 381static void __on_dev_error(struct ore_io_state *ios,
382 struct ore_dev *od, unsigned dev_index, enum osd_err_priority oep,
383 u64 dev_offset, u64 dev_len)
459{ 384{
460 struct bio_vec *bv; 385 struct objio_state *objios = ios->private;
461 unsigned i; 386 struct pnfs_osd_objid pooid;
462 387 struct objio_dev_ent *ode = container_of(od, typeof(*ode), od);
463 __bio_for_each_segment(bv, bio, i, 0) { 388 /* FIXME: what to do with more-then-one-group layouts. We need to
464 unsigned this_count = bv->bv_len; 389 * translate from ore_io_state index to oc->comps index
465 390 */
466 if (likely(PAGE_SIZE == this_count)) 391 unsigned comp = dev_index;
467 clear_highpage(bv->bv_page);
468 else
469 zero_user(bv->bv_page, bv->bv_offset, this_count);
470 }
471}
472
473static int _io_check(struct objio_state *ios, bool is_write)
474{
475 enum osd_err_priority oep = OSD_ERR_PRI_NO_ERROR;
476 int lin_ret = 0;
477 int i;
478
479 for (i = 0; i < ios->numdevs; i++) {
480 struct osd_sense_info osi;
481 struct osd_request *or = ios->per_dev[i].or;
482 int ret;
483
484 if (!or)
485 continue;
486 392
487 ret = osd_req_decode_sense(or, &osi); 393 pooid.oid_device_id = ode->id_node.deviceid;
488 if (likely(!ret)) 394 pooid.oid_partition_id = ios->oc->comps[comp].obj.partition;
489 continue; 395 pooid.oid_object_id = ios->oc->comps[comp].obj.id;
490 396
491 if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { 397 objlayout_io_set_result(&objios->oir, comp,
492 /* start read offset passed endof file */ 398 &pooid, osd_pri_2_pnfs_err(oep),
493 BUG_ON(is_write); 399 dev_offset, dev_len, !ios->reading);
494 _clear_bio(ios->per_dev[i].bio);
495 dprintk("%s: start read offset passed end of file "
496 "offset=0x%llx, length=0x%lx\n", __func__,
497 _LLU(ios->per_dev[i].offset),
498 ios->per_dev[i].length);
499
500 continue; /* we recovered */
501 }
502 objlayout_io_set_result(&ios->ol_state, i,
503 &ios->layout->comps[i].oc_object_id,
504 osd_pri_2_pnfs_err(osi.osd_err_pri),
505 ios->per_dev[i].offset,
506 ios->per_dev[i].length,
507 is_write);
508
509 if (osi.osd_err_pri >= oep) {
510 oep = osi.osd_err_pri;
511 lin_ret = ret;
512 }
513 }
514
515 return lin_ret;
516}
517
518/*
519 * Common IO state helpers.
520 */
521static void _io_free(struct objio_state *ios)
522{
523 unsigned i;
524
525 for (i = 0; i < ios->numdevs; i++) {
526 struct _objio_per_comp *per_dev = &ios->per_dev[i];
527
528 if (per_dev->or) {
529 osd_end_request(per_dev->or);
530 per_dev->or = NULL;
531 }
532
533 if (per_dev->bio) {
534 bio_put(per_dev->bio);
535 per_dev->bio = NULL;
536 }
537 }
538}
539
540struct osd_dev *_io_od(struct objio_state *ios, unsigned dev)
541{
542 unsigned min_dev = ios->layout->comps_index;
543 unsigned max_dev = min_dev + ios->layout->num_comps;
544
545 BUG_ON(dev < min_dev || max_dev <= dev);
546 return ios->layout->ods[dev - min_dev]->od;
547}
548
549struct _striping_info {
550 u64 obj_offset;
551 u64 group_length;
552 unsigned dev;
553 unsigned unit_off;
554};
555
556static void _calc_stripe_info(struct objio_state *ios, u64 file_offset,
557 struct _striping_info *si)
558{
559 u32 stripe_unit = ios->layout->stripe_unit;
560 u32 group_width = ios->layout->group_width;
561 u64 group_depth = ios->layout->group_depth;
562 u32 U = stripe_unit * group_width;
563
564 u64 T = U * group_depth;
565 u64 S = T * ios->layout->group_count;
566 u64 M = div64_u64(file_offset, S);
567
568 /*
569 G = (L - (M * S)) / T
570 H = (L - (M * S)) % T
571 */
572 u64 LmodU = file_offset - M * S;
573 u32 G = div64_u64(LmodU, T);
574 u64 H = LmodU - G * T;
575
576 u32 N = div_u64(H, U);
577
578 div_u64_rem(file_offset, stripe_unit, &si->unit_off);
579 si->obj_offset = si->unit_off + (N * stripe_unit) +
580 (M * group_depth * stripe_unit);
581
582 /* "H - (N * U)" is just "H % U" so it's bound to u32 */
583 si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width;
584 si->dev *= ios->layout->mirrors_p1;
585
586 si->group_length = T - H;
587}
588
589static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg,
590 unsigned pgbase, struct _objio_per_comp *per_dev, int len,
591 gfp_t gfp_flags)
592{
593 unsigned pg = *cur_pg;
594 int cur_len = len;
595 struct request_queue *q =
596 osd_request_queue(_io_od(ios, per_dev->dev));
597
598 if (per_dev->bio == NULL) {
599 unsigned pages_in_stripe = ios->layout->group_width *
600 (ios->layout->stripe_unit / PAGE_SIZE);
601 unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) /
602 ios->layout->group_width;
603
604 if (BIO_MAX_PAGES_KMALLOC < bio_size)
605 bio_size = BIO_MAX_PAGES_KMALLOC;
606
607 per_dev->bio = bio_kmalloc(gfp_flags, bio_size);
608 if (unlikely(!per_dev->bio)) {
609 dprintk("Faild to allocate BIO size=%u\n", bio_size);
610 return -ENOMEM;
611 }
612 }
613
614 while (cur_len > 0) {
615 unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
616 unsigned added_len;
617
618 BUG_ON(ios->ol_state.nr_pages <= pg);
619 cur_len -= pglen;
620
621 added_len = bio_add_pc_page(q, per_dev->bio,
622 ios->ol_state.pages[pg], pglen, pgbase);
623 if (unlikely(pglen != added_len))
624 return -ENOMEM;
625 pgbase = 0;
626 ++pg;
627 }
628 BUG_ON(cur_len);
629
630 per_dev->length += len;
631 *cur_pg = pg;
632 return 0;
633}
634
635static int _prepare_one_group(struct objio_state *ios, u64 length,
636 struct _striping_info *si, unsigned *last_pg,
637 gfp_t gfp_flags)
638{
639 unsigned stripe_unit = ios->layout->stripe_unit;
640 unsigned mirrors_p1 = ios->layout->mirrors_p1;
641 unsigned devs_in_group = ios->layout->group_width * mirrors_p1;
642 unsigned dev = si->dev;
643 unsigned first_dev = dev - (dev % devs_in_group);
644 unsigned max_comp = ios->numdevs ? ios->numdevs - mirrors_p1 : 0;
645 unsigned cur_pg = *last_pg;
646 int ret = 0;
647
648 while (length) {
649 struct _objio_per_comp *per_dev = &ios->per_dev[dev - first_dev];
650 unsigned cur_len, page_off = 0;
651
652 if (!per_dev->length) {
653 per_dev->dev = dev;
654 if (dev < si->dev) {
655 per_dev->offset = si->obj_offset + stripe_unit -
656 si->unit_off;
657 cur_len = stripe_unit;
658 } else if (dev == si->dev) {
659 per_dev->offset = si->obj_offset;
660 cur_len = stripe_unit - si->unit_off;
661 page_off = si->unit_off & ~PAGE_MASK;
662 BUG_ON(page_off &&
663 (page_off != ios->ol_state.pgbase));
664 } else { /* dev > si->dev */
665 per_dev->offset = si->obj_offset - si->unit_off;
666 cur_len = stripe_unit;
667 }
668
669 if (max_comp < dev - first_dev)
670 max_comp = dev - first_dev;
671 } else {
672 cur_len = stripe_unit;
673 }
674 if (cur_len >= length)
675 cur_len = length;
676
677 ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
678 cur_len, gfp_flags);
679 if (unlikely(ret))
680 goto out;
681
682 dev += mirrors_p1;
683 dev = (dev % devs_in_group) + first_dev;
684
685 length -= cur_len;
686 ios->length += cur_len;
687 }
688out:
689 ios->numdevs = max_comp + mirrors_p1;
690 *last_pg = cur_pg;
691 return ret;
692}
693
694static int _io_rw_pagelist(struct objio_state *ios, gfp_t gfp_flags)
695{
696 u64 length = ios->ol_state.count;
697 u64 offset = ios->ol_state.offset;
698 struct _striping_info si;
699 unsigned last_pg = 0;
700 int ret = 0;
701
702 while (length) {
703 _calc_stripe_info(ios, offset, &si);
704
705 if (length < si.group_length)
706 si.group_length = length;
707
708 ret = _prepare_one_group(ios, si.group_length, &si, &last_pg, gfp_flags);
709 if (unlikely(ret))
710 goto out;
711
712 offset += si.group_length;
713 length -= si.group_length;
714 }
715
716out:
717 if (!ios->length)
718 return ret;
719
720 return 0;
721}
722
723static ssize_t _sync_done(struct objio_state *ios)
724{
725 struct completion *waiting = ios->private;
726
727 complete(waiting);
728 return 0;
729}
730
731static void _last_io(struct kref *kref)
732{
733 struct objio_state *ios = container_of(kref, struct objio_state, kref);
734
735 ios->done(ios);
736}
737
738static void _done_io(struct osd_request *or, void *p)
739{
740 struct objio_state *ios = p;
741
742 kref_put(&ios->kref, _last_io);
743}
744
745static ssize_t _io_exec(struct objio_state *ios)
746{
747 DECLARE_COMPLETION_ONSTACK(wait);
748 ssize_t status = 0; /* sync status */
749 unsigned i;
750 objio_done_fn saved_done_fn = ios->done;
751 bool sync = ios->ol_state.sync;
752
753 if (sync) {
754 ios->done = _sync_done;
755 ios->private = &wait;
756 }
757
758 kref_init(&ios->kref);
759
760 for (i = 0; i < ios->numdevs; i++) {
761 struct osd_request *or = ios->per_dev[i].or;
762
763 if (!or)
764 continue;
765
766 kref_get(&ios->kref);
767 osd_execute_request_async(or, _done_io, ios);
768 }
769
770 kref_put(&ios->kref, _last_io);
771
772 if (sync) {
773 wait_for_completion(&wait);
774 status = saved_done_fn(ios);
775 }
776
777 return status;
778} 400}
779 401
780/* 402/*
781 * read 403 * read
782 */ 404 */
783static ssize_t _read_done(struct objio_state *ios) 405static void _read_done(struct ore_io_state *ios, void *private)
784{ 406{
407 struct objio_state *objios = private;
785 ssize_t status; 408 ssize_t status;
786 int ret = _io_check(ios, false); 409 int ret = ore_check_io(ios, &__on_dev_error);
787 410
788 _io_free(ios); 411 /* FIXME: _io_free(ios) can we dealocate the libosd resources; */
789 412
790 if (likely(!ret)) 413 if (likely(!ret))
791 status = ios->length; 414 status = ios->length;
792 else 415 else
793 status = ret; 416 status = ret;
794 417
795 objlayout_read_done(&ios->ol_state, status, ios->ol_state.sync); 418 objlayout_read_done(&objios->oir, status, objios->sync);
796 return status;
797} 419}
798 420
799static int _read_mirrors(struct objio_state *ios, unsigned cur_comp) 421int objio_read_pagelist(struct nfs_read_data *rdata)
800{ 422{
801 struct osd_request *or = NULL; 423 struct objio_state *objios;
802 struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp];
803 unsigned dev = per_dev->dev;
804 struct pnfs_osd_object_cred *cred =
805 &ios->layout->comps[cur_comp];
806 struct osd_obj_id obj = {
807 .partition = cred->oc_object_id.oid_partition_id,
808 .id = cred->oc_object_id.oid_object_id,
809 };
810 int ret; 424 int ret;
811 425
812 or = osd_start_request(_io_od(ios, dev), GFP_KERNEL); 426 ret = objio_alloc_io_state(NFS_I(rdata->inode)->layout, true,
813 if (unlikely(!or)) { 427 rdata->lseg, rdata->args.pages, rdata->args.pgbase,
814 ret = -ENOMEM; 428 rdata->args.offset, rdata->args.count, rdata,
815 goto err; 429 GFP_KERNEL, &objios);
816 }
817 per_dev->or = or;
818
819 osd_req_read(or, &obj, per_dev->offset, per_dev->bio, per_dev->length);
820
821 ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL);
822 if (ret) {
823 dprintk("%s: Faild to osd_finalize_request() => %d\n",
824 __func__, ret);
825 goto err;
826 }
827
828 dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n",
829 __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset),
830 per_dev->length);
831
832err:
833 return ret;
834}
835
836static ssize_t _read_exec(struct objio_state *ios)
837{
838 unsigned i;
839 int ret;
840
841 for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
842 if (!ios->per_dev[i].length)
843 continue;
844 ret = _read_mirrors(ios, i);
845 if (unlikely(ret))
846 goto err;
847 }
848
849 ios->done = _read_done;
850 return _io_exec(ios); /* In sync mode exec returns the io status */
851
852err:
853 _io_free(ios);
854 return ret;
855}
856
857ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state)
858{
859 struct objio_state *ios = container_of(ol_state, struct objio_state,
860 ol_state);
861 int ret;
862
863 ret = _io_rw_pagelist(ios, GFP_KERNEL);
864 if (unlikely(ret)) 430 if (unlikely(ret))
865 return ret; 431 return ret;
866 432
867 return _read_exec(ios); 433 objios->ios->done = _read_done;
434 dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
435 rdata->args.offset, rdata->args.count);
436 return ore_read(objios->ios);
868} 437}
869 438
870/* 439/*
871 * write 440 * write
872 */ 441 */
873static ssize_t _write_done(struct objio_state *ios) 442static void _write_done(struct ore_io_state *ios, void *private)
874{ 443{
444 struct objio_state *objios = private;
875 ssize_t status; 445 ssize_t status;
876 int ret = _io_check(ios, true); 446 int ret = ore_check_io(ios, &__on_dev_error);
877 447
878 _io_free(ios); 448 /* FIXME: _io_free(ios) can we dealocate the libosd resources; */
879 449
880 if (likely(!ret)) { 450 if (likely(!ret)) {
881 /* FIXME: should be based on the OSD's persistence model 451 /* FIXME: should be based on the OSD's persistence model
882 * See OSD2r05 Section 4.13 Data persistence model */ 452 * See OSD2r05 Section 4.13 Data persistence model */
883 ios->ol_state.committed = NFS_FILE_SYNC; 453 objios->oir.committed = NFS_FILE_SYNC;
884 status = ios->length; 454 status = ios->length;
885 } else { 455 } else {
886 status = ret; 456 status = ret;
887 } 457 }
888 458
889 objlayout_write_done(&ios->ol_state, status, ios->ol_state.sync); 459 objlayout_write_done(&objios->oir, status, objios->sync);
890 return status;
891} 460}
892 461
893static int _write_mirrors(struct objio_state *ios, unsigned cur_comp) 462static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
894{ 463{
895 struct _objio_per_comp *master_dev = &ios->per_dev[cur_comp]; 464 struct objio_state *objios = priv;
896 unsigned dev = ios->per_dev[cur_comp].dev; 465 struct nfs_write_data *wdata = objios->oir.rpcdata;
897 unsigned last_comp = cur_comp + ios->layout->mirrors_p1; 466 pgoff_t index = offset / PAGE_SIZE;
898 int ret; 467 struct page *page = find_get_page(wdata->inode->i_mapping, index);
899
900 for (; cur_comp < last_comp; ++cur_comp, ++dev) {
901 struct osd_request *or = NULL;
902 struct pnfs_osd_object_cred *cred =
903 &ios->layout->comps[cur_comp];
904 struct osd_obj_id obj = {
905 .partition = cred->oc_object_id.oid_partition_id,
906 .id = cred->oc_object_id.oid_object_id,
907 };
908 struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp];
909 struct bio *bio;
910
911 or = osd_start_request(_io_od(ios, dev), GFP_NOFS);
912 if (unlikely(!or)) {
913 ret = -ENOMEM;
914 goto err;
915 }
916 per_dev->or = or;
917
918 if (per_dev != master_dev) {
919 bio = bio_kmalloc(GFP_NOFS,
920 master_dev->bio->bi_max_vecs);
921 if (unlikely(!bio)) {
922 dprintk("Faild to allocate BIO size=%u\n",
923 master_dev->bio->bi_max_vecs);
924 ret = -ENOMEM;
925 goto err;
926 }
927
928 __bio_clone(bio, master_dev->bio);
929 bio->bi_bdev = NULL;
930 bio->bi_next = NULL;
931 per_dev->bio = bio;
932 per_dev->dev = dev;
933 per_dev->length = master_dev->length;
934 per_dev->offset = master_dev->offset;
935 } else {
936 bio = master_dev->bio;
937 bio->bi_rw |= REQ_WRITE;
938 }
939
940 osd_req_write(or, &obj, per_dev->offset, bio, per_dev->length);
941 468
942 ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL); 469 if (!page) {
943 if (ret) { 470 page = find_or_create_page(wdata->inode->i_mapping,
944 dprintk("%s: Faild to osd_finalize_request() => %d\n", 471 index, GFP_NOFS);
945 __func__, ret); 472 if (unlikely(!page)) {
946 goto err; 473 dprintk("%s: grab_cache_page Failed index=0x%lx\n",
474 __func__, index);
475 return NULL;
947 } 476 }
948 477 unlock_page(page);
949 dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n",
950 __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset),
951 per_dev->length);
952 } 478 }
479 if (PageDirty(page) || PageWriteback(page))
480 *uptodate = true;
481 else
482 *uptodate = PageUptodate(page);
483 dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate);
484 return page;
485}
953 486
954err: 487static void __r4w_put_page(void *priv, struct page *page)
955 return ret; 488{
489 dprintk("%s: index=0x%lx\n", __func__, page->index);
490 page_cache_release(page);
491 return;
956} 492}
957 493
958static ssize_t _write_exec(struct objio_state *ios) 494static const struct _ore_r4w_op _r4w_op = {
495 .get_page = &__r4w_get_page,
496 .put_page = &__r4w_put_page,
497};
498
499int objio_write_pagelist(struct nfs_write_data *wdata, int how)
959{ 500{
960 unsigned i; 501 struct objio_state *objios;
961 int ret; 502 int ret;
962 503
963 for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { 504 ret = objio_alloc_io_state(NFS_I(wdata->inode)->layout, false,
964 if (!ios->per_dev[i].length) 505 wdata->lseg, wdata->args.pages, wdata->args.pgbase,
965 continue; 506 wdata->args.offset, wdata->args.count, wdata, GFP_NOFS,
966 ret = _write_mirrors(ios, i); 507 &objios);
967 if (unlikely(ret)) 508 if (unlikely(ret))
968 goto err; 509 return ret;
969 }
970
971 ios->done = _write_done;
972 return _io_exec(ios); /* In sync mode exec returns the io->status */
973 510
974err: 511 objios->sync = 0 != (how & FLUSH_SYNC);
975 _io_free(ios); 512 objios->ios->r4w = &_r4w_op;
976 return ret;
977}
978 513
979ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, bool stable) 514 if (!objios->sync)
980{ 515 objios->ios->done = _write_done;
981 struct objio_state *ios = container_of(ol_state, struct objio_state,
982 ol_state);
983 int ret;
984 516
985 /* TODO: ios->stable = stable; */ 517 dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
986 ret = _io_rw_pagelist(ios, GFP_NOFS); 518 wdata->args.offset, wdata->args.count);
519 ret = ore_write(objios->ios);
987 if (unlikely(ret)) 520 if (unlikely(ret))
988 return ret; 521 return ret;
989 522
990 return _write_exec(ios); 523 if (objios->sync)
524 _write_done(objios->ios, objios);
525
526 return 0;
991} 527}
992 528
993static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, 529static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
@@ -997,7 +533,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
997 return false; 533 return false;
998 534
999 return pgio->pg_count + req->wb_bytes <= 535 return pgio->pg_count + req->wb_bytes <=
1000 OBJIO_LSEG(pgio->pg_lseg)->max_io_size; 536 OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
1001} 537}
1002 538
1003static const struct nfs_pageio_ops objio_pg_read_ops = { 539static const struct nfs_pageio_ops objio_pg_read_ops = {
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index 1d06f8e2adea..72074e3a04f9 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -156,77 +156,39 @@ last_byte_offset(u64 start, u64 len)
156 return end > start ? end - 1 : NFS4_MAX_UINT64; 156 return end > start ? end - 1 : NFS4_MAX_UINT64;
157} 157}
158 158
159static struct objlayout_io_state * 159void _fix_verify_io_params(struct pnfs_layout_segment *lseg,
160objlayout_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, 160 struct page ***p_pages, unsigned *p_pgbase,
161 struct page **pages, 161 u64 offset, unsigned long count)
162 unsigned pgbase,
163 loff_t offset,
164 size_t count,
165 struct pnfs_layout_segment *lseg,
166 void *rpcdata,
167 gfp_t gfp_flags)
168{ 162{
169 struct objlayout_io_state *state;
170 u64 lseg_end_offset; 163 u64 lseg_end_offset;
171 164
172 dprintk("%s: allocating io_state\n", __func__);
173 if (objio_alloc_io_state(lseg, &state, gfp_flags))
174 return NULL;
175
176 BUG_ON(offset < lseg->pls_range.offset); 165 BUG_ON(offset < lseg->pls_range.offset);
177 lseg_end_offset = end_offset(lseg->pls_range.offset, 166 lseg_end_offset = end_offset(lseg->pls_range.offset,
178 lseg->pls_range.length); 167 lseg->pls_range.length);
179 BUG_ON(offset >= lseg_end_offset); 168 BUG_ON(offset >= lseg_end_offset);
180 if (offset + count > lseg_end_offset) { 169 WARN_ON(offset + count > lseg_end_offset);
181 count = lseg->pls_range.length -
182 (offset - lseg->pls_range.offset);
183 dprintk("%s: truncated count %Zd\n", __func__, count);
184 }
185 170
186 if (pgbase > PAGE_SIZE) { 171 if (*p_pgbase > PAGE_SIZE) {
187 pages += pgbase >> PAGE_SHIFT; 172 dprintk("%s: pgbase(0x%x) > PAGE_SIZE\n", __func__, *p_pgbase);
188 pgbase &= ~PAGE_MASK; 173 *p_pages += *p_pgbase >> PAGE_SHIFT;
174 *p_pgbase &= ~PAGE_MASK;
189 } 175 }
190
191 INIT_LIST_HEAD(&state->err_list);
192 state->lseg = lseg;
193 state->rpcdata = rpcdata;
194 state->pages = pages;
195 state->pgbase = pgbase;
196 state->nr_pages = (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
197 state->offset = offset;
198 state->count = count;
199 state->sync = 0;
200
201 return state;
202}
203
204static void
205objlayout_free_io_state(struct objlayout_io_state *state)
206{
207 dprintk("%s: freeing io_state\n", __func__);
208 if (unlikely(!state))
209 return;
210
211 objio_free_io_state(state);
212} 176}
213 177
214/* 178/*
215 * I/O done common code 179 * I/O done common code
216 */ 180 */
217static void 181static void
218objlayout_iodone(struct objlayout_io_state *state) 182objlayout_iodone(struct objlayout_io_res *oir)
219{ 183{
220 dprintk("%s: state %p status\n", __func__, state); 184 if (likely(oir->status >= 0)) {
221 185 objio_free_result(oir);
222 if (likely(state->status >= 0)) {
223 objlayout_free_io_state(state);
224 } else { 186 } else {
225 struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout); 187 struct objlayout *objlay = oir->objlay;
226 188
227 spin_lock(&objlay->lock); 189 spin_lock(&objlay->lock);
228 objlay->delta_space_valid = OBJ_DSU_INVALID; 190 objlay->delta_space_valid = OBJ_DSU_INVALID;
229 list_add(&objlay->err_list, &state->err_list); 191 list_add(&objlay->err_list, &oir->err_list);
230 spin_unlock(&objlay->lock); 192 spin_unlock(&objlay->lock);
231 } 193 }
232} 194}
@@ -238,13 +200,13 @@ objlayout_iodone(struct objlayout_io_state *state)
238 * the error for later reporting at layout-return. 200 * the error for later reporting at layout-return.
239 */ 201 */
240void 202void
241objlayout_io_set_result(struct objlayout_io_state *state, unsigned index, 203objlayout_io_set_result(struct objlayout_io_res *oir, unsigned index,
242 struct pnfs_osd_objid *pooid, int osd_error, 204 struct pnfs_osd_objid *pooid, int osd_error,
243 u64 offset, u64 length, bool is_write) 205 u64 offset, u64 length, bool is_write)
244{ 206{
245 struct pnfs_osd_ioerr *ioerr = &state->ioerrs[index]; 207 struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[index];
246 208
247 BUG_ON(index >= state->num_comps); 209 BUG_ON(index >= oir->num_comps);
248 if (osd_error) { 210 if (osd_error) {
249 ioerr->oer_component = *pooid; 211 ioerr->oer_component = *pooid;
250 ioerr->oer_comp_offset = offset; 212 ioerr->oer_comp_offset = offset;
@@ -285,21 +247,18 @@ static void _rpc_read_complete(struct work_struct *work)
285} 247}
286 248
287void 249void
288objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync) 250objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
289{ 251{
290 int eof = state->eof; 252 struct nfs_read_data *rdata = oir->rpcdata;
291 struct nfs_read_data *rdata;
292 253
293 state->status = status; 254 oir->status = rdata->task.tk_status = status;
294 dprintk("%s: Begin status=%zd eof=%d\n", __func__, status, eof); 255 if (status >= 0)
295 rdata = state->rpcdata;
296 rdata->task.tk_status = status;
297 if (status >= 0) {
298 rdata->res.count = status; 256 rdata->res.count = status;
299 rdata->res.eof = eof; 257 objlayout_iodone(oir);
300 } 258 /* must not use oir after this point */
301 objlayout_iodone(state); 259
302 /* must not use state after this point */ 260 dprintk("%s: Return status=%zd eof=%d sync=%d\n", __func__,
261 status, rdata->res.eof, sync);
303 262
304 if (sync) 263 if (sync)
305 pnfs_ld_read_done(rdata); 264 pnfs_ld_read_done(rdata);
@@ -317,40 +276,36 @@ objlayout_read_pagelist(struct nfs_read_data *rdata)
317{ 276{
318 loff_t offset = rdata->args.offset; 277 loff_t offset = rdata->args.offset;
319 size_t count = rdata->args.count; 278 size_t count = rdata->args.count;
320 struct objlayout_io_state *state; 279 int err;
321 ssize_t status = 0;
322 loff_t eof; 280 loff_t eof;
323 281
324 dprintk("%s: Begin inode %p offset %llu count %d\n",
325 __func__, rdata->inode, offset, (int)count);
326
327 eof = i_size_read(rdata->inode); 282 eof = i_size_read(rdata->inode);
328 if (unlikely(offset + count > eof)) { 283 if (unlikely(offset + count > eof)) {
329 if (offset >= eof) { 284 if (offset >= eof) {
330 status = 0; 285 err = 0;
331 rdata->res.count = 0; 286 rdata->res.count = 0;
332 rdata->res.eof = 1; 287 rdata->res.eof = 1;
288 /*FIXME: do we need to call pnfs_ld_read_done() */
333 goto out; 289 goto out;
334 } 290 }
335 count = eof - offset; 291 count = eof - offset;
336 } 292 }
337 293
338 state = objlayout_alloc_io_state(NFS_I(rdata->inode)->layout, 294 rdata->res.eof = (offset + count) >= eof;
339 rdata->args.pages, rdata->args.pgbase, 295 _fix_verify_io_params(rdata->lseg, &rdata->args.pages,
340 offset, count, 296 &rdata->args.pgbase,
341 rdata->lseg, rdata, 297 rdata->args.offset, rdata->args.count);
342 GFP_KERNEL);
343 if (unlikely(!state)) {
344 status = -ENOMEM;
345 goto out;
346 }
347 298
348 state->eof = state->offset + state->count >= eof; 299 dprintk("%s: inode(%lx) offset 0x%llx count 0x%Zx eof=%d\n",
300 __func__, rdata->inode->i_ino, offset, count, rdata->res.eof);
349 301
350 status = objio_read_pagelist(state); 302 err = objio_read_pagelist(rdata);
351 out: 303 out:
352 dprintk("%s: Return status %Zd\n", __func__, status); 304 if (unlikely(err)) {
353 rdata->pnfs_error = status; 305 rdata->pnfs_error = err;
306 dprintk("%s: Returned Error %d\n", __func__, err);
307 return PNFS_NOT_ATTEMPTED;
308 }
354 return PNFS_ATTEMPTED; 309 return PNFS_ATTEMPTED;
355} 310}
356 311
@@ -371,26 +326,20 @@ static void _rpc_write_complete(struct work_struct *work)
371} 326}
372 327
373void 328void
374objlayout_write_done(struct objlayout_io_state *state, ssize_t status, 329objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
375 bool sync)
376{ 330{
377 struct nfs_write_data *wdata; 331 struct nfs_write_data *wdata = oir->rpcdata;
378 332
379 dprintk("%s: Begin\n", __func__); 333 oir->status = wdata->task.tk_status = status;
380 wdata = state->rpcdata;
381 state->status = status;
382 wdata->task.tk_status = status;
383 if (status >= 0) { 334 if (status >= 0) {
384 wdata->res.count = status; 335 wdata->res.count = status;
385 wdata->verf.committed = state->committed; 336 wdata->verf.committed = oir->committed;
386 dprintk("%s: Return status %d committed %d\n", 337 }
387 __func__, wdata->task.tk_status, 338 objlayout_iodone(oir);
388 wdata->verf.committed); 339 /* must not use oir after this point */
389 } else 340
390 dprintk("%s: Return status %d\n", 341 dprintk("%s: Return status %zd committed %d sync=%d\n", __func__,
391 __func__, wdata->task.tk_status); 342 status, wdata->verf.committed, sync);
392 objlayout_iodone(state);
393 /* must not use state after this point */
394 343
395 if (sync) 344 if (sync)
396 pnfs_ld_write_done(wdata); 345 pnfs_ld_write_done(wdata);
@@ -407,30 +356,18 @@ enum pnfs_try_status
407objlayout_write_pagelist(struct nfs_write_data *wdata, 356objlayout_write_pagelist(struct nfs_write_data *wdata,
408 int how) 357 int how)
409{ 358{
410 struct objlayout_io_state *state; 359 int err;
411 ssize_t status;
412
413 dprintk("%s: Begin inode %p offset %llu count %u\n",
414 __func__, wdata->inode, wdata->args.offset, wdata->args.count);
415
416 state = objlayout_alloc_io_state(NFS_I(wdata->inode)->layout,
417 wdata->args.pages,
418 wdata->args.pgbase,
419 wdata->args.offset,
420 wdata->args.count,
421 wdata->lseg, wdata,
422 GFP_NOFS);
423 if (unlikely(!state)) {
424 status = -ENOMEM;
425 goto out;
426 }
427 360
428 state->sync = how & FLUSH_SYNC; 361 _fix_verify_io_params(wdata->lseg, &wdata->args.pages,
362 &wdata->args.pgbase,
363 wdata->args.offset, wdata->args.count);
429 364
430 status = objio_write_pagelist(state, how & FLUSH_STABLE); 365 err = objio_write_pagelist(wdata, how);
431 out: 366 if (unlikely(err)) {
432 dprintk("%s: Return status %Zd\n", __func__, status); 367 wdata->pnfs_error = err;
433 wdata->pnfs_error = status; 368 dprintk("%s: Returned Error %d\n", __func__, err);
369 return PNFS_NOT_ATTEMPTED;
370 }
434 return PNFS_ATTEMPTED; 371 return PNFS_ATTEMPTED;
435} 372}
436 373
@@ -537,14 +474,14 @@ merge_ioerr(struct pnfs_osd_ioerr *dest_err,
537static void 474static void
538encode_accumulated_error(struct objlayout *objlay, __be32 *p) 475encode_accumulated_error(struct objlayout *objlay, __be32 *p)
539{ 476{
540 struct objlayout_io_state *state, *tmp; 477 struct objlayout_io_res *oir, *tmp;
541 struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0}; 478 struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0};
542 479
543 list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { 480 list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) {
544 unsigned i; 481 unsigned i;
545 482
546 for (i = 0; i < state->num_comps; i++) { 483 for (i = 0; i < oir->num_comps; i++) {
547 struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; 484 struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i];
548 485
549 if (!ioerr->oer_errno) 486 if (!ioerr->oer_errno)
550 continue; 487 continue;
@@ -563,8 +500,8 @@ encode_accumulated_error(struct objlayout *objlay, __be32 *p)
563 500
564 merge_ioerr(&accumulated_err, ioerr); 501 merge_ioerr(&accumulated_err, ioerr);
565 } 502 }
566 list_del(&state->err_list); 503 list_del(&oir->err_list);
567 objlayout_free_io_state(state); 504 objio_free_result(oir);
568 } 505 }
569 506
570 pnfs_osd_xdr_encode_ioerr(p, &accumulated_err); 507 pnfs_osd_xdr_encode_ioerr(p, &accumulated_err);
@@ -576,7 +513,7 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
576 const struct nfs4_layoutreturn_args *args) 513 const struct nfs4_layoutreturn_args *args)
577{ 514{
578 struct objlayout *objlay = OBJLAYOUT(pnfslay); 515 struct objlayout *objlay = OBJLAYOUT(pnfslay);
579 struct objlayout_io_state *state, *tmp; 516 struct objlayout_io_res *oir, *tmp;
580 __be32 *start; 517 __be32 *start;
581 518
582 dprintk("%s: Begin\n", __func__); 519 dprintk("%s: Begin\n", __func__);
@@ -585,13 +522,13 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
585 522
586 spin_lock(&objlay->lock); 523 spin_lock(&objlay->lock);
587 524
588 list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { 525 list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) {
589 __be32 *last_xdr = NULL, *p; 526 __be32 *last_xdr = NULL, *p;
590 unsigned i; 527 unsigned i;
591 int res = 0; 528 int res = 0;
592 529
593 for (i = 0; i < state->num_comps; i++) { 530 for (i = 0; i < oir->num_comps; i++) {
594 struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; 531 struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i];
595 532
596 if (!ioerr->oer_errno) 533 if (!ioerr->oer_errno)
597 continue; 534 continue;
@@ -615,7 +552,7 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
615 } 552 }
616 553
617 last_xdr = p; 554 last_xdr = p;
618 pnfs_osd_xdr_encode_ioerr(p, &state->ioerrs[i]); 555 pnfs_osd_xdr_encode_ioerr(p, &oir->ioerrs[i]);
619 } 556 }
620 557
621 /* TODO: use xdr_write_pages */ 558 /* TODO: use xdr_write_pages */
@@ -631,8 +568,8 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
631 encode_accumulated_error(objlay, last_xdr); 568 encode_accumulated_error(objlay, last_xdr);
632 goto loop_done; 569 goto loop_done;
633 } 570 }
634 list_del(&state->err_list); 571 list_del(&oir->err_list);
635 objlayout_free_io_state(state); 572 objio_free_result(oir);
636 } 573 }
637loop_done: 574loop_done:
638 spin_unlock(&objlay->lock); 575 spin_unlock(&objlay->lock);
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h
index a8244c8e042d..8ec34727ed21 100644
--- a/fs/nfs/objlayout/objlayout.h
+++ b/fs/nfs/objlayout/objlayout.h
@@ -74,19 +74,11 @@ OBJLAYOUT(struct pnfs_layout_hdr *lo)
74 * per-I/O operation state 74 * per-I/O operation state
75 * embedded in objects provider io_state data structure 75 * embedded in objects provider io_state data structure
76 */ 76 */
77struct objlayout_io_state { 77struct objlayout_io_res {
78 struct pnfs_layout_segment *lseg; 78 struct objlayout *objlay;
79
80 struct page **pages;
81 unsigned pgbase;
82 unsigned nr_pages;
83 unsigned long count;
84 loff_t offset;
85 bool sync;
86 79
87 void *rpcdata; 80 void *rpcdata;
88 int status; /* res */ 81 int status; /* res */
89 int eof; /* res */
90 int committed; /* res */ 82 int committed; /* res */
91 83
92 /* Error reporting (layout_return) */ 84 /* Error reporting (layout_return) */
@@ -100,6 +92,18 @@ struct objlayout_io_state {
100 struct pnfs_osd_ioerr *ioerrs; 92 struct pnfs_osd_ioerr *ioerrs;
101}; 93};
102 94
95static inline
96void objlayout_init_ioerrs(struct objlayout_io_res *oir, unsigned num_comps,
97 struct pnfs_osd_ioerr *ioerrs, void *rpcdata,
98 struct pnfs_layout_hdr *pnfs_layout_type)
99{
100 oir->objlay = OBJLAYOUT(pnfs_layout_type);
101 oir->rpcdata = rpcdata;
102 INIT_LIST_HEAD(&oir->err_list);
103 oir->num_comps = num_comps;
104 oir->ioerrs = ioerrs;
105}
106
103/* 107/*
104 * Raid engine I/O API 108 * Raid engine I/O API
105 */ 109 */
@@ -110,28 +114,24 @@ extern int objio_alloc_lseg(struct pnfs_layout_segment **outp,
110 gfp_t gfp_flags); 114 gfp_t gfp_flags);
111extern void objio_free_lseg(struct pnfs_layout_segment *lseg); 115extern void objio_free_lseg(struct pnfs_layout_segment *lseg);
112 116
113extern int objio_alloc_io_state( 117/* objio_free_result will free these @oir structs recieved from
114 struct pnfs_layout_segment *lseg, 118 * objlayout_{read,write}_done
115 struct objlayout_io_state **outp, 119 */
116 gfp_t gfp_flags); 120extern void objio_free_result(struct objlayout_io_res *oir);
117extern void objio_free_io_state(struct objlayout_io_state *state);
118 121
119extern ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state); 122extern int objio_read_pagelist(struct nfs_read_data *rdata);
120extern ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, 123extern int objio_write_pagelist(struct nfs_write_data *wdata, int how);
121 bool stable);
122 124
123/* 125/*
124 * callback API 126 * callback API
125 */ 127 */
126extern void objlayout_io_set_result(struct objlayout_io_state *state, 128extern void objlayout_io_set_result(struct objlayout_io_res *oir,
127 unsigned index, struct pnfs_osd_objid *pooid, 129 unsigned index, struct pnfs_osd_objid *pooid,
128 int osd_error, u64 offset, u64 length, bool is_write); 130 int osd_error, u64 offset, u64 length, bool is_write);
129 131
130static inline void 132static inline void
131objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used) 133objlayout_add_delta_space_used(struct objlayout *objlay, s64 space_used)
132{ 134{
133 struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout);
134
135 /* If one of the I/Os errored out and the delta_space_used was 135 /* If one of the I/Os errored out and the delta_space_used was
136 * invalid we render the complete report as invalid. Protocol mandate 136 * invalid we render the complete report as invalid. Protocol mandate
137 * the DSU be accurate or not reported. 137 * the DSU be accurate or not reported.
@@ -144,9 +144,9 @@ objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used)
144 spin_unlock(&objlay->lock); 144 spin_unlock(&objlay->lock);
145} 145}
146 146
147extern void objlayout_read_done(struct objlayout_io_state *state, 147extern void objlayout_read_done(struct objlayout_io_res *oir,
148 ssize_t status, bool sync); 148 ssize_t status, bool sync);
149extern void objlayout_write_done(struct objlayout_io_state *state, 149extern void objlayout_write_done(struct objlayout_io_res *oir,
150 ssize_t status, bool sync); 150 ssize_t status, bool sync);
151 151
152extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, 152extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index b60970cc7f1f..0a5ff5c19511 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -41,7 +41,7 @@ nfs_page_free(struct nfs_page *p)
41 41
42/** 42/**
43 * nfs_create_request - Create an NFS read/write request. 43 * nfs_create_request - Create an NFS read/write request.
44 * @file: file descriptor to use 44 * @ctx: open context to use
45 * @inode: inode to which the request is attached 45 * @inode: inode to which the request is attached
46 * @page: page to write 46 * @page: page to write
47 * @offset: starting offset within the page for the write 47 * @offset: starting offset within the page for the write
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index ee73d9a4f700..a2478bc74442 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1443,17 +1443,31 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
1443 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */ 1443 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
1444 data = kzalloc(sizeof(*data), GFP_NOFS); 1444 data = kzalloc(sizeof(*data), GFP_NOFS);
1445 if (!data) { 1445 if (!data) {
1446 mark_inode_dirty_sync(inode);
1447 status = -ENOMEM; 1446 status = -ENOMEM;
1448 goto out; 1447 goto out;
1449 } 1448 }
1450 1449
1450 if (!test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
1451 goto out_free;
1452
1453 if (test_and_set_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags)) {
1454 if (!sync) {
1455 status = -EAGAIN;
1456 goto out_free;
1457 }
1458 status = wait_on_bit_lock(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING,
1459 nfs_wait_bit_killable, TASK_KILLABLE);
1460 if (status)
1461 goto out_free;
1462 }
1463
1451 INIT_LIST_HEAD(&data->lseg_list); 1464 INIT_LIST_HEAD(&data->lseg_list);
1452 spin_lock(&inode->i_lock); 1465 spin_lock(&inode->i_lock);
1453 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { 1466 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
1467 clear_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags);
1454 spin_unlock(&inode->i_lock); 1468 spin_unlock(&inode->i_lock);
1455 kfree(data); 1469 wake_up_bit(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING);
1456 goto out; 1470 goto out_free;
1457 } 1471 }
1458 1472
1459 pnfs_list_write_lseg(inode, &data->lseg_list); 1473 pnfs_list_write_lseg(inode, &data->lseg_list);
@@ -1475,6 +1489,11 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
1475 1489
1476 status = nfs4_proc_layoutcommit(data, sync); 1490 status = nfs4_proc_layoutcommit(data, sync);
1477out: 1491out:
1492 if (status)
1493 mark_inode_dirty_sync(inode);
1478 dprintk("<-- %s status %d\n", __func__, status); 1494 dprintk("<-- %s status %d\n", __func__, status);
1479 return status; 1495 return status;
1496out_free:
1497 kfree(data);
1498 goto out;
1480} 1499}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 2219c88d96b2..b016b8a36399 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1243,7 +1243,6 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1243{ 1243{
1244 struct nfs_writeargs *argp = &data->args; 1244 struct nfs_writeargs *argp = &data->args;
1245 struct nfs_writeres *resp = &data->res; 1245 struct nfs_writeres *resp = &data->res;
1246 struct nfs_server *server = NFS_SERVER(data->inode);
1247 int status; 1246 int status;
1248 1247
1249 dprintk("NFS: %5u nfs_writeback_done (status %d)\n", 1248 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1277,7 +1276,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1277 if (time_before(complain, jiffies)) { 1276 if (time_before(complain, jiffies)) {
1278 dprintk("NFS: faulty NFS server %s:" 1277 dprintk("NFS: faulty NFS server %s:"
1279 " (committed = %d) != (stable = %d)\n", 1278 " (committed = %d) != (stable = %d)\n",
1280 server->nfs_client->cl_hostname, 1279 NFS_SERVER(data->inode)->nfs_client->cl_hostname,
1281 resp->verf->committed, argp->stable); 1280 resp->verf->committed, argp->stable);
1282 complain = jiffies + 300 * HZ; 1281 complain = jiffies + 300 * HZ;
1283 } 1282 }
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index dc5a1bf476b1..52cd976b6099 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -256,6 +256,8 @@ static void nfsd_last_thread(struct svc_serv *serv)
256 nfsd_serv = NULL; 256 nfsd_serv = NULL;
257 nfsd_shutdown(); 257 nfsd_shutdown();
258 258
259 svc_rpcb_cleanup(serv);
260
259 printk(KERN_WARNING "nfsd: last server has exited, flushing export " 261 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
260 "cache\n"); 262 "cache\n");
261 nfsd_export_flush(); 263 nfsd_export_flush();
diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
index 048b59d5b2f0..c70111ebefd4 100644
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -78,6 +78,28 @@ config SQUASHFS_XZ
78 78
79 If unsure, say N. 79 If unsure, say N.
80 80
81config SQUASHFS_4K_DEVBLK_SIZE
82 bool "Use 4K device block size?"
83 depends on SQUASHFS
84 help
85 By default Squashfs sets the dev block size (sb_min_blocksize)
86 to 1K or the smallest block size supported by the block device
87 (if larger). This, because blocks are packed together and
88 unaligned in Squashfs, should reduce latency.
89
90 This, however, gives poor performance on MTD NAND devices where
91 the optimal I/O size is 4K (even though the devices can support
92 smaller block sizes).
93
94 Using a 4K device block size may also improve overall I/O
95 performance for some file access patterns (e.g. sequential
96 accesses of files in filesystem order) on all media.
97
98 Setting this option will force Squashfs to use a 4K device block
99 size by default.
100
101 If unsure, say N.
102
81config SQUASHFS_EMBEDDED 103config SQUASHFS_EMBEDDED
82 bool "Additional option for memory-constrained systems" 104 bool "Additional option for memory-constrained systems"
83 depends on SQUASHFS 105 depends on SQUASHFS
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index b4a4e539a08c..e8e14645de9a 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -36,6 +36,13 @@
36#define SQUASHFS_FILE_SIZE 131072 36#define SQUASHFS_FILE_SIZE 131072
37#define SQUASHFS_FILE_LOG 17 37#define SQUASHFS_FILE_LOG 17
38 38
39/* default size of block device I/O */
40#ifdef CONFIG_SQUASHFS_4K_DEVBLK_SIZE
41#define SQUASHFS_DEVBLK_SIZE 4096
42#else
43#define SQUASHFS_DEVBLK_SIZE 1024
44#endif
45
39#define SQUASHFS_FILE_MAX_SIZE 1048576 46#define SQUASHFS_FILE_MAX_SIZE 1048576
40#define SQUASHFS_FILE_MAX_LOG 20 47#define SQUASHFS_FILE_MAX_LOG 20
41 48
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 7438850c62d0..2da1715452ac 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -95,7 +95,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
95 } 95 }
96 msblk = sb->s_fs_info; 96 msblk = sb->s_fs_info;
97 97
98 msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE); 98 msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
99 msblk->devblksize_log2 = ffz(~msblk->devblksize); 99 msblk->devblksize_log2 = ffz(~msblk->devblksize);
100 100
101 mutex_init(&msblk->read_data_mutex); 101 mutex_init(&msblk->read_data_mutex);
diff --git a/fs/statfs.c b/fs/statfs.c
index 8244924dec55..9cf04a118965 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -76,7 +76,7 @@ EXPORT_SYMBOL(vfs_statfs);
76int user_statfs(const char __user *pathname, struct kstatfs *st) 76int user_statfs(const char __user *pathname, struct kstatfs *st)
77{ 77{
78 struct path path; 78 struct path path;
79 int error = user_path(pathname, &path); 79 int error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
80 if (!error) { 80 if (!error) {
81 error = vfs_statfs(&path, st); 81 error = vfs_statfs(&path, st);
82 path_put(&path); 82 path_put(&path);
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index e6e28f37d8ec..9eabffbc4e50 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -47,6 +47,9 @@ enum {
47 * @muxval: a number usually used to poke into some mux regiser to 47 * @muxval: a number usually used to poke into some mux regiser to
48 * mux in the signal to this channel 48 * mux in the signal to this channel
49 * @cctl_opt: default options for the channel control register 49 * @cctl_opt: default options for the channel control register
50 * @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
51 * channels. Fill with 'true' if peripheral should be flow controller. Direction
52 * will be selected at Runtime.
50 * @addr: source/target address in physical memory for this DMA channel, 53 * @addr: source/target address in physical memory for this DMA channel,
51 * can be the address of a FIFO register for burst requests for example. 54 * can be the address of a FIFO register for burst requests for example.
52 * This can be left undefined if the PrimeCell API is used for configuring 55 * This can be left undefined if the PrimeCell API is used for configuring
@@ -65,6 +68,7 @@ struct pl08x_channel_data {
65 int max_signal; 68 int max_signal;
66 u32 muxval; 69 u32 muxval;
67 u32 cctl; 70 u32 cctl;
71 bool device_fc;
68 dma_addr_t addr; 72 dma_addr_t addr;
69 bool circular_buffer; 73 bool circular_buffer;
70 bool single; 74 bool single;
@@ -77,13 +81,11 @@ struct pl08x_channel_data {
77 * @addr: current address 81 * @addr: current address
78 * @maxwidth: the maximum width of a transfer on this bus 82 * @maxwidth: the maximum width of a transfer on this bus
79 * @buswidth: the width of this bus in bytes: 1, 2 or 4 83 * @buswidth: the width of this bus in bytes: 1, 2 or 4
80 * @fill_bytes: bytes required to fill to the next bus memory boundary
81 */ 84 */
82struct pl08x_bus_data { 85struct pl08x_bus_data {
83 dma_addr_t addr; 86 dma_addr_t addr;
84 u8 maxwidth; 87 u8 maxwidth;
85 u8 buswidth; 88 u8 buswidth;
86 size_t fill_bytes;
87}; 89};
88 90
89/** 91/**
@@ -104,17 +106,35 @@ struct pl08x_phy_chan {
104}; 106};
105 107
106/** 108/**
109 * struct pl08x_sg - structure containing data per sg
110 * @src_addr: src address of sg
111 * @dst_addr: dst address of sg
112 * @len: transfer len in bytes
113 * @node: node for txd's dsg_list
114 */
115struct pl08x_sg {
116 dma_addr_t src_addr;
117 dma_addr_t dst_addr;
118 size_t len;
119 struct list_head node;
120};
121
122/**
107 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor 123 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
124 * @tx: async tx descriptor
125 * @node: node for txd list for channels
126 * @dsg_list: list of children sg's
127 * @direction: direction of transfer
108 * @llis_bus: DMA memory address (physical) start for the LLIs 128 * @llis_bus: DMA memory address (physical) start for the LLIs
109 * @llis_va: virtual memory address start for the LLIs 129 * @llis_va: virtual memory address start for the LLIs
130 * @cctl: control reg values for current txd
131 * @ccfg: config reg values for current txd
110 */ 132 */
111struct pl08x_txd { 133struct pl08x_txd {
112 struct dma_async_tx_descriptor tx; 134 struct dma_async_tx_descriptor tx;
113 struct list_head node; 135 struct list_head node;
136 struct list_head dsg_list;
114 enum dma_data_direction direction; 137 enum dma_data_direction direction;
115 dma_addr_t src_addr;
116 dma_addr_t dst_addr;
117 size_t len;
118 dma_addr_t llis_bus; 138 dma_addr_t llis_bus;
119 struct pl08x_lli *llis_va; 139 struct pl08x_lli *llis_va;
120 /* Default cctl value for LLIs */ 140 /* Default cctl value for LLIs */
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index cbee7de7dd36..d12f077a6daf 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -19,12 +19,8 @@ struct dma_pl330_peri {
19 * Peri_Req i/f of the DMAC that is 19 * Peri_Req i/f of the DMAC that is
20 * peripheral could be reached from. 20 * peripheral could be reached from.
21 */ 21 */
22 u8 peri_id; /* {0, 31} */ 22 u8 peri_id; /* specific dma id */
23 enum pl330_reqtype rqtype; 23 enum pl330_reqtype rqtype;
24
25 /* For M->D and D->M Channels */
26 int burst_sz; /* in power of 2 */
27 dma_addr_t fifo_addr;
28}; 24};
29 25
30struct dma_pl330_platdata { 26struct dma_pl330_platdata {
diff --git a/include/linux/bio.h b/include/linux/bio.h
index ce33e6868a2f..a3c071c9e189 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -269,14 +269,6 @@ extern void bvec_free_bs(struct bio_set *, struct bio_vec *, unsigned int);
269extern unsigned int bvec_nr_vecs(unsigned short idx); 269extern unsigned int bvec_nr_vecs(unsigned short idx);
270 270
271/* 271/*
272 * Allow queuer to specify a completion CPU for this bio
273 */
274static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu)
275{
276 bio->bi_comp_cpu = cpu;
277}
278
279/*
280 * bio_set is used to allow other portions of the IO system to 272 * bio_set is used to allow other portions of the IO system to
281 * allocate their own private memory pools for bio and iovec structures. 273 * allocate their own private memory pools for bio and iovec structures.
282 * These memory pools in turn all allocate from the bio_slab 274 * These memory pools in turn all allocate from the bio_slab
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 71fc53bb8f1c..4053cbd4490e 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -59,8 +59,6 @@ struct bio {
59 59
60 unsigned int bi_max_vecs; /* max bvl_vecs we can hold */ 60 unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
61 61
62 unsigned int bi_comp_cpu; /* completion CPU */
63
64 atomic_t bi_cnt; /* pin count */ 62 atomic_t bi_cnt; /* pin count */
65 63
66 struct bio_vec *bi_io_vec; /* the actual vec list */ 64 struct bio_vec *bi_io_vec; /* the actual vec list */
@@ -93,11 +91,10 @@ struct bio {
93#define BIO_BOUNCED 5 /* bio is a bounce bio */ 91#define BIO_BOUNCED 5 /* bio is a bounce bio */
94#define BIO_USER_MAPPED 6 /* contains user pages */ 92#define BIO_USER_MAPPED 6 /* contains user pages */
95#define BIO_EOPNOTSUPP 7 /* not supported */ 93#define BIO_EOPNOTSUPP 7 /* not supported */
96#define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */ 94#define BIO_NULL_MAPPED 8 /* contains invalid user pages */
97#define BIO_NULL_MAPPED 9 /* contains invalid user pages */ 95#define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */
98#define BIO_FS_INTEGRITY 10 /* fs owns integrity data, not block layer */ 96#define BIO_QUIET 10 /* Make BIO Quiet */
99#define BIO_QUIET 11 /* Make BIO Quiet */ 97#define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
100#define BIO_MAPPED_INTEGRITY 12/* integrity metadata has been remapped */
101#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) 98#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
102 99
103/* 100/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 7fbaa9103344..5267cd2f20dc 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -195,7 +195,7 @@ struct request_pm_state
195#include <linux/elevator.h> 195#include <linux/elevator.h>
196 196
197typedef void (request_fn_proc) (struct request_queue *q); 197typedef void (request_fn_proc) (struct request_queue *q);
198typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); 198typedef void (make_request_fn) (struct request_queue *q, struct bio *bio);
199typedef int (prep_rq_fn) (struct request_queue *, struct request *); 199typedef int (prep_rq_fn) (struct request_queue *, struct request *);
200typedef void (unprep_rq_fn) (struct request_queue *, struct request *); 200typedef void (unprep_rq_fn) (struct request_queue *, struct request *);
201 201
@@ -680,6 +680,8 @@ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
680extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, 680extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
681 struct scsi_ioctl_command __user *); 681 struct scsi_ioctl_command __user *);
682 682
683extern void blk_queue_bio(struct request_queue *q, struct bio *bio);
684
683/* 685/*
684 * A queue has just exitted congestion. Note this in the global counter of 686 * A queue has just exitted congestion. Note this in the global counter of
685 * congested queues, and wake up anyone who was waiting for requests to be 687 * congested queues, and wake up anyone who was waiting for requests to be
@@ -863,16 +865,22 @@ struct request_queue *blk_alloc_queue_node(gfp_t, int);
863extern void blk_put_queue(struct request_queue *); 865extern void blk_put_queue(struct request_queue *);
864 866
865/* 867/*
866 * Note: Code in between changing the blk_plug list/cb_list or element of such 868 * blk_plug permits building a queue of related requests by holding the I/O
867 * lists is preemptable, but such code can't do sleep (or be very careful), 869 * fragments for a short period. This allows merging of sequential requests
868 * otherwise data is corrupted. For details, please check schedule() where 870 * into single larger request. As the requests are moved from a per-task list to
869 * blk_schedule_flush_plug() is called. 871 * the device's request_queue in a batch, this results in improved scalability
872 * as the lock contention for request_queue lock is reduced.
873 *
874 * It is ok not to disable preemption when adding the request to the plug list
875 * or when attempting a merge, because blk_schedule_flush_list() will only flush
876 * the plug list when the task sleeps by itself. For details, please see
877 * schedule() where blk_schedule_flush_plug() is called.
870 */ 878 */
871struct blk_plug { 879struct blk_plug {
872 unsigned long magic; 880 unsigned long magic; /* detect uninitialized use-cases */
873 struct list_head list; 881 struct list_head list; /* requests */
874 struct list_head cb_list; 882 struct list_head cb_list; /* md requires an unplug callback */
875 unsigned int should_sort; 883 unsigned int should_sort; /* list to be sorted before flushing? */
876}; 884};
877#define BLK_MAX_REQUEST_COUNT 16 885#define BLK_MAX_REQUEST_COUNT 16
878 886
@@ -1189,20 +1197,6 @@ static inline uint64_t rq_io_start_time_ns(struct request *req)
1189} 1197}
1190#endif 1198#endif
1191 1199
1192#ifdef CONFIG_BLK_DEV_THROTTLING
1193extern int blk_throtl_init(struct request_queue *q);
1194extern void blk_throtl_exit(struct request_queue *q);
1195extern int blk_throtl_bio(struct request_queue *q, struct bio **bio);
1196#else /* CONFIG_BLK_DEV_THROTTLING */
1197static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio)
1198{
1199 return 0;
1200}
1201
1202static inline int blk_throtl_init(struct request_queue *q) { return 0; }
1203static inline int blk_throtl_exit(struct request_queue *q) { return 0; }
1204#endif /* CONFIG_BLK_DEV_THROTTLING */
1205
1206#define MODULE_ALIAS_BLOCKDEV(major,minor) \ 1200#define MODULE_ALIAS_BLOCKDEV(major,minor) \
1207 MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) 1201 MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
1208#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ 1202#define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index b1a635acf72a..6cb60fd2ea84 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -196,13 +196,9 @@ static inline void cpu_hotplug_driver_unlock(void)
196#endif /* CONFIG_HOTPLUG_CPU */ 196#endif /* CONFIG_HOTPLUG_CPU */
197 197
198#ifdef CONFIG_PM_SLEEP_SMP 198#ifdef CONFIG_PM_SLEEP_SMP
199extern int suspend_cpu_hotplug;
200
201extern int disable_nonboot_cpus(void); 199extern int disable_nonboot_cpus(void);
202extern void enable_nonboot_cpus(void); 200extern void enable_nonboot_cpus(void);
203#else /* !CONFIG_PM_SLEEP_SMP */ 201#else /* !CONFIG_PM_SLEEP_SMP */
204#define suspend_cpu_hotplug 0
205
206static inline int disable_nonboot_cpus(void) { return 0; } 202static inline int disable_nonboot_cpus(void) { return 0; }
207static inline void enable_nonboot_cpus(void) {} 203static inline void enable_nonboot_cpus(void) {}
208#endif /* !CONFIG_PM_SLEEP_SMP */ 204#endif /* !CONFIG_PM_SLEEP_SMP */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index be86ae13893f..e13117cbd2f7 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -42,6 +42,9 @@ struct dma_map_ops {
42 int (*mapping_error)(struct device *dev, dma_addr_t dma_addr); 42 int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
43 int (*dma_supported)(struct device *dev, u64 mask); 43 int (*dma_supported)(struct device *dev, u64 mask);
44 int (*set_dma_mask)(struct device *dev, u64 mask); 44 int (*set_dma_mask)(struct device *dev, u64 mask);
45#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
46 u64 (*get_required_mask)(struct device *dev);
47#endif
45 int is_phys; 48 int is_phys;
46}; 49};
47 50
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8fbf40e0713c..ace51af4369f 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -24,8 +24,7 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/uio.h> 25#include <linux/uio.h>
26#include <linux/dma-direction.h> 26#include <linux/dma-direction.h>
27 27#include <linux/scatterlist.h>
28struct scatterlist;
29 28
30/** 29/**
31 * typedef dma_cookie_t - an opaque DMA cookie 30 * typedef dma_cookie_t - an opaque DMA cookie
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
519 (unsigned long)config); 518 (unsigned long)config);
520} 519}
521 520
521static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
522 struct dma_chan *chan, void *buf, size_t len,
523 enum dma_data_direction dir, unsigned long flags)
524{
525 struct scatterlist sg;
526 sg_init_one(&sg, buf, len);
527
528 return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
529}
530
522static inline int dmaengine_terminate_all(struct dma_chan *chan) 531static inline int dmaengine_terminate_all(struct dma_chan *chan)
523{ 532{
524 return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0); 533 return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index d800d5142184..1d0f7a2ff73b 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -38,6 +38,12 @@ struct elevator_ops
38 elevator_merged_fn *elevator_merged_fn; 38 elevator_merged_fn *elevator_merged_fn;
39 elevator_merge_req_fn *elevator_merge_req_fn; 39 elevator_merge_req_fn *elevator_merge_req_fn;
40 elevator_allow_merge_fn *elevator_allow_merge_fn; 40 elevator_allow_merge_fn *elevator_allow_merge_fn;
41
42 /*
43 * Used for both plugged list and elevator merging and in the
44 * former case called without queue_lock. Read comment on top of
45 * attempt_plug_merge() for details.
46 */
41 elevator_bio_merged_fn *elevator_bio_merged_fn; 47 elevator_bio_merged_fn *elevator_bio_merged_fn;
42 48
43 elevator_dispatch_fn *elevator_dispatch_fn; 49 elevator_dispatch_fn *elevator_dispatch_fn;
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index a49b52934c55..a5386e3ee756 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -143,14 +143,9 @@ static inline void set_freezable_with_signal(void)
143#define wait_event_freezekillable(wq, condition) \ 143#define wait_event_freezekillable(wq, condition) \
144({ \ 144({ \
145 int __retval; \ 145 int __retval; \
146 do { \ 146 freezer_do_not_count(); \
147 __retval = wait_event_killable(wq, \ 147 __retval = wait_event_killable(wq, (condition)); \
148 (condition) || freezing(current)); \ 148 freezer_count(); \
149 if (__retval && !freezing(current)) \
150 break; \
151 else if (!(condition)) \
152 __retval = -ERESTARTSYS; \
153 } while (try_to_freeze()); \
154 __retval; \ 149 __retval; \
155}) 150})
156 151
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6957350e122f..9de31bc98c88 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -131,6 +131,7 @@ struct hd_struct {
131#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ 131#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
132#define GENHD_FL_NATIVE_CAPACITY 128 132#define GENHD_FL_NATIVE_CAPACITY 128
133#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 133#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
134#define GENHD_FL_NO_PART_SCAN 512
134 135
135enum { 136enum {
136 DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ 137 DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
@@ -238,9 +239,10 @@ static inline int disk_max_parts(struct gendisk *disk)
238 return disk->minors; 239 return disk->minors;
239} 240}
240 241
241static inline bool disk_partitionable(struct gendisk *disk) 242static inline bool disk_part_scan_enabled(struct gendisk *disk)
242{ 243{
243 return disk_max_parts(disk) > 1; 244 return disk_max_parts(disk) > 1 &&
245 !(disk->flags & GENHD_FL_NO_PART_SCAN);
244} 246}
245 247
246static inline dev_t disk_devt(struct gendisk *disk) 248static inline dev_t disk_devt(struct gendisk *disk)
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 683d69890119..11a41a8f08eb 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -73,8 +73,8 @@ struct loop_device {
73 */ 73 */
74enum { 74enum {
75 LO_FLAGS_READ_ONLY = 1, 75 LO_FLAGS_READ_ONLY = 1,
76 LO_FLAGS_USE_AOPS = 2,
77 LO_FLAGS_AUTOCLEAR = 4, 76 LO_FLAGS_AUTOCLEAR = 4,
77 LO_FLAGS_PARTSCAN = 8,
78}; 78};
79 79
80#include <asm/posix_types.h> /* for __kernel_old_dev_t */ 80#include <asm/posix_types.h> /* for __kernel_old_dev_t */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 60a137b7f171..ab2c6343361a 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -229,6 +229,7 @@ struct nfs_inode {
229#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */ 229#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */
230#define NFS_INO_PNFS_COMMIT (8) /* use pnfs code for commit */ 230#define NFS_INO_PNFS_COMMIT (8) /* use pnfs code for commit */
231#define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */ 231#define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */
232#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
232 233
233static inline struct nfs_inode *NFS_I(const struct inode *inode) 234static inline struct nfs_inode *NFS_I(const struct inode *inode)
234{ 235{
diff --git a/include/linux/of.h b/include/linux/of.h
index f01ba8a209c0..0e89aa0bf07a 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -321,6 +321,16 @@ static inline struct device_node *of_parse_phandle(struct device_node *np,
321 return NULL; 321 return NULL;
322} 322}
323 323
324static inline int of_alias_get_id(struct device_node *np, const char *stem)
325{
326 return -ENOSYS;
327}
328
329static inline int of_machine_is_compatible(const char *compat)
330{
331 return 0;
332}
333
324#define of_match_ptr(_ptr) NULL 334#define of_match_ptr(_ptr) NULL
325#define of_match_node(_matches, _node) NULL 335#define of_match_node(_matches, _node) NULL
326#endif /* CONFIG_OF */ 336#endif /* CONFIG_OF */
diff --git a/include/linux/opp.h b/include/linux/opp.h
index 87a9208f8aec..ee94b33080c2 100644
--- a/include/linux/opp.h
+++ b/include/linux/opp.h
@@ -97,11 +97,11 @@ static inline int opp_disable(struct device *dev, unsigned long freq)
97 return 0; 97 return 0;
98} 98}
99 99
100struct srcu_notifier_head *opp_get_notifier(struct device *dev) 100static inline struct srcu_notifier_head *opp_get_notifier(struct device *dev)
101{ 101{
102 return ERR_PTR(-EINVAL); 102 return ERR_PTR(-EINVAL);
103} 103}
104#endif /* CONFIG_PM */ 104#endif /* CONFIG_PM_OPP */
105 105
106#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) 106#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
107int opp_init_cpufreq_table(struct device *dev, 107int opp_init_cpufreq_table(struct device *dev,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1679ff6931f9..3fdf251389de 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2873,3 +2873,5 @@
2873 2873
2874#define PCI_VENDOR_ID_XEN 0x5853 2874#define PCI_VENDOR_ID_XEN 0x5853
2875#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 2875#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
2876
2877#define PCI_VENDOR_ID_OCZ 0x1b85
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 8bffe9ae2ca0..0efa1f10bc2b 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -131,8 +131,6 @@ struct plat_sci_port {
131 131
132 struct plat_sci_port_ops *ops; 132 struct plat_sci_port_ops *ops;
133 133
134 struct device *dma_dev;
135
136 unsigned int dma_slave_tx; 134 unsigned int dma_slave_tx;
137 unsigned int dma_slave_rx; 135 unsigned int dma_slave_rx;
138}; 136};
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 492486a74484..3d8f9c44e27d 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -136,6 +136,8 @@ void rpc_shutdown_client(struct rpc_clnt *);
136void rpc_release_client(struct rpc_clnt *); 136void rpc_release_client(struct rpc_clnt *);
137void rpc_task_release_client(struct rpc_task *); 137void rpc_task_release_client(struct rpc_task *);
138 138
139int rpcb_create_local(void);
140void rpcb_put_local(void);
139int rpcb_register(u32, u32, int, unsigned short); 141int rpcb_register(u32, u32, int, unsigned short);
140int rpcb_v4_register(const u32 program, const u32 version, 142int rpcb_v4_register(const u32 program, const u32 version,
141 const struct sockaddr *address, 143 const struct sockaddr *address,
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index d8d5d93071b3..35b37b1e9299 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -413,6 +413,7 @@ struct svc_procedure {
413/* 413/*
414 * Function prototypes. 414 * Function prototypes.
415 */ 415 */
416void svc_rpcb_cleanup(struct svc_serv *serv);
416struct svc_serv *svc_create(struct svc_program *, unsigned int, 417struct svc_serv *svc_create(struct svc_program *, unsigned int,
417 void (*shutdown)(struct svc_serv *)); 418 void (*shutdown)(struct svc_serv *));
418struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, 419struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
diff --git a/include/linux/topology.h b/include/linux/topology.h
index fc839bfa7935..e26db031303b 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -201,6 +201,10 @@ int arch_update_cpu_topology(void);
201 .balance_interval = 64, \ 201 .balance_interval = 64, \
202} 202}
203 203
204#ifndef SD_NODES_PER_DOMAIN
205#define SD_NODES_PER_DOMAIN 16
206#endif
207
204#ifdef CONFIG_SCHED_BOOK 208#ifdef CONFIG_SCHED_BOOK
205#ifndef SD_BOOK_INIT 209#ifndef SD_BOOK_INIT
206#error Please define an appropriate SD_BOOK_INIT in include/asm/topology.h!!! 210#error Please define an appropriate SD_BOOK_INIT in include/asm/topology.h!!!
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 225560c1a10f..4b752d5ee80e 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -653,6 +653,10 @@ struct v4l2_buffer {
653#define V4L2_BUF_FLAG_ERROR 0x0040 653#define V4L2_BUF_FLAG_ERROR 0x0040
654#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ 654#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
655#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ 655#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
656#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */
657/* Cache handling flags */
658#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
659#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000
656 660
657/* 661/*
658 * O V E R L A Y P R E V I E W 662 * O V E R L A Y P R E V I E W
@@ -1165,6 +1169,7 @@ enum v4l2_power_line_frequency {
1165 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, 1169 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0,
1166 V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, 1170 V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1,
1167 V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, 1171 V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2,
1172 V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3,
1168}; 1173};
1169#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) 1174#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25)
1170#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) 1175#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26)
@@ -2138,6 +2143,23 @@ struct v4l2_dbg_chip_ident {
2138 __u32 revision; /* chip revision, chip specific */ 2143 __u32 revision; /* chip revision, chip specific */
2139} __attribute__ ((packed)); 2144} __attribute__ ((packed));
2140 2145
2146/**
2147 * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
2148 * @index: on return, index of the first created buffer
2149 * @count: entry: number of requested buffers,
2150 * return: number of created buffers
2151 * @memory: buffer memory type
2152 * @format: frame format, for which buffers are requested
2153 * @reserved: future extensions
2154 */
2155struct v4l2_create_buffers {
2156 __u32 index;
2157 __u32 count;
2158 enum v4l2_memory memory;
2159 struct v4l2_format format;
2160 __u32 reserved[8];
2161};
2162
2141/* 2163/*
2142 * I O C T L C O D E S F O R V I D E O D E V I C E S 2164 * I O C T L C O D E S F O R V I D E O D E V I C E S
2143 * 2165 *
@@ -2228,6 +2250,11 @@ struct v4l2_dbg_chip_ident {
2228#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) 2250#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
2229#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) 2251#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
2230 2252
2253/* Experimental, the below two ioctls may change over the next couple of kernel
2254 versions */
2255#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers)
2256#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer)
2257
2231/* Reminder: when adding new ioctls please add support for them to 2258/* Reminder: when adding new ioctls please add support for them to
2232 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 2259 drivers/media/video/v4l2-compat-ioctl32.c as well! */
2233 2260
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
index 548bf1155c83..00dbb7c4feae 100644
--- a/include/media/ov772x.h
+++ b/include/media/ov772x.h
@@ -12,12 +12,9 @@
12#ifndef __OV772X_H__ 12#ifndef __OV772X_H__
13#define __OV772X_H__ 13#define __OV772X_H__
14 14
15#include <media/soc_camera.h>
16
17/* for flags */ 15/* for flags */
18#define OV772X_FLAG_VFLIP (1 << 0) /* Vertical flip image */ 16#define OV772X_FLAG_VFLIP (1 << 0) /* Vertical flip image */
19#define OV772X_FLAG_HFLIP (1 << 1) /* Horizontal flip image */ 17#define OV772X_FLAG_HFLIP (1 << 1) /* Horizontal flip image */
20#define OV772X_FLAG_8BIT (1 << 2) /* default 10 bit */
21 18
22/* 19/*
23 * for Edge ctrl 20 * for Edge ctrl
@@ -32,22 +29,23 @@ struct ov772x_edge_ctrl {
32 unsigned char lower; 29 unsigned char lower;
33}; 30};
34 31
35#define OV772X_MANUAL_EDGE_CTRL 0x80 /* un-used bit of strength */ 32#define OV772X_MANUAL_EDGE_CTRL 0x80 /* un-used bit of strength */
36#define EDGE_STRENGTH_MASK 0x1F 33#define OV772X_EDGE_STRENGTH_MASK 0x1F
37#define EDGE_THRESHOLD_MASK 0x0F 34#define OV772X_EDGE_THRESHOLD_MASK 0x0F
38#define EDGE_UPPER_MASK 0xFF 35#define OV772X_EDGE_UPPER_MASK 0xFF
39#define EDGE_LOWER_MASK 0xFF 36#define OV772X_EDGE_LOWER_MASK 0xFF
40 37
41#define OV772X_AUTO_EDGECTRL(u, l) \ 38#define OV772X_AUTO_EDGECTRL(u, l) \
42{ \ 39{ \
43 .upper = (u & EDGE_UPPER_MASK), \ 40 .upper = (u & OV772X_EDGE_UPPER_MASK), \
44 .lower = (l & EDGE_LOWER_MASK), \ 41 .lower = (l & OV772X_EDGE_LOWER_MASK), \
45} 42}
46 43
47#define OV772X_MANUAL_EDGECTRL(s, t) \ 44#define OV772X_MANUAL_EDGECTRL(s, t) \
48{ \ 45{ \
49 .strength = (s & EDGE_STRENGTH_MASK) | OV772X_MANUAL_EDGE_CTRL,\ 46 .strength = (s & OV772X_EDGE_STRENGTH_MASK) | \
50 .threshold = (t & EDGE_THRESHOLD_MASK), \ 47 OV772X_MANUAL_EDGE_CTRL, \
48 .threshold = (t & OV772X_EDGE_THRESHOLD_MASK), \
51} 49}
52 50
53/* 51/*
diff --git a/include/media/s5k6aa.h b/include/media/s5k6aa.h
new file mode 100644
index 000000000000..ba34f7055e55
--- /dev/null
+++ b/include/media/s5k6aa.h
@@ -0,0 +1,51 @@
1/*
2 * S5K6AAFX camera sensor driver header
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef S5K6AA_H
13#define S5K6AA_H
14
15#include <media/v4l2-mediabus.h>
16
17/**
18 * struct s5k6aa_gpio - data structure describing a GPIO
19 * @gpio: GPIO number
20 * @level: indicates active state of the @gpio
21 */
22struct s5k6aa_gpio {
23 int gpio;
24 int level;
25};
26
27/**
28 * struct s5k6aa_platform_data - s5k6aa driver platform data
29 * @set_power: an additional callback to the board code, called
30 * after enabling the regulators and before switching
31 * the sensor off
32 * @mclk_frequency: sensor's master clock frequency in Hz
33 * @gpio_reset: GPIO driving RESET pin
34 * @gpio_stby: GPIO driving STBY pin
35 * @nlanes: maximum number of MIPI-CSI lanes used
36 * @horiz_flip: default horizontal image flip value, non zero to enable
37 * @vert_flip: default vertical image flip value, non zero to enable
38 */
39
40struct s5k6aa_platform_data {
41 int (*set_power)(int enable);
42 unsigned long mclk_frequency;
43 struct s5k6aa_gpio gpio_reset;
44 struct s5k6aa_gpio gpio_stby;
45 enum v4l2_mbus_type bus_type;
46 u8 nlanes;
47 u8 horiz_flip;
48 u8 vert_flip;
49};
50
51#endif /* S5K6AA_H */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 7582952dceae..b1377b931eb7 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -12,12 +12,14 @@
12#ifndef SOC_CAMERA_H 12#ifndef SOC_CAMERA_H
13#define SOC_CAMERA_H 13#define SOC_CAMERA_H
14 14
15#include <linux/bitops.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/mutex.h> 17#include <linux/mutex.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/videodev2.h> 19#include <linux/videodev2.h>
19#include <media/videobuf-core.h> 20#include <media/videobuf-core.h>
20#include <media/videobuf2-core.h> 21#include <media/videobuf2-core.h>
22#include <media/v4l2-ctrls.h>
21#include <media/v4l2-device.h> 23#include <media/v4l2-device.h>
22 24
23struct file; 25struct file;
@@ -37,8 +39,8 @@ struct soc_camera_device {
37 unsigned char iface; /* Host number */ 39 unsigned char iface; /* Host number */
38 unsigned char devnum; /* Device number per host */ 40 unsigned char devnum; /* Device number per host */
39 struct soc_camera_sense *sense; /* See comment in struct definition */ 41 struct soc_camera_sense *sense; /* See comment in struct definition */
40 struct soc_camera_ops *ops;
41 struct video_device *vdev; 42 struct video_device *vdev;
43 struct v4l2_ctrl_handler ctrl_handler;
42 const struct soc_camera_format_xlate *current_fmt; 44 const struct soc_camera_format_xlate *current_fmt;
43 struct soc_camera_format_xlate *user_formats; 45 struct soc_camera_format_xlate *user_formats;
44 int num_user_formats; 46 int num_user_formats;
@@ -93,14 +95,10 @@ struct soc_camera_host_ops {
93 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); 95 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
94 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 96 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
95 int (*set_bus_param)(struct soc_camera_device *, __u32); 97 int (*set_bus_param)(struct soc_camera_device *, __u32);
96 int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);
97 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
98 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 98 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
99 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 99 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
100 int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *); 100 int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
101 unsigned int (*poll)(struct file *, poll_table *); 101 unsigned int (*poll)(struct file *, poll_table *);
102 const struct v4l2_queryctrl *controls;
103 int num_controls;
104}; 102};
105 103
106#define SOCAM_SENSOR_INVERT_PCLK (1 << 0) 104#define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
@@ -193,13 +191,6 @@ struct soc_camera_format_xlate {
193 const struct soc_mbus_pixelfmt *host_fmt; 191 const struct soc_mbus_pixelfmt *host_fmt;
194}; 192};
195 193
196struct soc_camera_ops {
197 unsigned long (*query_bus_param)(struct soc_camera_device *);
198 int (*set_bus_param)(struct soc_camera_device *, unsigned long);
199 const struct v4l2_queryctrl *controls;
200 int num_controls;
201};
202
203#define SOCAM_SENSE_PCLK_CHANGED (1 << 0) 194#define SOCAM_SENSE_PCLK_CHANGED (1 << 0)
204 195
205/** 196/**
@@ -226,65 +217,18 @@ struct soc_camera_sense {
226 unsigned long pixel_clock; 217 unsigned long pixel_clock;
227}; 218};
228 219
229static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( 220#define SOCAM_DATAWIDTH(x) BIT((x) - 1)
230 struct soc_camera_ops *ops, int id) 221#define SOCAM_DATAWIDTH_4 SOCAM_DATAWIDTH(4)
231{ 222#define SOCAM_DATAWIDTH_8 SOCAM_DATAWIDTH(8)
232 int i; 223#define SOCAM_DATAWIDTH_9 SOCAM_DATAWIDTH(9)
233 224#define SOCAM_DATAWIDTH_10 SOCAM_DATAWIDTH(10)
234 for (i = 0; i < ops->num_controls; i++) 225#define SOCAM_DATAWIDTH_15 SOCAM_DATAWIDTH(15)
235 if (ops->controls[i].id == id) 226#define SOCAM_DATAWIDTH_16 SOCAM_DATAWIDTH(16)
236 return &ops->controls[i];
237
238 return NULL;
239}
240
241#define SOCAM_MASTER (1 << 0)
242#define SOCAM_SLAVE (1 << 1)
243#define SOCAM_HSYNC_ACTIVE_HIGH (1 << 2)
244#define SOCAM_HSYNC_ACTIVE_LOW (1 << 3)
245#define SOCAM_VSYNC_ACTIVE_HIGH (1 << 4)
246#define SOCAM_VSYNC_ACTIVE_LOW (1 << 5)
247#define SOCAM_DATAWIDTH_4 (1 << 6)
248#define SOCAM_DATAWIDTH_8 (1 << 7)
249#define SOCAM_DATAWIDTH_9 (1 << 8)
250#define SOCAM_DATAWIDTH_10 (1 << 9)
251#define SOCAM_DATAWIDTH_15 (1 << 10)
252#define SOCAM_DATAWIDTH_16 (1 << 11)
253#define SOCAM_PCLK_SAMPLE_RISING (1 << 12)
254#define SOCAM_PCLK_SAMPLE_FALLING (1 << 13)
255#define SOCAM_DATA_ACTIVE_HIGH (1 << 14)
256#define SOCAM_DATA_ACTIVE_LOW (1 << 15)
257#define SOCAM_MIPI_1LANE (1 << 16)
258#define SOCAM_MIPI_2LANE (1 << 17)
259#define SOCAM_MIPI_3LANE (1 << 18)
260#define SOCAM_MIPI_4LANE (1 << 19)
261#define SOCAM_MIPI (SOCAM_MIPI_1LANE | SOCAM_MIPI_2LANE | \
262 SOCAM_MIPI_3LANE | SOCAM_MIPI_4LANE)
263 227
264#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \ 228#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \
265 SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \ 229 SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \
266 SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16) 230 SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16)
267 231
268static inline unsigned long soc_camera_bus_param_compatible(
269 unsigned long camera_flags, unsigned long bus_flags)
270{
271 unsigned long common_flags, hsync, vsync, pclk, data, buswidth, mode;
272 unsigned long mipi;
273
274 common_flags = camera_flags & bus_flags;
275
276 hsync = common_flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW);
277 vsync = common_flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW);
278 pclk = common_flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING);
279 data = common_flags & (SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW);
280 mode = common_flags & (SOCAM_MASTER | SOCAM_SLAVE);
281 buswidth = common_flags & SOCAM_DATAWIDTH_MASK;
282 mipi = common_flags & SOCAM_MIPI;
283
284 return ((!hsync || !vsync || !pclk || !data || !mode || !buswidth) && !mipi) ? 0 :
285 common_flags;
286}
287
288static inline void soc_camera_limit_side(int *start, int *length, 232static inline void soc_camera_limit_side(int *start, int *length,
289 unsigned int start_min, 233 unsigned int start_min,
290 unsigned int length_min, unsigned int length_max) 234 unsigned int length_min, unsigned int length_max)
@@ -300,23 +244,37 @@ static inline void soc_camera_limit_side(int *start, int *length,
300 *start = start_min + length_max - *length; 244 *start = start_min + length_max - *length;
301} 245}
302 246
303extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 247unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
304 unsigned long flags); 248 unsigned long flags);
249unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
250 const struct v4l2_mbus_config *cfg);
305 251
306/* This is only temporary here - until v4l2-subdev begins to link to video_device */ 252/* This is only temporary here - until v4l2-subdev begins to link to video_device */
307#include <linux/i2c.h> 253#include <linux/i2c.h>
308static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *client) 254static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client)
255{
256 struct v4l2_subdev *sd = i2c_get_clientdata(client);
257 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
258 return icd ? icd->vdev : NULL;
259}
260
261static inline struct soc_camera_link *soc_camera_i2c_to_link(const struct i2c_client *client)
262{
263 return client->dev.platform_data;
264}
265
266static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(const struct video_device *vdev)
309{ 267{
310 struct soc_camera_device *icd = client->dev.platform_data; 268 struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
311 return icd->vdev; 269 return soc_camera_to_subdev(icd);
312} 270}
313 271
314static inline struct soc_camera_device *soc_camera_from_vb2q(struct vb2_queue *vq) 272static inline struct soc_camera_device *soc_camera_from_vb2q(const struct vb2_queue *vq)
315{ 273{
316 return container_of(vq, struct soc_camera_device, vb2_vidq); 274 return container_of(vq, struct soc_camera_device, vb2_vidq);
317} 275}
318 276
319static inline struct soc_camera_device *soc_camera_from_vbq(struct videobuf_queue *vq) 277static inline struct soc_camera_device *soc_camera_from_vbq(const struct videobuf_queue *vq)
320{ 278{
321 return container_of(vq, struct soc_camera_device, vb_vidq); 279 return container_of(vq, struct soc_camera_device, vb_vidq);
322} 280}
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h
index 74f0fa15ca47..8aa4200a0b1d 100644
--- a/include/media/soc_camera_platform.h
+++ b/include/media/soc_camera_platform.h
@@ -13,6 +13,7 @@
13 13
14#include <linux/videodev2.h> 14#include <linux/videodev2.h>
15#include <media/soc_camera.h> 15#include <media/soc_camera.h>
16#include <media/v4l2-mediabus.h>
16 17
17struct device; 18struct device;
18 19
@@ -20,7 +21,8 @@ struct soc_camera_platform_info {
20 const char *format_name; 21 const char *format_name;
21 unsigned long format_depth; 22 unsigned long format_depth;
22 struct v4l2_mbus_framefmt format; 23 struct v4l2_mbus_framefmt format;
23 unsigned long bus_param; 24 unsigned long mbus_param;
25 enum v4l2_mbus_type mbus_type;
24 struct soc_camera_device *icd; 26 struct soc_camera_device *icd;
25 int (*set_capture)(struct soc_camera_platform_info *info, int enable); 27 int (*set_capture)(struct soc_camera_platform_info *info, int enable);
26}; 28};
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h
index fae432544b41..73f1e7eb60f3 100644
--- a/include/media/soc_mediabus.h
+++ b/include/media/soc_mediabus.h
@@ -82,5 +82,7 @@ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
82s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); 82s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
83int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, 83int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
84 unsigned int *numerator, unsigned int *denominator); 84 unsigned int *numerator, unsigned int *denominator);
85unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
86 unsigned int flags);
85 87
86#endif 88#endif
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dd9f1e7b8ff7..4d1c74ad4c84 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
122 int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b); 122 int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b);
123 int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b); 123 int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b);
124 124
125 int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
126 int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
125 127
126 int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i); 128 int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
127 int (*vidioc_g_fbuf) (struct file *file, void *fh, 129 int (*vidioc_g_fbuf) (struct file *file, void *fh,
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 257da1a30f66..f0f3358d1b1b 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -158,6 +158,7 @@ struct v4l2_subdev_core_ops {
158 int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); 158 int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
159 int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); 159 int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
160 int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); 160 int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
161 int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm);
161 int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm); 162 int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
162 long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); 163 long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
163#ifdef CONFIG_VIDEO_ADV_DEBUG 164#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -534,13 +535,13 @@ struct v4l2_subdev {
534 void *dev_priv; 535 void *dev_priv;
535 void *host_priv; 536 void *host_priv;
536 /* subdev device node */ 537 /* subdev device node */
537 struct video_device devnode; 538 struct video_device *devnode;
538}; 539};
539 540
540#define media_entity_to_v4l2_subdev(ent) \ 541#define media_entity_to_v4l2_subdev(ent) \
541 container_of(ent, struct v4l2_subdev, entity) 542 container_of(ent, struct v4l2_subdev, entity)
542#define vdev_to_v4l2_subdev(vdev) \ 543#define vdev_to_v4l2_subdev(vdev) \
543 container_of(vdev, struct v4l2_subdev, devnode) 544 video_get_drvdata(vdev)
544 545
545/* 546/*
546 * Used for storing subdev information per file handle 547 * Used for storing subdev information per file handle
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index ea55c08eddfb..a15d1f1b319e 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -105,6 +105,7 @@ enum vb2_fileio_flags {
105/** 105/**
106 * enum vb2_buffer_state - current video buffer state 106 * enum vb2_buffer_state - current video buffer state
107 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control 107 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control
108 * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver
108 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver 109 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
109 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used 110 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
110 * in a hardware operation 111 * in a hardware operation
@@ -116,6 +117,7 @@ enum vb2_fileio_flags {
116 */ 117 */
117enum vb2_buffer_state { 118enum vb2_buffer_state {
118 VB2_BUF_STATE_DEQUEUED, 119 VB2_BUF_STATE_DEQUEUED,
120 VB2_BUF_STATE_PREPARED,
119 VB2_BUF_STATE_QUEUED, 121 VB2_BUF_STATE_QUEUED,
120 VB2_BUF_STATE_ACTIVE, 122 VB2_BUF_STATE_ACTIVE,
121 VB2_BUF_STATE_DONE, 123 VB2_BUF_STATE_DONE,
@@ -167,13 +169,21 @@ struct vb2_buffer {
167/** 169/**
168 * struct vb2_ops - driver-specific callbacks 170 * struct vb2_ops - driver-specific callbacks
169 * 171 *
170 * @queue_setup: called from a VIDIOC_REQBUFS handler, before 172 * @queue_setup: called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS
171 * memory allocation; driver should return the required 173 * handlers before memory allocation, or, if
172 * number of buffers in num_buffers, the required number 174 * *num_planes != 0, after the allocation to verify a
173 * of planes per buffer in num_planes; the size of each 175 * smaller number of buffers. Driver should return
174 * plane should be set in the sizes[] array and optional 176 * the required number of buffers in *num_buffers, the
175 * per-plane allocator specific context in alloc_ctxs[] 177 * required number of planes per buffer in *num_planes; the
176 * array 178 * size of each plane should be set in the sizes[] array
179 * and optional per-plane allocator specific context in the
180 * alloc_ctxs[] array. When called from VIDIOC_REQBUFS,
181 * fmt == NULL, the driver has to use the currently
182 * configured format and *num_buffers is the total number
183 * of buffers, that are being allocated. When called from
184 * VIDIOC_CREATE_BUFS, fmt != NULL and it describes the
185 * target frame format. In this case *num_buffers are being
186 * allocated additionally to q->num_buffers.
177 * @wait_prepare: release any locks taken while calling vb2 functions; 187 * @wait_prepare: release any locks taken while calling vb2 functions;
178 * it is called before an ioctl needs to wait for a new 188 * it is called before an ioctl needs to wait for a new
179 * buffer to arrive; required to avoid a deadlock in 189 * buffer to arrive; required to avoid a deadlock in
@@ -186,11 +196,11 @@ struct vb2_buffer {
186 * perform additional buffer-related initialization; 196 * perform additional buffer-related initialization;
187 * initialization failure (return != 0) will prevent 197 * initialization failure (return != 0) will prevent
188 * queue setup from completing successfully; optional 198 * queue setup from completing successfully; optional
189 * @buf_prepare: called every time the buffer is queued from userspace; 199 * @buf_prepare: called every time the buffer is queued from userspace
190 * drivers may perform any initialization required before 200 * and from the VIDIOC_PREPARE_BUF ioctl; drivers may
191 * each hardware operation in this callback; 201 * perform any initialization required before each hardware
192 * if an error is returned, the buffer will not be queued 202 * operation in this callback; if an error is returned, the
193 * in driver; optional 203 * buffer will not be queued in driver; optional
194 * @buf_finish: called before every dequeue of the buffer back to 204 * @buf_finish: called before every dequeue of the buffer back to
195 * userspace; drivers may perform any operations required 205 * userspace; drivers may perform any operations required
196 * before userspace accesses the buffer; optional 206 * before userspace accesses the buffer; optional
@@ -216,9 +226,9 @@ struct vb2_buffer {
216 * pre-queued buffers before calling STREAMON 226 * pre-queued buffers before calling STREAMON
217 */ 227 */
218struct vb2_ops { 228struct vb2_ops {
219 int (*queue_setup)(struct vb2_queue *q, unsigned int *num_buffers, 229 int (*queue_setup)(struct vb2_queue *q, const struct v4l2_format *fmt,
220 unsigned int *num_planes, unsigned int sizes[], 230 unsigned int *num_buffers, unsigned int *num_planes,
221 void *alloc_ctxs[]); 231 unsigned int sizes[], void *alloc_ctxs[]);
222 232
223 void (*wait_prepare)(struct vb2_queue *q); 233 void (*wait_prepare)(struct vb2_queue *q);
224 void (*wait_finish)(struct vb2_queue *q); 234 void (*wait_finish)(struct vb2_queue *q);
@@ -298,6 +308,9 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q);
298int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); 308int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
299int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); 309int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
300 310
311int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
312int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
313
301int vb2_queue_init(struct vb2_queue *q); 314int vb2_queue_init(struct vb2_queue *q);
302 315
303void vb2_queue_release(struct vb2_queue *q); 316void vb2_queue_release(struct vb2_queue *q);
@@ -309,6 +322,13 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
309int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type); 322int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
310 323
311int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma); 324int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
325#ifndef CONFIG_MMU
326unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
327 unsigned long addr,
328 unsigned long len,
329 unsigned long pgoff,
330 unsigned long flags);
331#endif
312unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait); 332unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
313size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, 333size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
314 loff_t *ppos, int nonblock); 334 loff_t *ppos, int nonblock);
diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h
index 3d5d6db864fe..9324488f23f0 100644
--- a/include/xen/interface/io/blkif.h
+++ b/include/xen/interface/io/blkif.h
@@ -57,6 +57,36 @@ typedef uint64_t blkif_sector_t;
57 * "feature-flush-cache" node! 57 * "feature-flush-cache" node!
58 */ 58 */
59#define BLKIF_OP_FLUSH_DISKCACHE 3 59#define BLKIF_OP_FLUSH_DISKCACHE 3
60
61/*
62 * Recognised only if "feature-discard" is present in backend xenbus info.
63 * The "feature-discard" node contains a boolean indicating whether trim
64 * (ATA) or unmap (SCSI) - conviently called discard requests are likely
65 * to succeed or fail. Either way, a discard request
66 * may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by
67 * the underlying block-device hardware. The boolean simply indicates whether
68 * or not it is worthwhile for the frontend to attempt discard requests.
69 * If a backend does not recognise BLKIF_OP_DISCARD, it should *not*
70 * create the "feature-discard" node!
71 *
72 * Discard operation is a request for the underlying block device to mark
73 * extents to be erased. However, discard does not guarantee that the blocks
74 * will be erased from the device - it is just a hint to the device
75 * controller that these blocks are no longer in use. What the device
76 * controller does with that information is left to the controller.
77 * Discard operations are passed with sector_number as the
78 * sector index to begin discard operations at and nr_sectors as the number of
79 * sectors to be discarded. The specified sectors should be discarded if the
80 * underlying block device supports trim (ATA) or unmap (SCSI) operations,
81 * or a BLKIF_RSP_EOPNOTSUPP should be returned.
82 * More information about trim/unmap operations at:
83 * http://t13.org/Documents/UploadedDocuments/docs2008/
84 * e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
85 * http://www.seagate.com/staticfiles/support/disc/manuals/
86 * Interface%20manuals/100293068c.pdf
87 */
88#define BLKIF_OP_DISCARD 5
89
60/* 90/*
61 * Maximum scatter/gather segments per request. 91 * Maximum scatter/gather segments per request.
62 * This is carefully chosen so that sizeof(struct blkif_ring) <= PAGE_SIZE. 92 * This is carefully chosen so that sizeof(struct blkif_ring) <= PAGE_SIZE.
@@ -74,6 +104,11 @@ struct blkif_request_rw {
74 } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 104 } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
75}; 105};
76 106
107struct blkif_request_discard {
108 blkif_sector_t sector_number;
109 uint64_t nr_sectors;
110};
111
77struct blkif_request { 112struct blkif_request {
78 uint8_t operation; /* BLKIF_OP_??? */ 113 uint8_t operation; /* BLKIF_OP_??? */
79 uint8_t nr_segments; /* number of segments */ 114 uint8_t nr_segments; /* number of segments */
@@ -81,6 +116,7 @@ struct blkif_request {
81 uint64_t id; /* private guest value, echoed in resp */ 116 uint64_t id; /* private guest value, echoed in resp */
82 union { 117 union {
83 struct blkif_request_rw rw; 118 struct blkif_request_rw rw;
119 struct blkif_request_discard discard;
84 } u; 120 } u;
85}; 121};
86 122
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 12b7458f23b1..aa39dd7a3846 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -15,6 +15,7 @@
15#include <linux/stop_machine.h> 15#include <linux/stop_machine.h>
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/gfp.h> 17#include <linux/gfp.h>
18#include <linux/suspend.h>
18 19
19#ifdef CONFIG_SMP 20#ifdef CONFIG_SMP
20/* Serializes the updates to cpu_online_mask, cpu_present_mask */ 21/* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -476,6 +477,79 @@ static int alloc_frozen_cpus(void)
476 return 0; 477 return 0;
477} 478}
478core_initcall(alloc_frozen_cpus); 479core_initcall(alloc_frozen_cpus);
480
481/*
482 * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
483 * hotplug when tasks are about to be frozen. Also, don't allow the freezer
484 * to continue until any currently running CPU hotplug operation gets
485 * completed.
486 * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
487 * 'cpu_add_remove_lock'. And this same lock is also taken by the regular
488 * CPU hotplug path and released only after it is complete. Thus, we
489 * (and hence the freezer) will block here until any currently running CPU
490 * hotplug operation gets completed.
491 */
492void cpu_hotplug_disable_before_freeze(void)
493{
494 cpu_maps_update_begin();
495 cpu_hotplug_disabled = 1;
496 cpu_maps_update_done();
497}
498
499
500/*
501 * When tasks have been thawed, re-enable regular CPU hotplug (which had been
502 * disabled while beginning to freeze tasks).
503 */
504void cpu_hotplug_enable_after_thaw(void)
505{
506 cpu_maps_update_begin();
507 cpu_hotplug_disabled = 0;
508 cpu_maps_update_done();
509}
510
511/*
512 * When callbacks for CPU hotplug notifications are being executed, we must
513 * ensure that the state of the system with respect to the tasks being frozen
514 * or not, as reported by the notification, remains unchanged *throughout the
515 * duration* of the execution of the callbacks.
516 * Hence we need to prevent the freezer from racing with regular CPU hotplug.
517 *
518 * This synchronization is implemented by mutually excluding regular CPU
519 * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
520 * Hibernate notifications.
521 */
522static int
523cpu_hotplug_pm_callback(struct notifier_block *nb,
524 unsigned long action, void *ptr)
525{
526 switch (action) {
527
528 case PM_SUSPEND_PREPARE:
529 case PM_HIBERNATION_PREPARE:
530 cpu_hotplug_disable_before_freeze();
531 break;
532
533 case PM_POST_SUSPEND:
534 case PM_POST_HIBERNATION:
535 cpu_hotplug_enable_after_thaw();
536 break;
537
538 default:
539 return NOTIFY_DONE;
540 }
541
542 return NOTIFY_OK;
543}
544
545
546int cpu_hotplug_pm_sync_init(void)
547{
548 pm_notifier(cpu_hotplug_pm_callback, 0);
549 return 0;
550}
551core_initcall(cpu_hotplug_pm_sync_init);
552
479#endif /* CONFIG_PM_SLEEP_SMP */ 553#endif /* CONFIG_PM_SLEEP_SMP */
480 554
481/** 555/**
diff --git a/kernel/freezer.c b/kernel/freezer.c
index 66a594e8ad2f..7b01de98bb6a 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -67,7 +67,7 @@ static void fake_signal_wake_up(struct task_struct *p)
67 unsigned long flags; 67 unsigned long flags;
68 68
69 spin_lock_irqsave(&p->sighand->siglock, flags); 69 spin_lock_irqsave(&p->sighand->siglock, flags);
70 signal_wake_up(p, 1); 70 signal_wake_up(p, 0);
71 spin_unlock_irqrestore(&p->sighand->siglock, flags); 71 spin_unlock_irqrestore(&p->sighand->siglock, flags);
72} 72}
73 73
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 1c1797dd1d1d..5167d996cd02 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -386,8 +386,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
386 pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE); 386 pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
387 filp->private_data = req; 387 filp->private_data = req;
388 388
389 if (filp->private_data) 389 return 0;
390 return 0;
391 } 390 }
392 return -EPERM; 391 return -EPERM;
393} 392}
diff --git a/kernel/sched.c b/kernel/sched.c
index d87c6e5d4e8c..0e9344a71be3 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7087,8 +7087,6 @@ static int __init isolated_cpu_setup(char *str)
7087 7087
7088__setup("isolcpus=", isolated_cpu_setup); 7088__setup("isolcpus=", isolated_cpu_setup);
7089 7089
7090#define SD_NODES_PER_DOMAIN 16
7091
7092#ifdef CONFIG_NUMA 7090#ifdef CONFIG_NUMA
7093 7091
7094/** 7092/**
diff --git a/mm/bounce.c b/mm/bounce.c
index 1481de68184b..434fb4f0c5e4 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/hash.h> 15#include <linux/hash.h>
16#include <linux/highmem.h> 16#include <linux/highmem.h>
17#include <linux/bootmem.h>
17#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
18 19
19#include <trace/events/block.h> 20#include <trace/events/block.h>
@@ -26,12 +27,10 @@ static mempool_t *page_pool, *isa_page_pool;
26#ifdef CONFIG_HIGHMEM 27#ifdef CONFIG_HIGHMEM
27static __init int init_emergency_pool(void) 28static __init int init_emergency_pool(void)
28{ 29{
29 struct sysinfo i; 30#ifndef CONFIG_MEMORY_HOTPLUG
30 si_meminfo(&i); 31 if (max_pfn <= max_low_pfn)
31 si_swapinfo(&i);
32
33 if (!i.totalhigh)
34 return 0; 32 return 0;
33#endif
35 34
36 page_pool = mempool_create_page_pool(POOL_SIZE, 0); 35 page_pool = mempool_create_page_pool(POOL_SIZE, 0);
37 BUG_ON(!page_pool); 36 BUG_ON(!page_pool);
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 4cb70dc6e7ad..e50502d8ceb7 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -129,6 +129,9 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
129 for (i = 0; i < groups ; i++) 129 for (i = 0; i < groups ; i++)
130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) 130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
131 return 0; 131 return 0;
132 if (groups < NFS_NGROUPS &&
133 cred->uc_gids[groups] != NOGROUP)
134 return 0;
132 return 1; 135 return 1;
133} 136}
134 137
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index f588b852d41c..8761bf8e36fc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -114,6 +114,9 @@ static struct rpc_program rpcb_program;
114static struct rpc_clnt * rpcb_local_clnt; 114static struct rpc_clnt * rpcb_local_clnt;
115static struct rpc_clnt * rpcb_local_clnt4; 115static struct rpc_clnt * rpcb_local_clnt4;
116 116
117DEFINE_SPINLOCK(rpcb_clnt_lock);
118unsigned int rpcb_users;
119
117struct rpcbind_args { 120struct rpcbind_args {
118 struct rpc_xprt * r_xprt; 121 struct rpc_xprt * r_xprt;
119 122
@@ -161,6 +164,56 @@ static void rpcb_map_release(void *data)
161 kfree(map); 164 kfree(map);
162} 165}
163 166
167static int rpcb_get_local(void)
168{
169 int cnt;
170
171 spin_lock(&rpcb_clnt_lock);
172 if (rpcb_users)
173 rpcb_users++;
174 cnt = rpcb_users;
175 spin_unlock(&rpcb_clnt_lock);
176
177 return cnt;
178}
179
180void rpcb_put_local(void)
181{
182 struct rpc_clnt *clnt = rpcb_local_clnt;
183 struct rpc_clnt *clnt4 = rpcb_local_clnt4;
184 int shutdown;
185
186 spin_lock(&rpcb_clnt_lock);
187 if (--rpcb_users == 0) {
188 rpcb_local_clnt = NULL;
189 rpcb_local_clnt4 = NULL;
190 }
191 shutdown = !rpcb_users;
192 spin_unlock(&rpcb_clnt_lock);
193
194 if (shutdown) {
195 /*
196 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
197 */
198 if (clnt4)
199 rpc_shutdown_client(clnt4);
200 if (clnt)
201 rpc_shutdown_client(clnt);
202 }
203}
204
205static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
206{
207 /* Protected by rpcb_create_local_mutex */
208 rpcb_local_clnt = clnt;
209 rpcb_local_clnt4 = clnt4;
210 smp_wmb();
211 rpcb_users = 1;
212 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
213 "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
214 rpcb_local_clnt4);
215}
216
164/* 217/*
165 * Returns zero on success, otherwise a negative errno value 218 * Returns zero on success, otherwise a negative errno value
166 * is returned. 219 * is returned.
@@ -205,9 +258,7 @@ static int rpcb_create_local_unix(void)
205 clnt4 = NULL; 258 clnt4 = NULL;
206 } 259 }
207 260
208 /* Protected by rpcb_create_local_mutex */ 261 rpcb_set_local(clnt, clnt4);
209 rpcb_local_clnt = clnt;
210 rpcb_local_clnt4 = clnt4;
211 262
212out: 263out:
213 return result; 264 return result;
@@ -259,9 +310,7 @@ static int rpcb_create_local_net(void)
259 clnt4 = NULL; 310 clnt4 = NULL;
260 } 311 }
261 312
262 /* Protected by rpcb_create_local_mutex */ 313 rpcb_set_local(clnt, clnt4);
263 rpcb_local_clnt = clnt;
264 rpcb_local_clnt4 = clnt4;
265 314
266out: 315out:
267 return result; 316 return result;
@@ -271,16 +320,16 @@ out:
271 * Returns zero on success, otherwise a negative errno value 320 * Returns zero on success, otherwise a negative errno value
272 * is returned. 321 * is returned.
273 */ 322 */
274static int rpcb_create_local(void) 323int rpcb_create_local(void)
275{ 324{
276 static DEFINE_MUTEX(rpcb_create_local_mutex); 325 static DEFINE_MUTEX(rpcb_create_local_mutex);
277 int result = 0; 326 int result = 0;
278 327
279 if (rpcb_local_clnt) 328 if (rpcb_get_local())
280 return result; 329 return result;
281 330
282 mutex_lock(&rpcb_create_local_mutex); 331 mutex_lock(&rpcb_create_local_mutex);
283 if (rpcb_local_clnt) 332 if (rpcb_get_local())
284 goto out; 333 goto out;
285 334
286 if (rpcb_create_local_unix() != 0) 335 if (rpcb_create_local_unix() != 0)
@@ -382,11 +431,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
382 struct rpc_message msg = { 431 struct rpc_message msg = {
383 .rpc_argp = &map, 432 .rpc_argp = &map,
384 }; 433 };
385 int error;
386
387 error = rpcb_create_local();
388 if (error)
389 return error;
390 434
391 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 435 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
392 "rpcbind\n", (port ? "" : "un"), 436 "rpcbind\n", (port ? "" : "un"),
@@ -522,11 +566,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
522 struct rpc_message msg = { 566 struct rpc_message msg = {
523 .rpc_argp = &map, 567 .rpc_argp = &map,
524 }; 568 };
525 int error;
526 569
527 error = rpcb_create_local();
528 if (error)
529 return error;
530 if (rpcb_local_clnt4 == NULL) 570 if (rpcb_local_clnt4 == NULL)
531 return -EPROTONOSUPPORT; 571 return -EPROTONOSUPPORT;
532 572
@@ -1060,15 +1100,3 @@ static struct rpc_program rpcb_program = {
1060 .version = rpcb_version, 1100 .version = rpcb_version,
1061 .stats = &rpcb_stats, 1101 .stats = &rpcb_stats,
1062}; 1102};
1063
1064/**
1065 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
1066 *
1067 */
1068void cleanup_rpcb_clnt(void)
1069{
1070 if (rpcb_local_clnt4)
1071 rpc_shutdown_client(rpcb_local_clnt4);
1072 if (rpcb_local_clnt)
1073 rpc_shutdown_client(rpcb_local_clnt);
1074}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9d0809160994..8ec9778c3f4a 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -61,8 +61,6 @@ static struct pernet_operations sunrpc_net_ops = {
61 61
62extern struct cache_detail unix_gid_cache; 62extern struct cache_detail unix_gid_cache;
63 63
64extern void cleanup_rpcb_clnt(void);
65
66static int __init 64static int __init
67init_sunrpc(void) 65init_sunrpc(void)
68{ 66{
@@ -102,7 +100,6 @@ out:
102static void __exit 100static void __exit
103cleanup_sunrpc(void) 101cleanup_sunrpc(void)
104{ 102{
105 cleanup_rpcb_clnt();
106 rpcauth_remove_module(); 103 rpcauth_remove_module();
107 cleanup_socket_xprt(); 104 cleanup_socket_xprt();
108 svc_cleanup_xprt_sock(); 105 svc_cleanup_xprt_sock();
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index dd5cc00ed559..6e038884ae0c 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -366,6 +366,42 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
366 return &serv->sv_pools[pidx % serv->sv_nrpools]; 366 return &serv->sv_pools[pidx % serv->sv_nrpools];
367} 367}
368 368
369static int svc_rpcb_setup(struct svc_serv *serv)
370{
371 int err;
372
373 err = rpcb_create_local();
374 if (err)
375 return err;
376
377 /* Remove any stale portmap registrations */
378 svc_unregister(serv);
379 return 0;
380}
381
382void svc_rpcb_cleanup(struct svc_serv *serv)
383{
384 svc_unregister(serv);
385 rpcb_put_local();
386}
387EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
388
389static int svc_uses_rpcbind(struct svc_serv *serv)
390{
391 struct svc_program *progp;
392 unsigned int i;
393
394 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
395 for (i = 0; i < progp->pg_nvers; i++) {
396 if (progp->pg_vers[i] == NULL)
397 continue;
398 if (progp->pg_vers[i]->vs_hidden == 0)
399 return 1;
400 }
401 }
402
403 return 0;
404}
369 405
370/* 406/*
371 * Create an RPC service 407 * Create an RPC service
@@ -431,8 +467,15 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
431 spin_lock_init(&pool->sp_lock); 467 spin_lock_init(&pool->sp_lock);
432 } 468 }
433 469
434 /* Remove any stale portmap registrations */ 470 if (svc_uses_rpcbind(serv)) {
435 svc_unregister(serv); 471 if (svc_rpcb_setup(serv) < 0) {
472 kfree(serv->sv_pools);
473 kfree(serv);
474 return NULL;
475 }
476 if (!serv->sv_shutdown)
477 serv->sv_shutdown = svc_rpcb_cleanup;
478 }
436 479
437 return serv; 480 return serv;
438} 481}
@@ -500,7 +543,6 @@ svc_destroy(struct svc_serv *serv)
500 if (svc_serv_is_pooled(serv)) 543 if (svc_serv_is_pooled(serv))
501 svc_pool_map_put(); 544 svc_pool_map_put();
502 545
503 svc_unregister(serv);
504 kfree(serv->sv_pools); 546 kfree(serv->sv_pools);
505 kfree(serv); 547 kfree(serv);
506} 548}
diff --git a/sound/core/control.c b/sound/core/control.c
index 978fe1a8e9f0..59edb12dd542 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1081,12 +1081,12 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
1081 char *names, *p; 1081 char *names, *p;
1082 size_t buf_len, name_len; 1082 size_t buf_len, name_len;
1083 unsigned int i; 1083 unsigned int i;
1084 const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
1084 1085
1085 if (ue->info.value.enumerated.names_length > 64 * 1024) 1086 if (ue->info.value.enumerated.names_length > 64 * 1024)
1086 return -EINVAL; 1087 return -EINVAL;
1087 1088
1088 names = memdup_user( 1089 names = memdup_user((const void __user *)user_ptrval,
1089 (const void __user *)ue->info.value.enumerated.names_ptr,
1090 ue->info.value.enumerated.names_length); 1090 ue->info.value.enumerated.names_length);
1091 if (IS_ERR(names)) 1091 if (IS_ERR(names))
1092 return PTR_ERR(names); 1092 return PTR_ERR(names);
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index a70ee7f1ed98..031e215b6dde 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -272,7 +272,14 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
272 if (get_user(device, (int __user *)arg)) 272 if (get_user(device, (int __user *)arg))
273 return -EFAULT; 273 return -EFAULT;
274 mutex_lock(&register_mutex); 274 mutex_lock(&register_mutex);
275 device = device < 0 ? 0 : device + 1; 275
276 if (device < 0)
277 device = 0;
278 else if (device < SNDRV_MINOR_HWDEPS)
279 device++;
280 else
281 device = SNDRV_MINOR_HWDEPS;
282
276 while (device < SNDRV_MINOR_HWDEPS) { 283 while (device < SNDRV_MINOR_HWDEPS) {
277 if (snd_hwdep_search(card, device)) 284 if (snd_hwdep_search(card, device))
278 break; 285 break;
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 72e5885007cc..7e7d0788ddcf 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -756,8 +756,6 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw)
756 } 756 }
757 if (!fw->size) 757 if (!fw->size)
758 return 0; 758 return 0;
759 if (size < fw->size)
760 size = fw->size;
761 759
762 for (len = 0; len < fw->size; len++) { 760 for (len = 0; len < fw->size; len++) {
763 if (!*p) 761 if (!*p)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bd7fc99af187..096507d2ca9a 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -3063,12 +3063,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3063 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 3063 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3064 .class_mask = 0xffffff, 3064 .class_mask = 0xffffff,
3065 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 3065 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
3066 AZX_DCAPS_RIRB_PRE_DELAY }, 3066 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
3067#else 3067#else
3068 /* this entry seems still valid -- i.e. without emu20kx chip */ 3068 /* this entry seems still valid -- i.e. without emu20kx chip */
3069 { PCI_DEVICE(0x1102, 0x0009), 3069 { PCI_DEVICE(0x1102, 0x0009),
3070 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 3070 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
3071 AZX_DCAPS_RIRB_PRE_DELAY }, 3071 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
3072#endif 3072#endif
3073 /* Vortex86MX */ 3073 /* Vortex86MX */
3074 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, 3074 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 81e12c0ed0a2..dcbea0da0fa2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -442,6 +442,8 @@ struct auto_pin_cfg {
442 (cfg & AC_DEFCFG_SEQUENCE) 442 (cfg & AC_DEFCFG_SEQUENCE)
443#define get_defcfg_device(cfg) \ 443#define get_defcfg_device(cfg) \
444 ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) 444 ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
445#define get_defcfg_misc(cfg) \
446 ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
445 447
446/* bit-flags for snd_hda_parse_pin_def_config() behavior */ 448/* bit-flags for snd_hda_parse_pin_def_config() behavior */
447#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ 449#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
@@ -509,6 +511,11 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
509static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) 511static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
510{ 512{
511 return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && 513 return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
514 /* disable MISC_NO_PRESENCE check because it may break too
515 * many devices
516 */
517 /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) &
518 AC_DEFCFG_MISC_NO_PRESENCE)) &&*/
512 (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); 519 (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
513} 520}
514 521
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 342540128fb8..aac3bfacda3f 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1006,7 +1006,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1006 unsigned int caps, config; 1006 unsigned int caps, config;
1007 int pin_idx; 1007 int pin_idx;
1008 struct hdmi_spec_per_pin *per_pin; 1008 struct hdmi_spec_per_pin *per_pin;
1009 struct hdmi_eld *eld;
1010 int err; 1009 int err;
1011 1010
1012 caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP); 1011 caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
@@ -1023,7 +1022,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1023 1022
1024 pin_idx = spec->num_pins; 1023 pin_idx = spec->num_pins;
1025 per_pin = &spec->pins[pin_idx]; 1024 per_pin = &spec->pins[pin_idx];
1026 eld = &per_pin->sink_eld;
1027 1025
1028 per_pin->pin_nid = pin_nid; 1026 per_pin->pin_nid = pin_nid;
1029 1027
@@ -1576,7 +1574,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1576 struct snd_pcm_substream *substream) 1574 struct snd_pcm_substream *substream)
1577{ 1575{
1578 int chs; 1576 int chs;
1579 unsigned int dataDCC1, dataDCC2, channel_id; 1577 unsigned int dataDCC2, channel_id;
1580 int i; 1578 int i;
1581 struct hdmi_spec *spec = codec->spec; 1579 struct hdmi_spec *spec = codec->spec;
1582 struct hda_spdif_out *spdif = 1580 struct hda_spdif_out *spdif =
@@ -1586,7 +1584,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1586 1584
1587 chs = substream->runtime->channels; 1585 chs = substream->runtime->channels;
1588 1586
1589 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
1590 dataDCC2 = 0x2; 1587 dataDCC2 = 0x2;
1591 1588
1592 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 1589 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8f93b97559a5..9693059dec84 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1604,27 +1604,29 @@ static void alc_auto_init_digital(struct hda_codec *codec)
1604static void alc_auto_parse_digital(struct hda_codec *codec) 1604static void alc_auto_parse_digital(struct hda_codec *codec)
1605{ 1605{
1606 struct alc_spec *spec = codec->spec; 1606 struct alc_spec *spec = codec->spec;
1607 int i, err; 1607 int i, err, nums;
1608 hda_nid_t dig_nid; 1608 hda_nid_t dig_nid;
1609 1609
1610 /* support multiple SPDIFs; the secondary is set up as a slave */ 1610 /* support multiple SPDIFs; the secondary is set up as a slave */
1611 nums = 0;
1611 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1612 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1612 hda_nid_t conn[4]; 1613 hda_nid_t conn[4];
1613 err = snd_hda_get_connections(codec, 1614 err = snd_hda_get_connections(codec,
1614 spec->autocfg.dig_out_pins[i], 1615 spec->autocfg.dig_out_pins[i],
1615 conn, ARRAY_SIZE(conn)); 1616 conn, ARRAY_SIZE(conn));
1616 if (err < 0) 1617 if (err <= 0)
1617 continue; 1618 continue;
1618 dig_nid = conn[0]; /* assume the first element is audio-out */ 1619 dig_nid = conn[0]; /* assume the first element is audio-out */
1619 if (!i) { 1620 if (!nums) {
1620 spec->multiout.dig_out_nid = dig_nid; 1621 spec->multiout.dig_out_nid = dig_nid;
1621 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1622 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1622 } else { 1623 } else {
1623 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1624 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1624 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1625 if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1625 break; 1626 break;
1626 spec->slave_dig_outs[i - 1] = dig_nid; 1627 spec->slave_dig_outs[nums - 1] = dig_nid;
1627 } 1628 }
1629 nums++;
1628 } 1630 }
1629 1631
1630 if (spec->autocfg.dig_in_pin) { 1632 if (spec->autocfg.dig_in_pin) {
@@ -2270,6 +2272,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2270 struct alc_spec *spec = codec->spec; 2272 struct alc_spec *spec = codec->spec;
2271 struct hda_pcm *info = spec->pcm_rec; 2273 struct hda_pcm *info = spec->pcm_rec;
2272 const struct hda_pcm_stream *p; 2274 const struct hda_pcm_stream *p;
2275 bool have_multi_adcs;
2273 int i; 2276 int i;
2274 2277
2275 codec->num_pcms = 1; 2278 codec->num_pcms = 1;
@@ -2348,8 +2351,11 @@ static int alc_build_pcms(struct hda_codec *codec)
2348 /* If the use of more than one ADC is requested for the current 2351 /* If the use of more than one ADC is requested for the current
2349 * model, configure a second analog capture-only PCM. 2352 * model, configure a second analog capture-only PCM.
2350 */ 2353 */
2354 have_multi_adcs = (spec->num_adc_nids > 1) &&
2355 !spec->dyn_adc_switch && !spec->auto_mic &&
2356 (!spec->input_mux || spec->input_mux->num_items > 1);
2351 /* Additional Analaog capture for index #2 */ 2357 /* Additional Analaog capture for index #2 */
2352 if (spec->alt_dac_nid || spec->num_adc_nids > 1) { 2358 if (spec->alt_dac_nid || have_multi_adcs) {
2353 codec->num_pcms = 3; 2359 codec->num_pcms = 3;
2354 info = spec->pcm_rec + 2; 2360 info = spec->pcm_rec + 2;
2355 info->name = spec->stream_name_analog; 2361 info->name = spec->stream_name_analog;
@@ -2365,7 +2371,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2365 alc_pcm_null_stream; 2371 alc_pcm_null_stream;
2366 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2372 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2367 } 2373 }
2368 if (spec->num_adc_nids > 1) { 2374 if (have_multi_adcs) {
2369 p = spec->stream_analog_alt_capture; 2375 p = spec->stream_analog_alt_capture;
2370 if (!p) 2376 if (!p)
2371 p = &alc_pcm_analog_alt_capture; 2377 p = &alc_pcm_analog_alt_capture;
@@ -2657,7 +2663,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2657 hda_nid_t *adc_nids = spec->private_adc_nids; 2663 hda_nid_t *adc_nids = spec->private_adc_nids;
2658 hda_nid_t *cap_nids = spec->private_capsrc_nids; 2664 hda_nid_t *cap_nids = spec->private_capsrc_nids;
2659 int max_nums = ARRAY_SIZE(spec->private_adc_nids); 2665 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2660 bool indep_capsrc = false;
2661 int i, nums = 0; 2666 int i, nums = 0;
2662 2667
2663 nid = codec->start_nid; 2668 nid = codec->start_nid;
@@ -2679,13 +2684,11 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2679 break; 2684 break;
2680 if (type == AC_WID_AUD_SEL) { 2685 if (type == AC_WID_AUD_SEL) {
2681 cap_nids[nums] = src; 2686 cap_nids[nums] = src;
2682 indep_capsrc = true;
2683 break; 2687 break;
2684 } 2688 }
2685 n = snd_hda_get_conn_list(codec, src, &list); 2689 n = snd_hda_get_conn_list(codec, src, &list);
2686 if (n > 1) { 2690 if (n > 1) {
2687 cap_nids[nums] = src; 2691 cap_nids[nums] = src;
2688 indep_capsrc = true;
2689 break; 2692 break;
2690 } else if (n != 1) 2693 } else if (n != 1)
2691 break; 2694 break;
@@ -3326,6 +3329,12 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
3326 if (nid) 3329 if (nid)
3327 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3330 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3328 AMP_OUT_ZERO); 3331 AMP_OUT_ZERO);
3332
3333 /* unmute DAC if it's not assigned to a mixer */
3334 nid = alc_look_for_out_mute_nid(codec, pin, dac);
3335 if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
3336 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3337 AMP_OUT_ZERO);
3329} 3338}
3330 3339
3331static void alc_auto_init_multi_out(struct hda_codec *codec) 3340static void alc_auto_init_multi_out(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 59a52a430f24..de4c36027cbe 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -3791,9 +3791,10 @@ static int is_dual_headphones(struct hda_codec *codec)
3791} 3791}
3792 3792
3793 3793
3794static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) 3794static int stac92xx_parse_auto_config(struct hda_codec *codec)
3795{ 3795{
3796 struct sigmatel_spec *spec = codec->spec; 3796 struct sigmatel_spec *spec = codec->spec;
3797 hda_nid_t dig_out = 0, dig_in = 0;
3797 int hp_swap = 0; 3798 int hp_swap = 0;
3798 int i, err; 3799 int i, err;
3799 3800
@@ -3976,6 +3977,22 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3976 if (spec->multiout.max_channels > 2) 3977 if (spec->multiout.max_channels > 2)
3977 spec->surr_switch = 1; 3978 spec->surr_switch = 1;
3978 3979
3980 /* find digital out and in converters */
3981 for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) {
3982 unsigned int wid_caps = get_wcaps(codec, i);
3983 if (wid_caps & AC_WCAP_DIGITAL) {
3984 switch (get_wcaps_type(wid_caps)) {
3985 case AC_WID_AUD_OUT:
3986 if (!dig_out)
3987 dig_out = i;
3988 break;
3989 case AC_WID_AUD_IN:
3990 if (!dig_in)
3991 dig_in = i;
3992 break;
3993 }
3994 }
3995 }
3979 if (spec->autocfg.dig_outs) 3996 if (spec->autocfg.dig_outs)
3980 spec->multiout.dig_out_nid = dig_out; 3997 spec->multiout.dig_out_nid = dig_out;
3981 if (dig_in && spec->autocfg.dig_in_pin) 3998 if (dig_in && spec->autocfg.dig_in_pin)
@@ -5279,7 +5296,7 @@ static int patch_stac925x(struct hda_codec *codec)
5279 spec->capvols = stac925x_capvols; 5296 spec->capvols = stac925x_capvols;
5280 spec->capsws = stac925x_capsws; 5297 spec->capsws = stac925x_capsws;
5281 5298
5282 err = stac92xx_parse_auto_config(codec, 0x8, 0x7); 5299 err = stac92xx_parse_auto_config(codec);
5283 if (!err) { 5300 if (!err) {
5284 if (spec->board_config < 0) { 5301 if (spec->board_config < 0) {
5285 printk(KERN_WARNING "hda_codec: No auto-config is " 5302 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -5420,7 +5437,7 @@ again:
5420 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); 5437 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
5421 spec->pwr_nids = stac92hd73xx_pwr_nids; 5438 spec->pwr_nids = stac92hd73xx_pwr_nids;
5422 5439
5423 err = stac92xx_parse_auto_config(codec, 0x25, 0x27); 5440 err = stac92xx_parse_auto_config(codec);
5424 5441
5425 if (!err) { 5442 if (!err) {
5426 if (spec->board_config < 0) { 5443 if (spec->board_config < 0) {
@@ -5629,26 +5646,8 @@ again:
5629 stac92xx_set_config_regs(codec, 5646 stac92xx_set_config_regs(codec,
5630 stac92hd83xxx_brd_tbl[spec->board_config]); 5647 stac92hd83xxx_brd_tbl[spec->board_config]);
5631 5648
5632 switch (codec->vendor_id) { 5649 if (spec->board_config != STAC_92HD83XXX_PWR_REF)
5633 case 0x111d76d1:
5634 case 0x111d76d9:
5635 case 0x111d76df:
5636 case 0x111d76e5:
5637 case 0x111d7666:
5638 case 0x111d7667:
5639 case 0x111d7668:
5640 case 0x111d7669:
5641 case 0x111d76e3:
5642 case 0x111d7604:
5643 case 0x111d76d4:
5644 case 0x111d7605:
5645 case 0x111d76d5:
5646 case 0x111d76e7:
5647 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5648 break;
5649 spec->num_pwrs = 0; 5650 spec->num_pwrs = 0;
5650 break;
5651 }
5652 5651
5653 codec->patch_ops = stac92xx_patch_ops; 5652 codec->patch_ops = stac92xx_patch_ops;
5654 5653
@@ -5675,7 +5674,7 @@ again:
5675 } 5674 }
5676#endif 5675#endif
5677 5676
5678 err = stac92xx_parse_auto_config(codec, 0x1d, 0); 5677 err = stac92xx_parse_auto_config(codec);
5679 if (!err) { 5678 if (!err) {
5680 if (spec->board_config < 0) { 5679 if (spec->board_config < 0) {
5681 printk(KERN_WARNING "hda_codec: No auto-config is " 5680 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -5996,7 +5995,7 @@ again:
5996 5995
5997 spec->multiout.dac_nids = spec->dac_nids; 5996 spec->multiout.dac_nids = spec->dac_nids;
5998 5997
5999 err = stac92xx_parse_auto_config(codec, 0x21, 0); 5998 err = stac92xx_parse_auto_config(codec);
6000 if (!err) { 5999 if (!err) {
6001 if (spec->board_config < 0) { 6000 if (spec->board_config < 0) {
6002 printk(KERN_WARNING "hda_codec: No auto-config is " 6001 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6105,7 +6104,7 @@ static int patch_stac922x(struct hda_codec *codec)
6105 6104
6106 spec->multiout.dac_nids = spec->dac_nids; 6105 spec->multiout.dac_nids = spec->dac_nids;
6107 6106
6108 err = stac92xx_parse_auto_config(codec, 0x08, 0x09); 6107 err = stac92xx_parse_auto_config(codec);
6109 if (!err) { 6108 if (!err) {
6110 if (spec->board_config < 0) { 6109 if (spec->board_config < 0) {
6111 printk(KERN_WARNING "hda_codec: No auto-config is " 6110 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6230,7 +6229,7 @@ static int patch_stac927x(struct hda_codec *codec)
6230 spec->aloopback_shift = 0; 6229 spec->aloopback_shift = 0;
6231 spec->eapd_switch = 1; 6230 spec->eapd_switch = 1;
6232 6231
6233 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); 6232 err = stac92xx_parse_auto_config(codec);
6234 if (!err) { 6233 if (!err) {
6235 if (spec->board_config < 0) { 6234 if (spec->board_config < 0) {
6236 printk(KERN_WARNING "hda_codec: No auto-config is " 6235 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6355,7 +6354,7 @@ static int patch_stac9205(struct hda_codec *codec)
6355 break; 6354 break;
6356 } 6355 }
6357 6356
6358 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); 6357 err = stac92xx_parse_auto_config(codec);
6359 if (!err) { 6358 if (!err) {
6360 if (spec->board_config < 0) { 6359 if (spec->board_config < 0) {
6361 printk(KERN_WARNING "hda_codec: No auto-config is " 6360 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6460,7 +6459,7 @@ static int patch_stac9872(struct hda_codec *codec)
6460 spec->capvols = stac9872_capvols; 6459 spec->capvols = stac9872_capvols;
6461 spec->capsws = stac9872_capsws; 6460 spec->capsws = stac9872_capsws;
6462 6461
6463 err = stac92xx_parse_auto_config(codec, 0x10, 0x12); 6462 err = stac92xx_parse_auto_config(codec);
6464 if (err < 0) { 6463 if (err < 0) {
6465 stac92xx_free(codec); 6464 stac92xx_free(codec);
6466 return -EINVAL; 6465 return -EINVAL;
@@ -6565,6 +6564,18 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6565 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, 6564 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
6566 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, 6565 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
6567 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, 6566 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
6567 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
6568 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
6569 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
6570 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
6571 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
6572 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
6573 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
6574 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
6575 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
6576 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
6577 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
6578 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
6568 {} /* terminator */ 6579 {} /* terminator */
6569}; 6580};
6570 6581
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 417d62ad3b96..0b020a93a8ed 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -3700,13 +3700,8 @@ static const struct hda_verb vt1812_init_verbs[] = {
3700static void set_widgets_power_state_vt1812(struct hda_codec *codec) 3700static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3701{ 3701{
3702 struct via_spec *spec = codec->spec; 3702 struct via_spec *spec = codec->spec;
3703 int imux_is_smixer =
3704 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3705 unsigned int parm; 3703 unsigned int parm;
3706 unsigned int present; 3704 unsigned int present;
3707 /* MUX10 (1eh) = stereo mixer */
3708 imux_is_smixer =
3709 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
3710 /* inputs */ 3705 /* inputs */
3711 /* PW 5/6/7 (29h/2ah/2bh) */ 3706 /* PW 5/6/7 (29h/2ah/2bh) */
3712 parm = AC_PWRST_D3; 3707 parm = AC_PWRST_D3;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 6a5b387b97fd..45b2055f5a76 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -42,6 +42,12 @@
42#include <asm/pgtable.h> 42#include <asm/pgtable.h>
43#include <asm/cacheflush.h> 43#include <asm/cacheflush.h>
44 44
45#ifdef CONFIG_KVM_GUEST
46#include <linux/kvm_para.h>
47#else
48#define kvm_para_available() (0)
49#endif
50
45MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 51MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
46MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); 52MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
47MODULE_LICENSE("GPL"); 53MODULE_LICENSE("GPL");
@@ -77,6 +83,7 @@ static int buggy_semaphore;
77static int buggy_irq = -1; /* auto-check */ 83static int buggy_irq = -1; /* auto-check */
78static int xbox; 84static int xbox;
79static int spdif_aclink = -1; 85static int spdif_aclink = -1;
86static int inside_vm = -1;
80 87
81module_param(index, int, 0444); 88module_param(index, int, 0444);
82MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); 89MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -94,6 +101,8 @@ module_param(xbox, bool, 0444);
94MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); 101MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
95module_param(spdif_aclink, int, 0444); 102module_param(spdif_aclink, int, 0444);
96MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); 103MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
104module_param(inside_vm, bool, 0444);
105MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization.");
97 106
98/* just for backward compatibility */ 107/* just for backward compatibility */
99static int enable; 108static int enable;
@@ -400,6 +409,7 @@ struct intel8x0 {
400 unsigned buggy_irq: 1; /* workaround for buggy mobos */ 409 unsigned buggy_irq: 1; /* workaround for buggy mobos */
401 unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ 410 unsigned xbox: 1; /* workaround for Xbox AC'97 detection */
402 unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */ 411 unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */
412 unsigned inside_vm: 1; /* enable VM optimization */
403 413
404 int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ 414 int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
405 unsigned int sdm_saved; /* SDM reg value */ 415 unsigned int sdm_saved; /* SDM reg value */
@@ -1065,8 +1075,11 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
1065 udelay(10); 1075 udelay(10);
1066 continue; 1076 continue;
1067 } 1077 }
1068 if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && 1078 if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV))
1069 ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) 1079 continue;
1080 if (chip->inside_vm)
1081 break;
1082 if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
1070 break; 1083 break;
1071 } while (timeout--); 1084 } while (timeout--);
1072 ptr = ichdev->last_pos; 1085 ptr = ichdev->last_pos;
@@ -2984,6 +2997,10 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
2984 if (xbox) 2997 if (xbox)
2985 chip->xbox = 1; 2998 chip->xbox = 1;
2986 2999
3000 chip->inside_vm = inside_vm;
3001 if (inside_vm)
3002 printk(KERN_INFO "intel8x0: enable KVM optimization\n");
3003
2987 if (pci->vendor == PCI_VENDOR_ID_INTEL && 3004 if (pci->vendor == PCI_VENDOR_ID_INTEL &&
2988 pci->device == PCI_DEVICE_ID_INTEL_440MX) 3005 pci->device == PCI_DEVICE_ID_INTEL_440MX)
2989 chip->fix_nocache = 1; /* enable workaround */ 3006 chip->fix_nocache = 1; /* enable workaround */
@@ -3226,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
3226 buggy_irq = 0; 3243 buggy_irq = 0;
3227 } 3244 }
3228 3245
3246 if (inside_vm < 0) {
3247 /* detect KVM and Parallels virtual environments */
3248 inside_vm = kvm_para_available();
3249#if defined(__i386__) || defined(__x86_64__)
3250 inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR);
3251#endif
3252 }
3253
3229 if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, 3254 if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
3230 &chip)) < 0) { 3255 &chip)) < 0) {
3231 snd_card_free(card); 3256 snd_card_free(card);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 1c6d1e1c27c1..f74220292254 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -151,7 +151,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
151#define HDSP_PROGRAM 0x020 151#define HDSP_PROGRAM 0x020
152#define HDSP_CONFIG_MODE_0 0x040 152#define HDSP_CONFIG_MODE_0 0x040
153#define HDSP_CONFIG_MODE_1 0x080 153#define HDSP_CONFIG_MODE_1 0x080
154#define HDSP_VERSION_BIT 0x100 154#define HDSP_VERSION_BIT (0x100 | HDSP_S_LOAD)
155#define HDSP_BIGENDIAN_MODE 0x200 155#define HDSP_BIGENDIAN_MODE 0x200
156#define HDSP_RD_MULTIPLE 0x400 156#define HDSP_RD_MULTIPLE 0x400
157#define HDSP_9652_ENABLE_MIXER 0x800 157#define HDSP_9652_ENABLE_MIXER 0x800
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 6e2f7ef7ddb1..15a6c3b9bc9a 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
520#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) 520#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
522 522
523/* revisions >= 230 indicate AES32 card */
524#define HDSPM_MADI_ANCIENT_REV 204
525#define HDSPM_MADI_OLD_REV 207
526#define HDSPM_MADI_REV 210
527#define HDSPM_RAYDAT_REV 211 523#define HDSPM_RAYDAT_REV 211
528#define HDSPM_AIO_REV 212 524#define HDSPM_AIO_REV 212
529#define HDSPM_MADIFACE_REV 213 525#define HDSPM_MADIFACE_REV 213
530#define HDSPM_AES_REV 240
531#define HDSPM_AES32_REV 234
532#define HDSPM_AES32_OLD_REV 233
533 526
534/* speed factor modes */ 527/* speed factor modes */
535#define HDSPM_SPEED_SINGLE 0 528#define HDSPM_SPEED_SINGLE 0
@@ -6253,7 +6246,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6253 status.card_specific.madi.madi_input = 6246 status.card_specific.madi.madi_input =
6254 (statusregister & HDSPM_AB_int) ? 1 : 0; 6247 (statusregister & HDSPM_AB_int) ? 1 : 0;
6255 status.card_specific.madi.channel_format = 6248 status.card_specific.madi.channel_format =
6256 (statusregister & HDSPM_TX_64ch) ? 1 : 0; 6249 (statusregister & HDSPM_RX_64ch) ? 1 : 0;
6257 /* TODO: Mac driver sets it when f_s>48kHz */ 6250 /* TODO: Mac driver sets it when f_s>48kHz */
6258 status.card_specific.madi.frame_format = 0; 6251 status.card_specific.madi.frame_format = 0;
6259 6252
@@ -6503,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
6503 strcpy(card->driver, "HDSPM"); 6496 strcpy(card->driver, "HDSPM");
6504 6497
6505 switch (hdspm->firmware_rev) { 6498 switch (hdspm->firmware_rev) {
6506 case HDSPM_MADI_REV:
6507 case HDSPM_MADI_OLD_REV:
6508 case HDSPM_MADI_ANCIENT_REV:
6509 hdspm->io_type = MADI;
6510 hdspm->card_name = "RME MADI";
6511 hdspm->midiPorts = 3;
6512 break;
6513 case HDSPM_RAYDAT_REV: 6499 case HDSPM_RAYDAT_REV:
6514 hdspm->io_type = RayDAT; 6500 hdspm->io_type = RayDAT;
6515 hdspm->card_name = "RME RayDAT"; 6501 hdspm->card_name = "RME RayDAT";
@@ -6525,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
6525 hdspm->card_name = "RME MADIface"; 6511 hdspm->card_name = "RME MADIface";
6526 hdspm->midiPorts = 1; 6512 hdspm->midiPorts = 1;
6527 break; 6513 break;
6528 case HDSPM_AES_REV:
6529 case HDSPM_AES32_REV:
6530 case HDSPM_AES32_OLD_REV:
6531 hdspm->io_type = AES32;
6532 hdspm->card_name = "RME AES32";
6533 hdspm->midiPorts = 2;
6534 break;
6535 default: 6514 default:
6536 snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n", 6515 if ((hdspm->firmware_rev == 0xf0) ||
6516 ((hdspm->firmware_rev >= 0xe6) &&
6517 (hdspm->firmware_rev <= 0xea))) {
6518 hdspm->io_type = AES32;
6519 hdspm->card_name = "RME AES32";
6520 hdspm->midiPorts = 2;
6521 } else if ((hdspm->firmware_rev == 0xd5) ||
6522 ((hdspm->firmware_rev >= 0xc8) &&
6523 (hdspm->firmware_rev <= 0xcf))) {
6524 hdspm->io_type = MADI;
6525 hdspm->card_name = "RME MADI";
6526 hdspm->midiPorts = 3;
6527 } else {
6528 snd_printk(KERN_ERR
6529 "HDSPM: unknown firmware revision %x\n",
6537 hdspm->firmware_rev); 6530 hdspm->firmware_rev);
6538 return -ENODEV; 6531 return -ENODEV;
6532 }
6539 } 6533 }
6540 6534
6541 err = pci_enable_device(pci); 6535 err = pci_enable_device(pci);
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index ab27dbcd1262..336de8f69a02 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -430,6 +430,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
430 iface_reg |= TLV320AIC23_MS_MASTER; 430 iface_reg |= TLV320AIC23_MS_MASTER;
431 break; 431 break;
432 case SND_SOC_DAIFMT_CBS_CFS: 432 case SND_SOC_DAIFMT_CBS_CFS:
433 iface_reg &= ~TLV320AIC23_MS_MASTER;
433 break; 434 break;
434 default: 435 default:
435 return -EINVAL; 436 return -EINVAL;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 7a49390bc30d..87d5ef188e29 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1023,6 +1023,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
1023 break; 1023 break;
1024 case SND_SOC_DAIFMT_CBS_CFS: 1024 case SND_SOC_DAIFMT_CBS_CFS:
1025 aic3x->master = 0; 1025 aic3x->master = 0;
1026 iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
1026 break; 1027 break;
1027 default: 1028 default:
1028 return -EINVAL; 1029 return -EINVAL;
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 5d88c99aaea6..42d9039a49e9 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2361,13 +2361,17 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2361{ 2361{
2362 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); 2362 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2363 struct snd_soc_codec *codec = wm5100->codec; 2363 struct snd_soc_codec *codec = wm5100->codec;
2364 int val; 2364 int val, ret;
2365 2365
2366 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); 2366 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2367 2367
2368 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, 2368 ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2369 WM5100_GP1_FN_MASK | WM5100_GP1_DIR | 2369 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2370 WM5100_GP1_LVL, val); 2370 WM5100_GP1_LVL, val);
2371 if (ret < 0)
2372 return ret;
2373 else
2374 return 0;
2371} 2375}
2372 2376
2373static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) 2377static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 8d0347cf0e9a..076bdb9930a1 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -151,7 +151,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
151{ 151{
152 struct snd_soc_codec *codec = dai->codec; 152 struct snd_soc_codec *codec = dai->codec;
153 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 153 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
154 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; 154 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3;
155 int i = get_coeff(wm8711->sysclk, params_rate(params)); 155 int i = get_coeff(wm8711->sysclk, params_rate(params));
156 u16 srate = (coeff_div[i].sr << 2) | 156 u16 srate = (coeff_div[i].sr << 2) |
157 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 157 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
@@ -232,7 +232,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
232 unsigned int fmt) 232 unsigned int fmt)
233{ 233{
234 struct snd_soc_codec *codec = codec_dai->codec; 234 struct snd_soc_codec *codec = codec_dai->codec;
235 u16 iface = 0; 235 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c;
236 236
237 /* set master/slave audio interface */ 237 /* set master/slave audio interface */
238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 9fc8f4c0a9a9..285ef87e6704 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -867,7 +867,7 @@ SOC_ENUM("Right Capture Mode", rin_mode),
867SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, 867SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
868 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), 868 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
869SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, 869SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
870 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0), 870 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1),
871 871
872SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 872SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
873SOC_ENUM("High Pass Filter Mode", hpf_mode), 873SOC_ENUM("High Pass Filter Mode", hpf_mode),
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index dc5cb3150857..de9ec9b8b7d9 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -621,7 +621,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
621 621
622 switch (div_id) { 622 switch (div_id) {
623 case WM8940_BCLKDIV: 623 case WM8940_BCLKDIV:
624 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3; 624 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
625 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2)); 625 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
626 break; 626 break;
627 case WM8940_MCLKDIV: 627 case WM8940_MCLKDIV:
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index f60dfa16545e..91d3c6dbeba3 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1961,7 +1961,13 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re
1961 1961
1962static int wm8962_reset(struct snd_soc_codec *codec) 1962static int wm8962_reset(struct snd_soc_codec *codec)
1963{ 1963{
1964 return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); 1964 int ret;
1965
1966 ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
1967 if (ret != 0)
1968 return ret;
1969
1970 return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0);
1965} 1971}
1966 1972
1967static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); 1973static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2360,15 +2366,14 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
2360 2366
2361 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2367 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2362 WM8962_FLL_ENA, WM8962_FLL_ENA); 2368 WM8962_FLL_ENA, WM8962_FLL_ENA);
2363 if (wm8962->irq) { 2369
2364 timeout = msecs_to_jiffies(5); 2370 timeout = msecs_to_jiffies(5);
2365 timeout = wait_for_completion_timeout(&wm8962->fll_lock, 2371 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
2366 timeout); 2372 timeout);
2367 2373
2368 if (timeout == 0) 2374 if (wm8962->irq && timeout == 0)
2369 dev_err(codec->dev, 2375 dev_err(codec->dev,
2370 "Timed out starting FLL\n"); 2376 "Timed out starting FLL\n");
2371 }
2372 } 2377 }
2373 break; 2378 break;
2374 2379
@@ -4029,6 +4034,11 @@ static int wm8962_probe(struct snd_soc_codec *codec)
4029 snd_soc_update_bits(codec, WM8962_CLOCKING2, 4034 snd_soc_update_bits(codec, WM8962_CLOCKING2,
4030 WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); 4035 WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
4031 4036
4037 /* Ensure that the oscillator and PLLs are disabled */
4038 snd_soc_update_bits(codec, WM8962_PLL2,
4039 WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
4040 0);
4041
4032 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); 4042 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
4033 4043
4034 if (pdata) { 4044 if (pdata) {
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index b5e922f469d5..bad91b4584f9 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
271 271
272 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); 272 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
273 273
274 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); 274 if (!dma_data->ops)
275 dma_data->ops = samsung_dma_get_ops();
276
277 dma_data->ops->started(dma_data->channel);
275 278
276 return 0; 279 return 0;
277} 280}
@@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
317 320
318 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); 321 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
319 322
320 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); 323 if (!dma_data->ops)
324 dma_data->ops = samsung_dma_get_ops();
325
326 dma_data->ops->started(dma_data->channel);
321 327
322 return 0; 328 return 0;
323} 329}
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 9465588b02f2..2d622b635e68 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -54,7 +54,6 @@ struct runtime_data {
54 spinlock_t lock; 54 spinlock_t lock;
55 int state; 55 int state;
56 unsigned int dma_loaded; 56 unsigned int dma_loaded;
57 unsigned int dma_limit;
58 unsigned int dma_period; 57 unsigned int dma_period;
59 dma_addr_t dma_start; 58 dma_addr_t dma_start;
60 dma_addr_t dma_pos; 59 dma_addr_t dma_pos;
@@ -62,77 +61,79 @@ struct runtime_data {
62 struct s3c_dma_params *params; 61 struct s3c_dma_params *params;
63}; 62};
64 63
64static void audio_buffdone(void *data);
65
65/* dma_enqueue 66/* dma_enqueue
66 * 67 *
67 * place a dma buffer onto the queue for the dma system 68 * place a dma buffer onto the queue for the dma system
68 * to handle. 69 * to handle.
69*/ 70 */
70static void dma_enqueue(struct snd_pcm_substream *substream) 71static void dma_enqueue(struct snd_pcm_substream *substream)
71{ 72{
72 struct runtime_data *prtd = substream->runtime->private_data; 73 struct runtime_data *prtd = substream->runtime->private_data;
73 dma_addr_t pos = prtd->dma_pos; 74 dma_addr_t pos = prtd->dma_pos;
74 unsigned int limit; 75 unsigned int limit;
75 int ret; 76 struct samsung_dma_prep_info dma_info;
76 77
77 pr_debug("Entered %s\n", __func__); 78 pr_debug("Entered %s\n", __func__);
78 79
79 if (s3c_dma_has_circular()) 80 limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
80 limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
81 else
82 limit = prtd->dma_limit;
83 81
84 pr_debug("%s: loaded %d, limit %d\n", 82 pr_debug("%s: loaded %d, limit %d\n",
85 __func__, prtd->dma_loaded, limit); 83 __func__, prtd->dma_loaded, limit);
86 84
87 while (prtd->dma_loaded < limit) { 85 dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE);
88 unsigned long len = prtd->dma_period; 86 dma_info.direction =
87 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
88 ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
89 dma_info.fp = audio_buffdone;
90 dma_info.fp_param = substream;
91 dma_info.period = prtd->dma_period;
92 dma_info.len = prtd->dma_period*limit;
89 93
94 while (prtd->dma_loaded < limit) {
90 pr_debug("dma_loaded: %d\n", prtd->dma_loaded); 95 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
91 96
92 if ((pos + len) > prtd->dma_end) { 97 if ((pos + dma_info.period) > prtd->dma_end) {
93 len = prtd->dma_end - pos; 98 dma_info.period = prtd->dma_end - pos;
94 pr_debug("%s: corrected dma len %ld\n", __func__, len); 99 pr_debug("%s: corrected dma len %ld\n",
100 __func__, dma_info.period);
95 } 101 }
96 102
97 ret = s3c2410_dma_enqueue(prtd->params->channel, 103 dma_info.buf = pos;
98 substream, pos, len); 104 prtd->params->ops->prepare(prtd->params->ch, &dma_info);
99 105
100 if (ret == 0) { 106 prtd->dma_loaded++;
101 prtd->dma_loaded++; 107 pos += prtd->dma_period;
102 pos += prtd->dma_period; 108 if (pos >= prtd->dma_end)
103 if (pos >= prtd->dma_end) 109 pos = prtd->dma_start;
104 pos = prtd->dma_start;
105 } else
106 break;
107 } 110 }
108 111
109 prtd->dma_pos = pos; 112 prtd->dma_pos = pos;
110} 113}
111 114
112static void audio_buffdone(struct s3c2410_dma_chan *channel, 115static void audio_buffdone(void *data)
113 void *dev_id, int size,
114 enum s3c2410_dma_buffresult result)
115{ 116{
116 struct snd_pcm_substream *substream = dev_id; 117 struct snd_pcm_substream *substream = data;
117 struct runtime_data *prtd; 118 struct runtime_data *prtd = substream->runtime->private_data;
118 119
119 pr_debug("Entered %s\n", __func__); 120 pr_debug("Entered %s\n", __func__);
120 121
121 if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) 122 if (prtd->state & ST_RUNNING) {
122 return; 123 prtd->dma_pos += prtd->dma_period;
123 124 if (prtd->dma_pos >= prtd->dma_end)
124 prtd = substream->runtime->private_data; 125 prtd->dma_pos = prtd->dma_start;
125 126
126 if (substream) 127 if (substream)
127 snd_pcm_period_elapsed(substream); 128 snd_pcm_period_elapsed(substream);
128 129
129 spin_lock(&prtd->lock); 130 spin_lock(&prtd->lock);
130 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { 131 if (!samsung_dma_has_circular()) {
131 prtd->dma_loaded--; 132 prtd->dma_loaded--;
132 dma_enqueue(substream); 133 dma_enqueue(substream);
134 }
135 spin_unlock(&prtd->lock);
133 } 136 }
134
135 spin_unlock(&prtd->lock);
136} 137}
137 138
138static int dma_hw_params(struct snd_pcm_substream *substream, 139static int dma_hw_params(struct snd_pcm_substream *substream,
@@ -144,8 +145,7 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
144 unsigned long totbytes = params_buffer_bytes(params); 145 unsigned long totbytes = params_buffer_bytes(params);
145 struct s3c_dma_params *dma = 146 struct s3c_dma_params *dma =
146 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 147 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
147 int ret = 0; 148 struct samsung_dma_info dma_info;
148
149 149
150 pr_debug("Entered %s\n", __func__); 150 pr_debug("Entered %s\n", __func__);
151 151
@@ -163,30 +163,26 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
163 pr_debug("params %p, client %p, channel %d\n", prtd->params, 163 pr_debug("params %p, client %p, channel %d\n", prtd->params,
164 prtd->params->client, prtd->params->channel); 164 prtd->params->client, prtd->params->channel);
165 165
166 ret = s3c2410_dma_request(prtd->params->channel, 166 prtd->params->ops = samsung_dma_get_ops();
167 prtd->params->client, NULL); 167
168 168 dma_info.cap = (samsung_dma_has_circular() ?
169 if (ret < 0) { 169 DMA_CYCLIC : DMA_SLAVE);
170 printk(KERN_ERR "failed to get dma channel\n"); 170 dma_info.client = prtd->params->client;
171 return ret; 171 dma_info.direction =
172 } 172 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
173 173 ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
174 /* use the circular buffering if we have it available. */ 174 dma_info.width = prtd->params->dma_size;
175 if (s3c_dma_has_circular()) 175 dma_info.fifo = prtd->params->dma_addr;
176 s3c2410_dma_setflags(prtd->params->channel, 176 prtd->params->ch = prtd->params->ops->request(
177 S3C2410_DMAF_CIRCULAR); 177 prtd->params->channel, &dma_info);
178 } 178 }
179 179
180 s3c2410_dma_set_buffdone_fn(prtd->params->channel,
181 audio_buffdone);
182
183 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 180 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
184 181
185 runtime->dma_bytes = totbytes; 182 runtime->dma_bytes = totbytes;
186 183
187 spin_lock_irq(&prtd->lock); 184 spin_lock_irq(&prtd->lock);
188 prtd->dma_loaded = 0; 185 prtd->dma_loaded = 0;
189 prtd->dma_limit = runtime->hw.periods_min;
190 prtd->dma_period = params_period_bytes(params); 186 prtd->dma_period = params_period_bytes(params);
191 prtd->dma_start = runtime->dma_addr; 187 prtd->dma_start = runtime->dma_addr;
192 prtd->dma_pos = prtd->dma_start; 188 prtd->dma_pos = prtd->dma_start;
@@ -202,11 +198,12 @@ static int dma_hw_free(struct snd_pcm_substream *substream)
202 198
203 pr_debug("Entered %s\n", __func__); 199 pr_debug("Entered %s\n", __func__);
204 200
205 /* TODO - do we need to ensure DMA flushed */
206 snd_pcm_set_runtime_buffer(substream, NULL); 201 snd_pcm_set_runtime_buffer(substream, NULL);
207 202
208 if (prtd->params) { 203 if (prtd->params) {
209 s3c2410_dma_free(prtd->params->channel, prtd->params->client); 204 prtd->params->ops->flush(prtd->params->ch);
205 prtd->params->ops->release(prtd->params->ch,
206 prtd->params->client);
210 prtd->params = NULL; 207 prtd->params = NULL;
211 } 208 }
212 209
@@ -225,23 +222,9 @@ static int dma_prepare(struct snd_pcm_substream *substream)
225 if (!prtd->params) 222 if (!prtd->params)
226 return 0; 223 return 0;
227 224
228 /* channel needs configuring for mem=>device, increment memory addr,
229 * sync to pclk, half-word transfers to the IIS-FIFO. */
230 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231 s3c2410_dma_devconfig(prtd->params->channel,
232 S3C2410_DMASRC_MEM,
233 prtd->params->dma_addr);
234 } else {
235 s3c2410_dma_devconfig(prtd->params->channel,
236 S3C2410_DMASRC_HW,
237 prtd->params->dma_addr);
238 }
239
240 s3c2410_dma_config(prtd->params->channel,
241 prtd->params->dma_size);
242
243 /* flush the DMA channel */ 225 /* flush the DMA channel */
244 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); 226 prtd->params->ops->flush(prtd->params->ch);
227
245 prtd->dma_loaded = 0; 228 prtd->dma_loaded = 0;
246 prtd->dma_pos = prtd->dma_start; 229 prtd->dma_pos = prtd->dma_start;
247 230
@@ -265,14 +248,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
265 case SNDRV_PCM_TRIGGER_RESUME: 248 case SNDRV_PCM_TRIGGER_RESUME:
266 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 249 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
267 prtd->state |= ST_RUNNING; 250 prtd->state |= ST_RUNNING;
268 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); 251 prtd->params->ops->trigger(prtd->params->ch);
269 break; 252 break;
270 253
271 case SNDRV_PCM_TRIGGER_STOP: 254 case SNDRV_PCM_TRIGGER_STOP:
272 case SNDRV_PCM_TRIGGER_SUSPEND: 255 case SNDRV_PCM_TRIGGER_SUSPEND:
273 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 256 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
274 prtd->state &= ~ST_RUNNING; 257 prtd->state &= ~ST_RUNNING;
275 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); 258 prtd->params->ops->stop(prtd->params->ch);
276 break; 259 break;
277 260
278 default: 261 default:
@@ -291,21 +274,12 @@ dma_pointer(struct snd_pcm_substream *substream)
291 struct snd_pcm_runtime *runtime = substream->runtime; 274 struct snd_pcm_runtime *runtime = substream->runtime;
292 struct runtime_data *prtd = runtime->private_data; 275 struct runtime_data *prtd = runtime->private_data;
293 unsigned long res; 276 unsigned long res;
294 dma_addr_t src, dst;
295 277
296 pr_debug("Entered %s\n", __func__); 278 pr_debug("Entered %s\n", __func__);
297 279
298 spin_lock(&prtd->lock); 280 res = prtd->dma_pos - prtd->dma_start;
299 s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
300
301 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
302 res = dst - prtd->dma_start;
303 else
304 res = src - prtd->dma_start;
305
306 spin_unlock(&prtd->lock);
307 281
308 pr_debug("Pointer %x %x\n", src, dst); 282 pr_debug("Pointer offset: %lu\n", res);
309 283
310 /* we seem to be getting the odd error from the pcm library due 284 /* we seem to be getting the odd error from the pcm library due
311 * to out-of-bounds pointers. this is maybe due to the dma engine 285 * to out-of-bounds pointers. this is maybe due to the dma engine
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index c50659269a40..7d1ead77ef21 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -6,7 +6,7 @@
6 * Free Software Foundation; either version 2 of the License, or (at your 6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. 7 * option) any later version.
8 * 8 *
9 * ALSA PCM interface for the Samsung S3C24xx CPU 9 * ALSA PCM interface for the Samsung SoC
10 */ 10 */
11 11
12#ifndef _S3C_AUDIO_H 12#ifndef _S3C_AUDIO_H
@@ -17,6 +17,8 @@ struct s3c_dma_params {
17 int channel; /* Channel ID */ 17 int channel; /* Channel ID */
18 dma_addr_t dma_addr; 18 dma_addr_t dma_addr;
19 int dma_size; /* Size of the DMA transfer */ 19 int dma_size; /* Size of the DMA transfer */
20 unsigned ch;
21 struct samsung_dma_ops *ops;
20}; 22};
21 23
22#endif 24#endif
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 67bec7612442..c0609c210303 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -459,7 +459,8 @@ static void kill_stream_urbs(struct ua101_stream *stream)
459 unsigned int i; 459 unsigned int i;
460 460
461 for (i = 0; i < stream->queue_length; ++i) 461 for (i = 0; i < stream->queue_length; ++i)
462 usb_kill_urb(&stream->urbs[i]->urb); 462 if (stream->urbs[i])
463 usb_kill_urb(&stream->urbs[i]->urb);
463} 464}
464 465
465static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index) 466static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index)
@@ -484,6 +485,9 @@ static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index)
484{ 485{
485 struct usb_host_interface *alts; 486 struct usb_host_interface *alts;
486 487
488 if (!ua->intf[intf_index])
489 return;
490
487 alts = ua->intf[intf_index]->cur_altsetting; 491 alts = ua->intf[intf_index]->cur_altsetting;
488 if (alts->desc.bAlternateSetting != 0) { 492 if (alts->desc.bAlternateSetting != 0) {
489 int err = usb_set_interface(ua->dev, 493 int err = usb_set_interface(ua->dev,
@@ -1144,27 +1148,37 @@ static void free_stream_urbs(struct ua101_stream *stream)
1144{ 1148{
1145 unsigned int i; 1149 unsigned int i;
1146 1150
1147 for (i = 0; i < stream->queue_length; ++i) 1151 for (i = 0; i < stream->queue_length; ++i) {
1148 kfree(stream->urbs[i]); 1152 kfree(stream->urbs[i]);
1153 stream->urbs[i] = NULL;
1154 }
1149} 1155}
1150 1156
1151static void free_usb_related_resources(struct ua101 *ua, 1157static void free_usb_related_resources(struct ua101 *ua,
1152 struct usb_interface *interface) 1158 struct usb_interface *interface)
1153{ 1159{
1154 unsigned int i; 1160 unsigned int i;
1161 struct usb_interface *intf;
1155 1162
1163 mutex_lock(&ua->mutex);
1156 free_stream_urbs(&ua->capture); 1164 free_stream_urbs(&ua->capture);
1157 free_stream_urbs(&ua->playback); 1165 free_stream_urbs(&ua->playback);
1166 mutex_unlock(&ua->mutex);
1158 free_stream_buffers(ua, &ua->capture); 1167 free_stream_buffers(ua, &ua->capture);
1159 free_stream_buffers(ua, &ua->playback); 1168 free_stream_buffers(ua, &ua->playback);
1160 1169
1161 for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) 1170 for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) {
1162 if (ua->intf[i]) { 1171 mutex_lock(&ua->mutex);
1163 usb_set_intfdata(ua->intf[i], NULL); 1172 intf = ua->intf[i];
1164 if (ua->intf[i] != interface) 1173 ua->intf[i] = NULL;
1174 mutex_unlock(&ua->mutex);
1175 if (intf) {
1176 usb_set_intfdata(intf, NULL);
1177 if (intf != interface)
1165 usb_driver_release_interface(&ua101_driver, 1178 usb_driver_release_interface(&ua101_driver,
1166 ua->intf[i]); 1179 intf);
1167 } 1180 }
1181 }
1168} 1182}
1169 1183
1170static void ua101_card_free(struct snd_card *card) 1184static void ua101_card_free(struct snd_card *card)